]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libndb/ndbcache.c
vt, ssh: don't send interrupts on window resize
[plan9front.git] / sys / src / libndb / ndbcache.c
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         ndbsetmalloctag(first, getcallerpc(&db));
68         return first;
69 }
70
71 /*
72  *  if found, move to front
73  */
74 int
75 _ndbcachesearch(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple **t)
76 {
77         Ndbcache *c, **l;
78
79         *t = nil;
80         c = nil;
81         for(l = &db->cache; *l != nil; l = &(*l)->next){
82                 c = *l;
83                 if(strcmp(c->attr, attr) == 0 && strcmp(c->val, val) == 0)
84                         break;
85         }
86         if(*l == nil)
87                 return -1;
88
89         /* move to front */
90         *l = c->next;
91         c->next = db->cache;
92         db->cache = c;
93
94         *t = ndbcopy(db, c->t, &c->s, s);
95         return 0;
96 }
97
98 Ndbtuple*
99 _ndbcacheadd(Ndb *db, Ndbs *s, char *attr, char *val, Ndbtuple *t)
100 {
101         Ndbcache *c, **l;
102
103         c = mallocz(sizeof *c, 1);
104         if(c == nil)
105                 return nil;
106         c->attr = strdup(attr);
107         if(c->attr == nil)
108                 goto err;
109         c->val = strdup(val);
110         if(c->val == nil)
111                 goto err;
112         c->t = ndbcopy(db, t, s, &c->s);
113         if(c->t == nil && t != nil)
114                 goto err;
115
116         /* add to front */
117         c->next = db->cache;
118         db->cache = c;
119
120         /* trim list */
121         if(db->ncache < Maxcached){
122                 db->ncache++;
123                 return t;
124         }
125         for(l = &db->cache; (*l)->next; l = &(*l)->next)
126                 ;
127         c = *l;
128         *l = nil;
129 err:
130         ndbcachefree(c);
131         ndbsetmalloctag(t, getcallerpc(&db));
132         return t;
133 }
134
135 void
136 _ndbcacheflush(Ndb *db)
137 {
138         Ndbcache *c;
139
140         while(db->cache != nil){
141                 c = db->cache;
142                 db->cache = c->next;
143                 ndbcachefree(c);
144         }
145         db->ncache = 0;
146 }