URI:
       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 }