xref: /inferno-os/liblogfs/map.c (revision 28942ead413418b56c5be78e8c4c400881fba72e)
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