155 lines · 2.6 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <bio.h>#include <ndb.h> struct Ndbcache{	Ndbcache	*next;	char		*attr;	char		*val;	Ndbs		s;	Ndbtuple	*t;	}; enum{	Maxcached=	128,}; static voidndbcachefree(Ndbcache *c){	free(c->val);	free(c->attr);	if(c->t)		ndbfree(c->t);	free(c);} static Ndbtuple*ndbcopy(Ndb *db, Ndbtuple *from_t, Ndbs *from_s, Ndbs *to_s){	Ndbtuple *first, *to_t, *last, *line;	int newline; 	*to_s = *from_s;	to_s->t = nil;	to_s->db = db; 	newline = 1;	last = nil;	first = nil;	line = nil;	for(; from_t != nil; from_t = from_t->entry){		to_t = ndbnew(from_t->attr, from_t->val); 		/* have s point to matching tuple */		if(from_s->t == from_t)			to_s->t = to_t; 		if(newline)			line = to_t;		else			last->line = to_t; 		if(last != nil)			last->entry = to_t;		else {			first = to_t;			line = to_t;		}		to_t->entry = nil;		to_t->line = line;		last = to_t;		newline = from_t->line != from_t->entry;	}	ndbsetmalloctag(first, getcallerpc(&db));	return first;} /* *  if found, move to front */int_ndbcachesearch(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple **t){	Ndbcache *c, **l; 	*t = nil;	c = nil;	for(l = &db->cache; *l != nil; l = &(*l)->next){		c = *l;		if(strcmp(c->attr, attr) == 0 && strcmp(c->val, val) == 0)			break;	}	if(*l == nil)		return -1; 	/* move to front */	*l = c->next;	c->next = db->cache;	db->cache = c; 	*t = ndbcopy(db, c->t, &c->s, s);	return 0;} Ndbtuple*_ndbcacheadd(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple *t){	Ndbcache *c, **l; 	c = mallocz(sizeof *c, 1);	if(c == nil)		return nil;	c->attr = strdup(attr);	if(c->attr == nil)		goto err;	c->val = strdup(val);	if(c->val == nil)		goto err;	c->t = ndbcopy(db, t, s, &c->s);	if(c->t == nil && t != nil)		goto err; 	/* add to front */	c->next = db->cache;	db->cache = c; 	/* trim list */	if(db->ncache < Maxcached){		db->ncache++;		return t;	}	for(l = &db->cache; (*l)->next; l = &(*l)->next)		;	c = *l;	*l = nil;err:	ndbcachefree(c);	ndbsetmalloctag(t, getcallerpc(&db));	return t;} void_ndbcacheflush(Ndb *db){	Ndbcache *c; 	while(db->cache != nil){		c = db->cache;		db->cache = c->next;		ndbcachefree(c);	}	db->ncache = 0;}