19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <bio.h>
49a747e4fSDavid du Colombier #include <ndb.h>
59a747e4fSDavid du Colombier
69a747e4fSDavid du Colombier struct Ndbcache
79a747e4fSDavid du Colombier {
89a747e4fSDavid du Colombier Ndbcache *next;
99a747e4fSDavid du Colombier char *attr;
109a747e4fSDavid du Colombier char *val;
119a747e4fSDavid du Colombier Ndbs s;
129a747e4fSDavid du Colombier Ndbtuple *t;
139a747e4fSDavid du Colombier };
149a747e4fSDavid du Colombier
159a747e4fSDavid du Colombier enum
169a747e4fSDavid du Colombier {
173ff48bf5SDavid du Colombier Maxcached= 128,
189a747e4fSDavid du Colombier };
199a747e4fSDavid du Colombier
209a747e4fSDavid du Colombier static void
ndbcachefree(Ndbcache * c)219a747e4fSDavid du Colombier ndbcachefree(Ndbcache *c)
229a747e4fSDavid du Colombier {
239a747e4fSDavid du Colombier free(c->val);
249a747e4fSDavid du Colombier free(c->attr);
259a747e4fSDavid du Colombier if(c->t)
269a747e4fSDavid du Colombier ndbfree(c->t);
279a747e4fSDavid du Colombier free(c);
289a747e4fSDavid du Colombier }
299a747e4fSDavid du Colombier
309a747e4fSDavid du Colombier static Ndbtuple*
ndbcopy(Ndb * db,Ndbtuple * from_t,Ndbs * from_s,Ndbs * to_s)319a747e4fSDavid du Colombier ndbcopy(Ndb *db, Ndbtuple *from_t, Ndbs *from_s, Ndbs *to_s)
329a747e4fSDavid du Colombier {
339a747e4fSDavid du Colombier Ndbtuple *first, *to_t, *last, *line;
349a747e4fSDavid du Colombier int newline;
359a747e4fSDavid du Colombier
369a747e4fSDavid du Colombier *to_s = *from_s;
379a747e4fSDavid du Colombier to_s->t = nil;
389a747e4fSDavid du Colombier to_s->db = db;
399a747e4fSDavid du Colombier
409a747e4fSDavid du Colombier newline = 1;
419a747e4fSDavid du Colombier last = nil;
429a747e4fSDavid du Colombier first = nil;
439a747e4fSDavid du Colombier line = nil;
449a747e4fSDavid du Colombier for(; from_t != nil; from_t = from_t->entry){
4595a264b3SDavid du Colombier to_t = ndbnew(from_t->attr, from_t->val);
469a747e4fSDavid du Colombier
479a747e4fSDavid du Colombier /* have s point to matching tuple */
489a747e4fSDavid du Colombier if(from_s->t == from_t)
499a747e4fSDavid du Colombier to_s->t = to_t;
509a747e4fSDavid du Colombier
519a747e4fSDavid du Colombier if(newline)
529a747e4fSDavid du Colombier line = to_t;
539a747e4fSDavid du Colombier else
549a747e4fSDavid du Colombier last->line = to_t;
559a747e4fSDavid du Colombier
569a747e4fSDavid du Colombier if(last != nil)
579a747e4fSDavid du Colombier last->entry = to_t;
589a747e4fSDavid du Colombier else {
599a747e4fSDavid du Colombier first = to_t;
609a747e4fSDavid du Colombier line = to_t;
619a747e4fSDavid du Colombier }
629a747e4fSDavid du Colombier to_t->entry = nil;
639a747e4fSDavid du Colombier to_t->line = line;
649a747e4fSDavid du Colombier last = to_t;
659a747e4fSDavid du Colombier newline = from_t->line != from_t->entry;
669a747e4fSDavid du Colombier }
67*1a4050f5SDavid du Colombier ndbsetmalloctag(first, getcallerpc(&db));
689a747e4fSDavid du Colombier return first;
699a747e4fSDavid du Colombier }
709a747e4fSDavid du Colombier
719a747e4fSDavid du Colombier /*
729a747e4fSDavid du Colombier * if found, move to front
739a747e4fSDavid du Colombier */
749a747e4fSDavid du Colombier int
_ndbcachesearch(Ndb * db,Ndbs * s,char * attr,char * val,Ndbtuple ** t)759a747e4fSDavid du Colombier _ndbcachesearch(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple **t)
769a747e4fSDavid du Colombier {
779a747e4fSDavid du Colombier Ndbcache *c, **l;
789a747e4fSDavid du Colombier
799a747e4fSDavid du Colombier *t = nil;
809a747e4fSDavid du Colombier c = nil;
819a747e4fSDavid du Colombier for(l = &db->cache; *l != nil; l = &(*l)->next){
829a747e4fSDavid du Colombier c = *l;
839a747e4fSDavid du Colombier if(strcmp(c->attr, attr) == 0 && strcmp(c->val, val) == 0)
849a747e4fSDavid du Colombier break;
859a747e4fSDavid du Colombier }
869a747e4fSDavid du Colombier if(*l == nil)
879a747e4fSDavid du Colombier return -1;
889a747e4fSDavid du Colombier
899a747e4fSDavid du Colombier /* move to front */
909a747e4fSDavid du Colombier *l = c->next;
919a747e4fSDavid du Colombier c->next = db->cache;
929a747e4fSDavid du Colombier db->cache = c;
939a747e4fSDavid du Colombier
949a747e4fSDavid du Colombier *t = ndbcopy(db, c->t, &c->s, s);
959a747e4fSDavid du Colombier return 0;
969a747e4fSDavid du Colombier }
979a747e4fSDavid du Colombier
989a747e4fSDavid du Colombier Ndbtuple*
_ndbcacheadd(Ndb * db,Ndbs * s,char * attr,char * val,Ndbtuple * t)999a747e4fSDavid du Colombier _ndbcacheadd(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple *t)
1009a747e4fSDavid du Colombier {
1019a747e4fSDavid du Colombier Ndbcache *c, **l;
1029a747e4fSDavid du Colombier
1039a747e4fSDavid du Colombier c = mallocz(sizeof *c, 1);
1049a747e4fSDavid du Colombier if(c == nil)
1059a747e4fSDavid du Colombier return nil;
1069a747e4fSDavid du Colombier c->attr = strdup(attr);
1079a747e4fSDavid du Colombier if(c->attr == nil)
1089a747e4fSDavid du Colombier goto err;
1099a747e4fSDavid du Colombier c->val = strdup(val);
1109a747e4fSDavid du Colombier if(c->val == nil)
1119a747e4fSDavid du Colombier goto err;
1129a747e4fSDavid du Colombier c->t = ndbcopy(db, t, s, &c->s);
1139a747e4fSDavid du Colombier if(c->t == nil && t != nil)
1149a747e4fSDavid du Colombier goto err;
1159a747e4fSDavid du Colombier
1169a747e4fSDavid du Colombier /* add to front */
1179a747e4fSDavid du Colombier c->next = db->cache;
1189a747e4fSDavid du Colombier db->cache = c;
1199a747e4fSDavid du Colombier
1209a747e4fSDavid du Colombier /* trim list */
1219a747e4fSDavid du Colombier if(db->ncache < Maxcached){
1229a747e4fSDavid du Colombier db->ncache++;
1239a747e4fSDavid du Colombier return t;
1249a747e4fSDavid du Colombier }
1259a747e4fSDavid du Colombier for(l = &db->cache; (*l)->next; l = &(*l)->next)
1269a747e4fSDavid du Colombier ;
1279a747e4fSDavid du Colombier c = *l;
1289a747e4fSDavid du Colombier *l = nil;
1299a747e4fSDavid du Colombier err:
1309a747e4fSDavid du Colombier ndbcachefree(c);
131*1a4050f5SDavid du Colombier ndbsetmalloctag(t, getcallerpc(&db));
1329a747e4fSDavid du Colombier return t;
1339a747e4fSDavid du Colombier }
1349a747e4fSDavid du Colombier
1359a747e4fSDavid du Colombier void
_ndbcacheflush(Ndb * db)1369a747e4fSDavid du Colombier _ndbcacheflush(Ndb *db)
1379a747e4fSDavid du Colombier {
1389a747e4fSDavid du Colombier Ndbcache *c;
1399a747e4fSDavid du Colombier
1409a747e4fSDavid du Colombier while(db->cache != nil){
1419a747e4fSDavid du Colombier c = db->cache;
1429a747e4fSDavid du Colombier db->cache = c->next;
1439a747e4fSDavid du Colombier ndbcachefree(c);
1449a747e4fSDavid du Colombier }
1459a747e4fSDavid du Colombier db->ncache = 0;
1469a747e4fSDavid du Colombier }
147