ref: a754ee9f8591a7773426988e8bbd5d18d0494d03
parent: 7577bfa10f5e2fe386bddff5c52c43d1f992cecd
author: Jacob Moody <[email protected]>
date: Sun Dec 15 22:22:19 EST 2019
Fix traversal bug in mapinsert Fix failure to runlock on certain map methods Remove unused hasfn member
--- a/dat.c
+++ b/dat.c
@@ -12,8 +12,8 @@
int i;
uvlong hash;
hash = 7;
- for(i=0;i<strlen(s);i++)
- hash = hash*31 + s[i];
+ for(;*s;s++)
+ hash = hash*31 + *s;
return hash;
}
@@ -29,31 +29,31 @@
void
mapinsert(Hmap *h, char *key, void *val)
{
- Hnode *n;
+ Hnode *n, *end;
wlock(h);
n = h->nodes+(string2hash(key)%h->size);
assert(n != nil);
- for(;n->next!=nil || n->key!=nil ;n=n->next)
- if(strcmp(key, n->key) == 0){
- /* update value */
- n->val = val;
- wunlock(h);
- return;
- }
+ do {
+ if(n->key == nil)
+ goto new;
+ else if(strcmp(key, n->key) == 0)
+ goto found;
+
+ end = n;
+ n = n->next;
+ } while(n != nil);
+ n = end;
- /* Set existing free node */
- if(n->key == nil){
- n->key = strdup(key);
- n->val = val;
- wunlock(h);
- return;
- }
-
/* create new node */
n->next = emalloc(sizeof(Hnode));
- n->next->key = strdup(key);
- n->next->val = val;
+ n = n->next;
+
+new:
+ n->key = strdup(key);
+
+found:
+ n->val = val;
wunlock(h);
}
@@ -61,6 +61,7 @@
mapget(Hmap *h, char *key)
{
Hnode *n;
+
rlock(h);
n = h->nodes+(string2hash(key)%h->size);
for(;n!=nil;n=n->next){
@@ -107,9 +108,10 @@
for(i=c=0;i<h->size;i++)
for(n=h->nodes+i;n!=nil && n->key!=nil;n=n->next){
if(c >= size)
- return c;
+ goto done;
buf[c++] = n->val;
}
+done:
runlock(h);
return c;
}
@@ -124,9 +126,10 @@
for(i=c=0;i<h->size;i++)
for(n=h->nodes+i;n!=nil && n->key!=nil;n=n->next){
if(c >= size)
- return c;
+ goto done;
buf[c++] = n->key;
}
+done:
runlock(h);
return c;
}
--- a/dat.h
+++ b/dat.h
@@ -124,7 +124,6 @@
struct Hmap{
RWLock;
int size;
- int (*hashfn)(void*);
struct Hnode{
char *key;
void *val;