mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-13 15:47:15 +03:00
abstract hash indexes
This commit is contained in:
parent
454a261c95
commit
478e1fc92f
37
hash.c
37
hash.c
@ -41,10 +41,13 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include "gap.h"
|
||||
|
||||
typedef void* hash_item;
|
||||
#include "hash.h"
|
||||
|
||||
static const int h_keylen = 5; /* How many bits in the hash key? (hash is 2^h_keylen big) */
|
||||
static const int hash_size = (1 << h_keylen); /* 8 => 256 */
|
||||
static const int keymask = hash_size - 1; /* 8 => 11111111 */
|
||||
static void* const FREE = NULL;
|
||||
|
||||
struct hash {
|
||||
@ -59,6 +62,12 @@ struct hash {
|
||||
typedef struct hash hash;
|
||||
|
||||
|
||||
static int hash_make_key(hash* h, hash_item item)
|
||||
{
|
||||
return h->hash_make_key(item) & keymask;
|
||||
}
|
||||
|
||||
|
||||
hash* hash_init(hash_make_key_fn make_key, hash_cmp_item_fn cmp_item)
|
||||
{
|
||||
hash* h = malloc(sizeof(*h));
|
||||
@ -83,10 +92,10 @@ static int hash_next_index(hash* h, int i)
|
||||
* item is an item object that must return the target wanted index and for
|
||||
* which comparison with the searched object will succeed.
|
||||
* */
|
||||
int hash_find_index(hash* h, hash_item item)
|
||||
static int hash_find_index(hash* h, hash_item item)
|
||||
{
|
||||
hash_item cnx;
|
||||
int index = h->hash_make_key(item);
|
||||
int index = hash_make_key(h, item);
|
||||
int cnt = 0;
|
||||
|
||||
if (index < h->floor) index = h->floor;
|
||||
@ -111,6 +120,14 @@ int hash_find_index(hash* h, hash_item item)
|
||||
return index;
|
||||
}
|
||||
|
||||
hash_item hash_find(hash* h, hash_item item)
|
||||
{
|
||||
int index = hash_find_index(h, item);
|
||||
if (index == -1) return NULL;
|
||||
hash_item out = gap_get(h->data, index);
|
||||
return out;
|
||||
}
|
||||
|
||||
/* says if we should swap the bubble (element that's going up) and the current
|
||||
* indexed element.
|
||||
* index: current insertion index
|
||||
@ -141,7 +158,7 @@ static int i_should_swap(int index, int wanted_index, int bubble_index, int floo
|
||||
|
||||
int hash_insert(hash* h, hash_item new)
|
||||
{
|
||||
int bubble_wanted_index = h->hash_make_key(new);
|
||||
int bubble_wanted_index = hash_make_key(h, new);
|
||||
int index = bubble_wanted_index;
|
||||
gap_array* hash = h->data;
|
||||
|
||||
@ -163,7 +180,7 @@ int hash_insert(hash* h, hash_item new)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int curr_wanted_index = h->hash_make_key(curr_item);
|
||||
int curr_wanted_index = hash_make_key(h, curr_item);
|
||||
|
||||
if (i_should_swap(index, curr_wanted_index, bubble_wanted_index, orig_floor, wrapped)) {
|
||||
gap_set(h->data, index, new);
|
||||
@ -184,13 +201,10 @@ int hash_insert(hash* h, hash_item new)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int next_in_right_place(hash* h, hash_item item, int index)
|
||||
{
|
||||
if (!item) return 0;
|
||||
int wanted_index = h->hash_make_key(item);
|
||||
int wanted_index = hash_make_key(h, item);
|
||||
return (wanted_index == index);
|
||||
}
|
||||
|
||||
@ -224,7 +238,7 @@ int hash_remove(hash* h, hash_item item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if HASH_TESTING
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#define STR_LENGTH 16
|
||||
@ -249,11 +263,12 @@ void hash_dump(hash* h, char* filename)
|
||||
|
||||
memset(str, 0, STR_LENGTH);
|
||||
if (item) {
|
||||
idx = h->hash_make_key(item);
|
||||
memcpy(str, item->str, STR_LENGTH);
|
||||
idx = hash_make_key(h, item);
|
||||
memcpy(str, ((struct hash_item*)item)->str, STR_LENGTH);
|
||||
}
|
||||
fprintf(out, "\t%d:%d:%s\n", i, idx, str);
|
||||
}
|
||||
fprintf(out, "</hash>\n");
|
||||
fclose(out);
|
||||
}
|
||||
#endif
|
||||
|
16
hash.h
16
hash.h
@ -1,16 +1,28 @@
|
||||
#ifndef HASH_H
|
||||
#define HASH_H
|
||||
|
||||
/* You will need to typedef a pointer type to hash_item before including this
|
||||
* .h */
|
||||
|
||||
typedef struct hash hash;
|
||||
typedef struct hash_item* hash_item;
|
||||
|
||||
/* Function that returns a key (index) for a given item. The key must be always
|
||||
* the same for an item. It doesn't need to be bounded (hash.c masks it for you) */
|
||||
typedef int (*hash_make_key_fn)(hash_item item);
|
||||
|
||||
/* Function that compares two items: returns 0 if they are the same */
|
||||
typedef int (*hash_cmp_item_fn)(hash_item item1, hash_item item2);
|
||||
|
||||
hash* hash_init(hash_make_key_fn make_key, hash_cmp_item_fn cmp_item);
|
||||
int hash_find_index(hash* h, hash_item item);
|
||||
|
||||
int hash_insert(hash* h, hash_item new);
|
||||
int hash_remove(hash* h, hash_item item);
|
||||
|
||||
/* Returns the hash item that matches specification (meaning the
|
||||
* comparison function returns true for cmp(x, item), or NULL if not found */
|
||||
hash_item hash_find(hash* h, hash_item item);
|
||||
|
||||
|
||||
void hash_dump(hash* h, char* filename); /* For development only */
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,5 @@
|
||||
|
||||
CFLAGS=-DHASH_TESTING
|
||||
OBJ=../hash.o ../gap.o htest.o
|
||||
|
||||
htest: $(OBJ)
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../hash.h"
|
||||
|
||||
|
||||
#define STR_LENGTH 16
|
||||
@ -27,6 +26,9 @@ struct hash_item {
|
||||
char str[STR_LENGTH];
|
||||
};
|
||||
|
||||
typedef struct hash_item* hash_item;
|
||||
|
||||
#include "../hash.h"
|
||||
|
||||
|
||||
|
||||
@ -92,8 +94,8 @@ int main(int argc, char* argv[])
|
||||
|
||||
case 's': /* search */
|
||||
fprintf(stderr, "searching\n");
|
||||
int i = hash_find_index(h, item);
|
||||
fprintf(stderr, "searching %d[%s]: %d\n", item->wanted_index, item->str, i);
|
||||
struct hash_item* found = hash_find(h, item);
|
||||
fprintf(stderr, "searching %d[%s]: %p\n", item->wanted_index, item->str, found);
|
||||
break;
|
||||
|
||||
case 'q': /* quit */
|
||||
|
Loading…
x
Reference in New Issue
Block a user