Permalink
Browse files

rewrite hash map

  • Loading branch information...
1 parent 4ebf8c9 commit 88bde778a560c1bb04ca687020cf4ca0bf1c9b25 @cloudwu committed Apr 9, 2012
Showing with 70 additions and 30 deletions.
  1. +61 −19 map.c
  2. +1 −0 map.h
  3. +8 −11 testmap.c
View
@@ -2,11 +2,12 @@
#include <stdlib.h>
#include <assert.h>
+#include <stdio.h>
struct node {
int fd;
int id;
- int next;
+ struct node * next;
};
struct map {
@@ -27,7 +28,7 @@ map_new(int max) {
for (i=0;i<sz;i++) {
m->hash[i].fd = -1;
m->hash[i].id = 0;
- m->hash[i].next = -1;
+ m->hash[i].next = NULL;
}
return m;
}
@@ -42,30 +43,40 @@ int
map_search(struct map * m, int fd) {
int hash = fd & (m->size-1);
struct node * n = &m->hash[hash];
- for(;;) {
+ do {
if (n->fd == fd)
return n->id;
- if (n->next < 0)
- return -1;
- n = &m->hash[n->next];
- }
+ n = n->next;
+ } while(n);
+ return -1;
}
void
map_insert(struct map * m, int fd, int id) {
int hash = fd & (m->size-1);
struct node * n = &m->hash[hash];
- for (;;) {
- if (n->fd < 0) {
- n->fd = fd;
- n->id = id;
- return;
- }
- if (n->next < 0 ) {
- break;
+ if (n->fd < 0) {
+ n->fd = fd;
+ n->id = id;
+ return;
+ }
+ int ohash = n->fd & (m->size-1);
+ if (hash != ohash) {
+ struct node * last = &m->hash[ohash];
+ while (last->next != &m->hash[hash]) {
+ last = last->next;
}
- n = &m->hash[n->next];
+ last->next = n->next;
+
+ int ofd = n->fd;
+ int oid = n->id;
+ n->fd = fd;
+ n->id = id;
+ n->next = NULL;
+ map_insert(m,ofd, oid);
+ return;
}
+
int last = (n - m->hash) * 2;
int i;
for (i=0;i<m->size;i++) {
@@ -74,7 +85,8 @@ map_insert(struct map * m, int fd, int id) {
if (temp->fd < 0) {
temp->fd = fd;
temp->id = id;
- n->next = idx;
+ temp->next = n->next;
+ n->next = temp;
return;
}
}
@@ -85,13 +97,43 @@ void
map_erase(struct map *m , int fd) {
int hash = fd & (m->size-1);
struct node * n = &m->hash[hash];
+ if (n->fd == fd) {
+ if (n->next == NULL) {
+ n->fd = -1;
+ return;
+ }
+ struct node * next = n->next;
+ n->fd = next->fd;
+ n->id = next->id;
+ n->next = next->next;
+ next->fd = -1;
+ next->next = NULL;
+ return;
+ }
+ if (n->next == NULL) {
+ return;
+ }
+ struct node * last = n;
+ n = n->next;
for(;;) {
if (n->fd == fd) {
n->fd = -1;
+ last->next = n->next;
+ n->next = NULL;
return;
}
- if (n->next < 0)
+ if (n->next == NULL)
return;
- n = &m->hash[n->next];
+ last = n;
+ n = n->next;
}
}
+
+void
+map_dump(struct map *m) {
+ int i;
+ for (i=0;i<m->size;i++) {
+ struct node * n = &(m->hash[i]);
+ printf("[%d] fd = %d , id = %d , next = %d\n",i,n->fd,n->id,(n->next - m->hash));
+ }
+}
View
@@ -8,5 +8,6 @@ void map_delete(struct map *);
int map_search(struct map * , int fd);
void map_insert(struct map * , int fd, int id);
void map_erase(struct map *, int fd);
+void map_dump(struct map *m);
#endif
View
@@ -4,21 +4,21 @@
#include <assert.h>
#include <stdio.h>
-#define MAX 1000
+#define MAX 2000
static void
test(struct map *m) {
int a[MAX * 2];
int i;
int s = 0;
for (i=0;i<MAX*2;i++) {
- int inc = random() % 3 + 1;
+ int inc = rand() % 3 + 1;
s += inc;
a[i] = s;
}
for (i=0;i<MAX * 2;i++) {
- int x = random()%(MAX*2);
- int y = random()%(MAX*2);
+ int x = rand()%(MAX*2);
+ int y = rand()%(MAX*2);
int temp = a[x];
a[x] = a[y];
a[y] = temp;
@@ -34,15 +34,12 @@ test(struct map *m) {
map_erase(m, a[i]);
}
for (i=0;i<MAX/2;i++) {
- map_insert(m,a[i+MAX],i);
+ a[i] = a[i+MAX];
+ map_insert(m,a[i],i);
}
for (i=0;i<MAX;i++) {
- int id = map_search(m,a[i+MAX/2]);
- if (i>=MAX/2) {
- assert(id == i - MAX/2);
- } else {
- assert(id == i + MAX/2);
- }
+ int id = map_search(m,a[i]);
+ assert(id == i);
}
}

0 comments on commit 88bde77

Please sign in to comment.