1*9a747e4fSDavid du Colombier #include <u.h> 2*9a747e4fSDavid du Colombier #include <libc.h> 3*9a747e4fSDavid du Colombier #include <bio.h> 4*9a747e4fSDavid du Colombier #include <ndb.h> 5*9a747e4fSDavid du Colombier 6*9a747e4fSDavid du Colombier struct Ndbcache 7*9a747e4fSDavid du Colombier { 8*9a747e4fSDavid du Colombier Ndbcache *next; 9*9a747e4fSDavid du Colombier char *attr; 10*9a747e4fSDavid du Colombier char *val; 11*9a747e4fSDavid du Colombier Ndbs s; 12*9a747e4fSDavid du Colombier Ndbtuple *t; 13*9a747e4fSDavid du Colombier }; 14*9a747e4fSDavid du Colombier 15*9a747e4fSDavid du Colombier enum 16*9a747e4fSDavid du Colombier { 17*9a747e4fSDavid du Colombier Maxcached= 32, 18*9a747e4fSDavid du Colombier }; 19*9a747e4fSDavid du Colombier 20*9a747e4fSDavid du Colombier static void 21*9a747e4fSDavid du Colombier ndbcachefree(Ndbcache *c) 22*9a747e4fSDavid du Colombier { 23*9a747e4fSDavid du Colombier free(c->val); 24*9a747e4fSDavid du Colombier free(c->attr); 25*9a747e4fSDavid du Colombier if(c->t) 26*9a747e4fSDavid du Colombier ndbfree(c->t); 27*9a747e4fSDavid du Colombier free(c); 28*9a747e4fSDavid du Colombier } 29*9a747e4fSDavid du Colombier 30*9a747e4fSDavid du Colombier static Ndbtuple* 31*9a747e4fSDavid du Colombier ndbcopy(Ndb *db, Ndbtuple *from_t, Ndbs *from_s, Ndbs *to_s) 32*9a747e4fSDavid du Colombier { 33*9a747e4fSDavid du Colombier Ndbtuple *first, *to_t, *last, *line; 34*9a747e4fSDavid du Colombier int newline; 35*9a747e4fSDavid du Colombier 36*9a747e4fSDavid du Colombier *to_s = *from_s; 37*9a747e4fSDavid du Colombier to_s->t = nil; 38*9a747e4fSDavid du Colombier to_s->db = db; 39*9a747e4fSDavid du Colombier 40*9a747e4fSDavid du Colombier newline = 1; 41*9a747e4fSDavid du Colombier last = nil; 42*9a747e4fSDavid du Colombier first = nil; 43*9a747e4fSDavid du Colombier line = nil; 44*9a747e4fSDavid du Colombier for(; from_t != nil; from_t = from_t->entry){ 45*9a747e4fSDavid du Colombier to_t = malloc(sizeof *to_t); 46*9a747e4fSDavid du Colombier if(to_t == nil){ 47*9a747e4fSDavid du Colombier ndbfree(first); 48*9a747e4fSDavid du Colombier return nil; 49*9a747e4fSDavid du Colombier } 50*9a747e4fSDavid du Colombier *to_t = *from_t; 51*9a747e4fSDavid du Colombier 52*9a747e4fSDavid du Colombier /* have s point to matching tuple */ 53*9a747e4fSDavid du Colombier if(from_s->t == from_t) 54*9a747e4fSDavid du Colombier to_s->t = to_t; 55*9a747e4fSDavid du Colombier 56*9a747e4fSDavid du Colombier if(newline) 57*9a747e4fSDavid du Colombier line = to_t; 58*9a747e4fSDavid du Colombier else 59*9a747e4fSDavid du Colombier last->line = to_t; 60*9a747e4fSDavid du Colombier 61*9a747e4fSDavid du Colombier if(last != nil) 62*9a747e4fSDavid du Colombier last->entry = to_t; 63*9a747e4fSDavid du Colombier else { 64*9a747e4fSDavid du Colombier first = to_t; 65*9a747e4fSDavid du Colombier line = to_t; 66*9a747e4fSDavid du Colombier } 67*9a747e4fSDavid du Colombier to_t->entry = nil; 68*9a747e4fSDavid du Colombier to_t->line = line; 69*9a747e4fSDavid du Colombier last = to_t; 70*9a747e4fSDavid du Colombier newline = from_t->line != from_t->entry; 71*9a747e4fSDavid du Colombier } 72*9a747e4fSDavid du Colombier return first; 73*9a747e4fSDavid du Colombier } 74*9a747e4fSDavid du Colombier 75*9a747e4fSDavid du Colombier /* 76*9a747e4fSDavid du Colombier * if found, move to front 77*9a747e4fSDavid du Colombier */ 78*9a747e4fSDavid du Colombier int 79*9a747e4fSDavid du Colombier _ndbcachesearch(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple **t) 80*9a747e4fSDavid du Colombier { 81*9a747e4fSDavid du Colombier Ndbcache *c, **l; 82*9a747e4fSDavid du Colombier 83*9a747e4fSDavid du Colombier *t = nil; 84*9a747e4fSDavid du Colombier c = nil; 85*9a747e4fSDavid du Colombier for(l = &db->cache; *l != nil; l = &(*l)->next){ 86*9a747e4fSDavid du Colombier c = *l; 87*9a747e4fSDavid du Colombier if(strcmp(c->attr, attr) == 0 && strcmp(c->val, val) == 0) 88*9a747e4fSDavid du Colombier break; 89*9a747e4fSDavid du Colombier } 90*9a747e4fSDavid du Colombier if(*l == nil) 91*9a747e4fSDavid du Colombier return -1; 92*9a747e4fSDavid du Colombier 93*9a747e4fSDavid du Colombier /* move to front */ 94*9a747e4fSDavid du Colombier *l = c->next; 95*9a747e4fSDavid du Colombier c->next = db->cache; 96*9a747e4fSDavid du Colombier db->cache = c; 97*9a747e4fSDavid du Colombier 98*9a747e4fSDavid du Colombier *t = ndbcopy(db, c->t, &c->s, s); 99*9a747e4fSDavid du Colombier return 0; 100*9a747e4fSDavid du Colombier } 101*9a747e4fSDavid du Colombier 102*9a747e4fSDavid du Colombier Ndbtuple* 103*9a747e4fSDavid du Colombier _ndbcacheadd(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple *t) 104*9a747e4fSDavid du Colombier { 105*9a747e4fSDavid du Colombier Ndbcache *c, **l; 106*9a747e4fSDavid du Colombier 107*9a747e4fSDavid du Colombier c = mallocz(sizeof *c, 1); 108*9a747e4fSDavid du Colombier if(c == nil) 109*9a747e4fSDavid du Colombier return nil; 110*9a747e4fSDavid du Colombier c->attr = strdup(attr); 111*9a747e4fSDavid du Colombier if(c->attr == nil) 112*9a747e4fSDavid du Colombier goto err; 113*9a747e4fSDavid du Colombier c->val = strdup(val); 114*9a747e4fSDavid du Colombier if(c->val == nil) 115*9a747e4fSDavid du Colombier goto err; 116*9a747e4fSDavid du Colombier c->t = ndbcopy(db, t, s, &c->s); 117*9a747e4fSDavid du Colombier if(c->t == nil && t != nil) 118*9a747e4fSDavid du Colombier goto err; 119*9a747e4fSDavid du Colombier 120*9a747e4fSDavid du Colombier /* add to front */ 121*9a747e4fSDavid du Colombier c->next = db->cache; 122*9a747e4fSDavid du Colombier db->cache = c; 123*9a747e4fSDavid du Colombier 124*9a747e4fSDavid du Colombier /* trim list */ 125*9a747e4fSDavid du Colombier if(db->ncache < Maxcached){ 126*9a747e4fSDavid du Colombier db->ncache++; 127*9a747e4fSDavid du Colombier return t; 128*9a747e4fSDavid du Colombier } 129*9a747e4fSDavid du Colombier for(l = &db->cache; (*l)->next; l = &(*l)->next) 130*9a747e4fSDavid du Colombier ; 131*9a747e4fSDavid du Colombier c = *l; 132*9a747e4fSDavid du Colombier *l = nil; 133*9a747e4fSDavid du Colombier err: 134*9a747e4fSDavid du Colombier ndbcachefree(c); 135*9a747e4fSDavid du Colombier return t; 136*9a747e4fSDavid du Colombier } 137*9a747e4fSDavid du Colombier 138*9a747e4fSDavid du Colombier void 139*9a747e4fSDavid du Colombier _ndbcacheflush(Ndb *db) 140*9a747e4fSDavid du Colombier { 141*9a747e4fSDavid du Colombier Ndbcache *c; 142*9a747e4fSDavid du Colombier 143*9a747e4fSDavid du Colombier while(db->cache != nil){ 144*9a747e4fSDavid du Colombier c = db->cache; 145*9a747e4fSDavid du Colombier db->cache = c->next; 146*9a747e4fSDavid du Colombier ndbcachefree(c); 147*9a747e4fSDavid du Colombier } 148*9a747e4fSDavid du Colombier db->ncache = 0; 149*9a747e4fSDavid du Colombier } 150