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