tndbcache.c - plan9port - [fork] Plan 9 from user space
HTML git clone git://src.adamsgaard.dk/plan9port
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
tndbcache.c (2162B)
---
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ndb.h>
5
6 struct Ndbcache
7 {
8 Ndbcache *next;
9 char *attr;
10 char *val;
11 Ndbs s;
12 Ndbtuple *t;
13 };
14
15 enum
16 {
17 Maxcached= 128
18 };
19
20 static void
21 ndbcachefree(Ndbcache *c)
22 {
23 free(c->val);
24 free(c->attr);
25 if(c->t)
26 ndbfree(c->t);
27 free(c);
28 }
29
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;
35
36 *to_s = *from_s;
37 to_s->t = nil;
38 to_s->db = db;
39
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);
46
47 /* have s point to matching tuple */
48 if(from_s->t == from_t)
49 to_s->t = to_t;
50
51 if(newline)
52 line = to_t;
53 else
54 last->line = to_t;
55
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 }
69
70 /*
71 * if found, move to front
72 */
73 int
74 _ndbcachesearch(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple **t)
75 {
76 Ndbcache *c, **l;
77
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;
87
88 /* move to front */
89 *l = c->next;
90 c->next = db->cache;
91 db->cache = c;
92
93 *t = ndbcopy(db, c->t, &c->s, s);
94 return 0;
95 }
96
97 Ndbtuple*
98 _ndbcacheadd(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple *t)
99 {
100 Ndbcache *c, **l;
101
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;
114
115 /* add to front */
116 c->next = db->cache;
117 db->cache = c;
118
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 }
132
133 void
134 _ndbcacheflush(Ndb *db)
135 {
136 Ndbcache *c;
137
138 while(db->cache != nil){
139 c = db->cache;
140 db->cache = c->next;
141 ndbcachefree(c);
142 }
143 db->ncache = 0;
144 }