Skip to content

Commit

Permalink
rewrite hash map
Browse files Browse the repository at this point in the history
  • Loading branch information
cloudwu committed Apr 9, 2012
1 parent 4ebf8c9 commit 88bde77
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 30 deletions.
80 changes: 61 additions & 19 deletions map.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}
Expand All @@ -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++) {
Expand All @@ -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;
}
}
Expand All @@ -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));
}
}
1 change: 1 addition & 0 deletions map.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
19 changes: 8 additions & 11 deletions testmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
}

Expand Down

0 comments on commit 88bde77

Please sign in to comment.