xref: /plan9/sys/src/libndb/ndbcache.c (revision 1a4050f5b2ddf426a278e3233ccd7b6bcb0639b8)
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