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