#include "logfsos.h"#include "logfs.h"#include "local.h" typedef struct MapNode MapNode; struct MapNode { MapNode *next; uchar e[1]; // entry goes here, inline}; struct Map { int size; int (*hash)(void *key, int size); int (*compare)(void *entry, void *key); int (*allocsize)(void *key); void (*free)(void *entry); MapNode *head[1];}; 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){ Map *p; *mapp = p = logfsrealloc(nil, sizeof(Map) + (size - 1) * sizeof(MapNode *)); if(p == nil) return Enomem; p->size = size; p->hash = hash; p->compare = compare; p->allocsize = allocsize; p->free = free; return nil;} voidlogfsmapfree(FidMap **mp){ FidMap *m; int i; m = *mp; if(m == nil) return; for(i = 0; i < m->size; i++) { MapNode *n, *next; n = m->head[i]; while(n) { next = n->next; if(m->free) (*m->free)(n->e); logfsfreemem(n); n = next; } } logfsfreemem(m); *mp = nil;} static char *find(FidMap *m, void *key, int create, void **ep){ MapNode *n; int i; i = (*m->hash)(key, m->size); n = m->head[i]; while(n && !(*m->compare)(n->e, key)) n = n->next; if(n) { if(create) { *ep = nil; return nil; } *ep = n->e; return nil; } if(!create) { *ep = nil; return nil; } n = logfsrealloc(nil, (*m->allocsize)(key) + sizeof(MapNode *)); if(n == nil) { *ep = nil; return Enomem; } n->next = m->head[i]; m->head[i] = n; *ep = n->e; return nil;} void *logfsmapfindentry(Map *m, void *key){ void *rv; find(m, key, 0, &rv); return rv;} char *logfsmapnewentry(Map *m, void *key, void **entryp){ return find(m, key, 1, entryp);} intlogfsmapdeleteentry(Map *m, void *key){ MapNode **np, *n; np = &m->head[(*m->hash)(key, m->size)]; while((n = *np) && !(*m->compare)(n->e, key)) np = &n->next; if(n) { *np = n->next; if(m->free) (*m->free)(n->e); logfsfreemem(n); return 1; } return 0; // not there} intlogfsmapwalk(Map *m, int (*func)(void *magic, void *), void *magic){ int x; MapNode *n; for(x = 0; x < m->size; x++) for(n = m->head[x]; n; n = n->next) { int rv = (*func)(magic, n->e); if(rv <= 0) return rv; } return 1;}
#include "logfsos.h"
#include "logfs.h"
#include "local.h"
typedef struct MapNode MapNode;
struct MapNode {
MapNode *next;
uchar e[1]; // entry goes here, inline
};
struct Map {
int size;
int (*hash)(void *key, int size);
int (*compare)(void *entry, void *key);
int (*allocsize)(void *key);
void (*free)(void *entry);
MapNode *head[1];
};
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)
{
Map *p;
*mapp = p = logfsrealloc(nil, sizeof(Map) + (size - 1) * sizeof(MapNode *));
if(p == nil)
return Enomem;
p->size = size;
p->hash = hash;
p->compare = compare;
p->allocsize = allocsize;
p->free = free;
return nil;
}
void
logfsmapfree(FidMap **mp)
{
FidMap *m;
int i;
m = *mp;
if(m == nil)
return;
for(i = 0; i < m->size; i++) {
MapNode *n, *next;
n = m->head[i];
while(n) {
next = n->next;
if(m->free)
(*m->free)(n->e);
logfsfreemem(n);
n = next;
}
}
logfsfreemem(m);
*mp = nil;
}
static char *
find(FidMap *m, void *key, int create, void **ep)
{
MapNode *n;
int i;
i = (*m->hash)(key, m->size);
n = m->head[i];
while(n && !(*m->compare)(n->e, key))
n = n->next;
if(n) {
if(create) {
*ep = nil;
return nil;
}
*ep = n->e;
return nil;
}
if(!create) {
*ep = nil;
return nil;
}
n = logfsrealloc(nil, (*m->allocsize)(key) + sizeof(MapNode *));
if(n == nil) {
*ep = nil;
return Enomem;
}
n->next = m->head[i];
m->head[i] = n;
*ep = n->e;
return nil;
}
void *
logfsmapfindentry(Map *m, void *key)
{
void *rv;
find(m, key, 0, &rv);
return rv;
}
char *
logfsmapnewentry(Map *m, void *key, void **entryp)
{
return find(m, key, 1, entryp);
}
int
logfsmapdeleteentry(Map *m, void *key)
{
MapNode **np, *n;
np = &m->head[(*m->hash)(key, m->size)];
while((n = *np) && !(*m->compare)(n->e, key))
np = &n->next;
if(n) {
*np = n->next;
if(m->free)
(*m->free)(n->e);
logfsfreemem(n);
return 1;
}
return 0; // not there
}
int
logfsmapwalk(Map *m, int (*func)(void *magic, void *), void *magic)
{
int x;
MapNode *n;
for(x = 0; x < m->size; x++)
for(n = m->head[x]; n; n = n->next) {
int rv = (*func)(magic, n->e);
if(rv <= 0)
return rv;
}
return 1;
}