1*28942eadSforsyth #include "logfsos.h"
237da2899SCharles.Forsyth #include "logfs.h"
337da2899SCharles.Forsyth #include "local.h"
437da2899SCharles.Forsyth
5*28942eadSforsyth typedef struct MapNode MapNode;
6*28942eadSforsyth
7*28942eadSforsyth struct MapNode {
8*28942eadSforsyth MapNode *next;
937da2899SCharles.Forsyth uchar e[1]; // entry goes here, inline
10*28942eadSforsyth };
1137da2899SCharles.Forsyth
1237da2899SCharles.Forsyth struct Map {
1337da2899SCharles.Forsyth int size;
1437da2899SCharles.Forsyth int (*hash)(void *key, int size);
1537da2899SCharles.Forsyth int (*compare)(void *entry, void *key);
1637da2899SCharles.Forsyth int (*allocsize)(void *key);
1737da2899SCharles.Forsyth void (*free)(void *entry);
1837da2899SCharles.Forsyth MapNode *head[1];
1937da2899SCharles.Forsyth };
2037da2899SCharles.Forsyth
2137da2899SCharles.Forsyth char *
logfsmapnew(int size,int (* hash)(void * key,int size),int (* compare)(void * entry,void * key),int (* allocsize)(void * key),void (* free)(void *),Map ** mapp)2237da2899SCharles.Forsyth logfsmapnew(int size, int (*hash)(void *key, int size), int (*compare)(void *entry, void *key), int (*allocsize)(void *key), void (*free)(void *), Map **mapp)
2337da2899SCharles.Forsyth {
2437da2899SCharles.Forsyth Map *p;
2537da2899SCharles.Forsyth *mapp = p = logfsrealloc(nil, sizeof(Map) + (size - 1) * sizeof(MapNode *));
2637da2899SCharles.Forsyth if(p == nil)
2737da2899SCharles.Forsyth return Enomem;
2837da2899SCharles.Forsyth p->size = size;
2937da2899SCharles.Forsyth p->hash = hash;
3037da2899SCharles.Forsyth p->compare = compare;
3137da2899SCharles.Forsyth p->allocsize = allocsize;
3237da2899SCharles.Forsyth p->free = free;
3337da2899SCharles.Forsyth return nil;
3437da2899SCharles.Forsyth }
3537da2899SCharles.Forsyth
3637da2899SCharles.Forsyth void
logfsmapfree(FidMap ** mp)3737da2899SCharles.Forsyth logfsmapfree(FidMap **mp)
3837da2899SCharles.Forsyth {
3937da2899SCharles.Forsyth FidMap *m;
4037da2899SCharles.Forsyth int i;
4137da2899SCharles.Forsyth
4237da2899SCharles.Forsyth m = *mp;
4337da2899SCharles.Forsyth if(m == nil)
4437da2899SCharles.Forsyth return;
4537da2899SCharles.Forsyth
4637da2899SCharles.Forsyth for(i = 0; i < m->size; i++) {
4737da2899SCharles.Forsyth MapNode *n, *next;
4837da2899SCharles.Forsyth n = m->head[i];
4937da2899SCharles.Forsyth while(n) {
5037da2899SCharles.Forsyth next = n->next;
5137da2899SCharles.Forsyth if(m->free)
5237da2899SCharles.Forsyth (*m->free)(n->e);
5337da2899SCharles.Forsyth logfsfreemem(n);
5437da2899SCharles.Forsyth n = next;
5537da2899SCharles.Forsyth }
5637da2899SCharles.Forsyth }
5737da2899SCharles.Forsyth logfsfreemem(m);
5837da2899SCharles.Forsyth *mp = nil;
5937da2899SCharles.Forsyth }
6037da2899SCharles.Forsyth
6137da2899SCharles.Forsyth static char *
find(FidMap * m,void * key,int create,void ** ep)6237da2899SCharles.Forsyth find(FidMap *m, void *key, int create, void **ep)
6337da2899SCharles.Forsyth {
6437da2899SCharles.Forsyth MapNode *n;
6537da2899SCharles.Forsyth int i;
66*28942eadSforsyth
6737da2899SCharles.Forsyth i = (*m->hash)(key, m->size);
6837da2899SCharles.Forsyth n = m->head[i];
6937da2899SCharles.Forsyth while(n && !(*m->compare)(n->e, key))
7037da2899SCharles.Forsyth n = n->next;
7137da2899SCharles.Forsyth if(n) {
7237da2899SCharles.Forsyth if(create) {
7337da2899SCharles.Forsyth *ep = nil;
7437da2899SCharles.Forsyth return nil;
7537da2899SCharles.Forsyth }
7637da2899SCharles.Forsyth *ep = n->e;
7737da2899SCharles.Forsyth return nil;
7837da2899SCharles.Forsyth }
7937da2899SCharles.Forsyth if(!create) {
8037da2899SCharles.Forsyth *ep = nil;
8137da2899SCharles.Forsyth return nil;
8237da2899SCharles.Forsyth }
8337da2899SCharles.Forsyth n = logfsrealloc(nil, (*m->allocsize)(key) + sizeof(MapNode *));
8437da2899SCharles.Forsyth if(n == nil) {
8537da2899SCharles.Forsyth *ep = nil;
8637da2899SCharles.Forsyth return Enomem;
8737da2899SCharles.Forsyth }
8837da2899SCharles.Forsyth n->next = m->head[i];
8937da2899SCharles.Forsyth m->head[i] = n;
9037da2899SCharles.Forsyth *ep = n->e;
9137da2899SCharles.Forsyth return nil;
9237da2899SCharles.Forsyth }
9337da2899SCharles.Forsyth
9437da2899SCharles.Forsyth void *
logfsmapfindentry(Map * m,void * key)9537da2899SCharles.Forsyth logfsmapfindentry(Map *m, void *key)
9637da2899SCharles.Forsyth {
9737da2899SCharles.Forsyth void *rv;
9837da2899SCharles.Forsyth find(m, key, 0, &rv);
9937da2899SCharles.Forsyth return rv;
10037da2899SCharles.Forsyth }
10137da2899SCharles.Forsyth
10237da2899SCharles.Forsyth char *
logfsmapnewentry(Map * m,void * key,void ** entryp)10337da2899SCharles.Forsyth logfsmapnewentry(Map *m, void *key, void **entryp)
10437da2899SCharles.Forsyth {
10537da2899SCharles.Forsyth return find(m, key, 1, entryp);
10637da2899SCharles.Forsyth }
10737da2899SCharles.Forsyth
10837da2899SCharles.Forsyth int
logfsmapdeleteentry(Map * m,void * key)10937da2899SCharles.Forsyth logfsmapdeleteentry(Map *m, void *key)
11037da2899SCharles.Forsyth {
11137da2899SCharles.Forsyth MapNode **np, *n;
11237da2899SCharles.Forsyth np = &m->head[(*m->hash)(key, m->size)];
11337da2899SCharles.Forsyth while((n = *np) && !(*m->compare)(n->e, key))
11437da2899SCharles.Forsyth np = &n->next;
11537da2899SCharles.Forsyth if(n) {
11637da2899SCharles.Forsyth *np = n->next;
11737da2899SCharles.Forsyth if(m->free)
11837da2899SCharles.Forsyth (*m->free)(n->e);
11937da2899SCharles.Forsyth logfsfreemem(n);
12037da2899SCharles.Forsyth return 1;
12137da2899SCharles.Forsyth }
12237da2899SCharles.Forsyth return 0; // not there
12337da2899SCharles.Forsyth }
12437da2899SCharles.Forsyth
12537da2899SCharles.Forsyth int
logfsmapwalk(Map * m,int (* func)(void * magic,void *),void * magic)12637da2899SCharles.Forsyth logfsmapwalk(Map *m, int (*func)(void *magic, void *), void *magic)
12737da2899SCharles.Forsyth {
12837da2899SCharles.Forsyth int x;
12937da2899SCharles.Forsyth MapNode *n;
13037da2899SCharles.Forsyth
13137da2899SCharles.Forsyth for(x = 0; x < m->size; x++)
13237da2899SCharles.Forsyth for(n = m->head[x]; n; n = n->next) {
13337da2899SCharles.Forsyth int rv = (*func)(magic, n->e);
13437da2899SCharles.Forsyth if(rv <= 0)
13537da2899SCharles.Forsyth return rv;
13637da2899SCharles.Forsyth }
13737da2899SCharles.Forsyth return 1;
13837da2899SCharles.Forsyth }
13937da2899SCharles.Forsyth
140