plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

ndbcache.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 }