remove debug code, TODO list for hash map.
This commit is contained in:
@@ -41,7 +41,7 @@ mem: clean memcheck
|
|||||||
unit: CFLAGS+=-DUNIT_TEST
|
unit: CFLAGS+=-DUNIT_TEST
|
||||||
unit: clean std
|
unit: clean std
|
||||||
|
|
||||||
debug: CFLAGS+=-DUNIT_TEST -DDEBUG
|
debug: CFLAGS+=-DUNIT_TEST -DDEBUG -DDEBUG_HASH
|
||||||
debug: clean std
|
debug: clean std
|
||||||
|
|
||||||
debugtest: CFLAGS+=-DDEBUG
|
debugtest: CFLAGS+=-DDEBUG
|
||||||
|
@@ -3,28 +3,18 @@
|
|||||||
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
#define HASH_SIZE 50
|
/* TODO:
|
||||||
|
* - multiple linked pools
|
||||||
|
* - free pools ?
|
||||||
|
* - do a kernel-like list management, + add counter for pool elements
|
||||||
|
* so that they get freed when counter becomes zero (to allow an element
|
||||||
|
* to be in multiple lists)
|
||||||
|
*/
|
||||||
|
|
||||||
//static hash_t *hash_table[HASH_SIZE];
|
|
||||||
static h_entry_t *pool_free, *alloc_entries;
|
static h_entry_t *pool_free, *alloc_entries;
|
||||||
static int n_entries;
|
static int n_entries;
|
||||||
|
|
||||||
void h_init(hash_t *hash)
|
void h_free_all(hash_t *h)
|
||||||
{
|
|
||||||
memset(hash->entries, 0, sizeof(h_entry_t)*hash->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
hash_t *h_create(int size)
|
|
||||||
{
|
|
||||||
hash_t *hash;
|
|
||||||
|
|
||||||
if ( !(hash=calloc(sizeof(hash_t) + size*(sizeof (h_entry_t *)), 1)) )
|
|
||||||
return NULL;
|
|
||||||
hash->size=size;
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
void h_destroy(hash_t *h)
|
|
||||||
{
|
{
|
||||||
h_entry_t *tmp;
|
h_entry_t *tmp;
|
||||||
|
|
||||||
@@ -35,6 +25,32 @@ void h_destroy(hash_t *h)
|
|||||||
h->entries[i]=tmp;
|
h->entries[i]=tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should be used only when using unknown memory state, which is unlickely.
|
||||||
|
* Instead prefer:
|
||||||
|
* h_free_all: removes all entries from hash table
|
||||||
|
* h_destroy: cleans entries, and free hash memory
|
||||||
|
* TODO: add size parameter, to totally create a hash in known available memory
|
||||||
|
*/
|
||||||
|
void h_init(hash_t *h)
|
||||||
|
{
|
||||||
|
memset(h->entries, 0, sizeof(h_entry_t)*h->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_t *h_create(int size)
|
||||||
|
{
|
||||||
|
hash_t *hash;
|
||||||
|
|
||||||
|
if ( !(hash=calloc(1, sizeof(hash_t) + size*(sizeof (h_entry_t *)))) )
|
||||||
|
return NULL;
|
||||||
|
hash->size=size;
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
void h_destroy(hash_t *h)
|
||||||
|
{
|
||||||
|
h_free_all(h);
|
||||||
free(h);
|
free(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +76,7 @@ h_entry_t *h_entry_find(hash_t *h, const unsigned char *s, const int l)
|
|||||||
h_entry_t *entry;
|
h_entry_t *entry;
|
||||||
int found=0;
|
int found=0;
|
||||||
|
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG_HASH
|
||||||
printf("h_entry_find([%.*s]): hash=%#lx (%lu) - ", l, s, hash, hash%h->size);
|
printf("h_entry_find([%.*s]): hash=%#lx (%lu) - ", l, s, hash, hash%h->size);
|
||||||
# endif
|
# endif
|
||||||
hash%=h->size;
|
hash%=h->size;
|
||||||
@@ -70,7 +86,7 @@ h_entry_t *h_entry_find(hash_t *h, const unsigned char *s, const int l)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG_HASH
|
||||||
printf("ret=%p\n", found? (void *)entry: (void *)-1);
|
printf("ret=%p\n", found? (void *)entry: (void *)-1);
|
||||||
# endif
|
# endif
|
||||||
return found? entry: NULL;
|
return found? entry: NULL;
|
||||||
@@ -86,17 +102,15 @@ h_entry_t *h_entry_add(hash_t *h, const unsigned char *s, const int l, int *inse
|
|||||||
if (!pool_free) {
|
if (!pool_free) {
|
||||||
register int i=n_entries;
|
register int i=n_entries;
|
||||||
|
|
||||||
n_entries+=ENTRY_ALLOC_SIZE;
|
n_entries+=POOL_ALLOC_SIZE;
|
||||||
# ifdef DEBUG
|
# ifdef DEBUG_HASH
|
||||||
printf("get_hash: allocating %d new entries - total entries=%d\n",
|
printf("get_hash: allocating %d new entries - total entries=%d\n",
|
||||||
ENTRY_ALLOC_SIZE, n_entries);
|
POOL_ALLOC_SIZE, n_entries);
|
||||||
# endif
|
# endif
|
||||||
alloc_entries=reallocarray(alloc_entries, n_entries, sizeof(h_entry_t));
|
alloc_entries=reallocarray(alloc_entries, n_entries, sizeof(h_entry_t));
|
||||||
|
|
||||||
for (; i<n_entries; ++i) { /* create free entries list */
|
for (; i<n_entries; ++i)
|
||||||
(alloc_entries+i)->next=pool_free;
|
h_entry_free(alloc_entries+i);
|
||||||
pool_free=alloc_entries+i;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ((entry=h_entry_find(h, s, l)))
|
if ((entry=h_entry_find(h, s, l)))
|
||||||
return entry;
|
return entry;
|
||||||
@@ -116,8 +130,7 @@ h_entry_t *h_entry_add(hash_t *h, const unsigned char *s, const int l, int *inse
|
|||||||
entry->data=(unsigned char *)s;
|
entry->data=(unsigned char *)s;
|
||||||
entry->key_len=l;
|
entry->key_len=l;
|
||||||
|
|
||||||
//assert(entry!=freenodes);
|
# ifdef DEBUG_HASH
|
||||||
# ifdef DEBUG
|
|
||||||
printf("h_entry_add: %p\n", (void *)entry);
|
printf("h_entry_add: %p\n", (void *)entry);
|
||||||
# endif
|
# endif
|
||||||
return entry;
|
return entry;
|
||||||
|
@@ -30,23 +30,25 @@ typedef struct {
|
|||||||
h_entry_t *entries[1024];
|
h_entry_t *entries[1024];
|
||||||
} hash_1024_t;
|
} hash_1024_t;
|
||||||
|
|
||||||
#define ENTRY_ALLOC_SIZE 20
|
#define POOL_ALLOC_SIZE 1024
|
||||||
|
|
||||||
/* hash map functions */
|
/* hash map functions */
|
||||||
|
// TODO: hash function parameter
|
||||||
hash_t *h_create(int size);
|
hash_t *h_create(int size);
|
||||||
void h_init(hash_t *);
|
void h_init(hash_t *);
|
||||||
void h_destroy(hash_t *);
|
void h_destroy(hash_t *);
|
||||||
|
void h_free_all(hash_t *);
|
||||||
|
|
||||||
/* static free_nodes */
|
/* TODO: static free_nodes */
|
||||||
void set_pool_free_static(h_entry_t *p);
|
// void set_pool_free_static(h_entry_t *p);
|
||||||
|
|
||||||
/* hash entries functions */
|
/* hash entries functions */
|
||||||
h_entry_t *h_entry_add(hash_t *, const unsigned char *, const int, int *);
|
|
||||||
h_entry_t *h_entry_find(hash_t *, const unsigned char *, const int);
|
h_entry_t *h_entry_find(hash_t *, const unsigned char *, const int);
|
||||||
|
h_entry_t *h_entry_add(hash_t *, const unsigned char *, const int, int *);
|
||||||
void h_entry_free(h_entry_t *);
|
void h_entry_free(h_entry_t *);
|
||||||
|
// TODO: delete entry
|
||||||
|
|
||||||
|
/* hash functions */
|
||||||
/* hash function */
|
|
||||||
unsigned long hash_djb2(const unsigned char *str, const int len);
|
unsigned long hash_djb2(const unsigned char *str, const int len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -33,9 +33,6 @@ static word_t next_word(const char **p)
|
|||||||
static char tmp[1024];
|
static char tmp[1024];
|
||||||
int pos=0;
|
int pos=0;
|
||||||
|
|
||||||
# ifdef DEBUG
|
|
||||||
printf("next_word(%s)\n", *p);
|
|
||||||
# endif
|
|
||||||
for (; *p1 && !isalpha(*p1) && !isdigit(*p1); ++p1)
|
for (; *p1 && !isalpha(*p1) && !isdigit(*p1); ++p1)
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -70,18 +67,11 @@ static word_t next_word(const char **p)
|
|||||||
*p=q;
|
*p=q;
|
||||||
}
|
}
|
||||||
end:
|
end:
|
||||||
# ifdef DEBUG
|
|
||||||
printf("next_word: [%s], %d\n", res.word? res.word: "NULL", res.len);
|
|
||||||
# endif
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int insert_word(word_count_word_t *words, word_t w, int pos)
|
static int insert_word(word_count_word_t *words, word_t w, int pos)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
|
||||||
printf("insert words(len=%d word=[%.*s])\n", w.len, w.len, w.word);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
memcpy(words[pos].text, w.word, w.len);
|
memcpy(words[pos].text, w.word, w.len);
|
||||||
words[pos].text[w.len]=0;
|
words[pos].text[w.len]=0;
|
||||||
words[pos].count=0;
|
words[pos].count=0;
|
||||||
@@ -94,14 +84,8 @@ int count_words(const char *sentence, word_count_word_t *words)
|
|||||||
int current=0, new, index;
|
int current=0, new, index;
|
||||||
hash_t *hash;
|
hash_t *hash;
|
||||||
h_entry_t *e;
|
h_entry_t *e;
|
||||||
# ifdef DEBUG
|
|
||||||
const char *s=sentence;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
hash=h_create(16);
|
hash=h_create(16);
|
||||||
# ifdef DEBUG
|
|
||||||
printf("count_words([%s], %p)\n", sentence, (void *)words);
|
|
||||||
# endif
|
|
||||||
for (; *sentence;) {
|
for (; *sentence;) {
|
||||||
w=next_word(&sentence);
|
w=next_word(&sentence);
|
||||||
if (!w.word)
|
if (!w.word)
|
||||||
@@ -117,12 +101,6 @@ int count_words(const char *sentence, word_count_word_t *words)
|
|||||||
}
|
}
|
||||||
index=(word_count_word_t *)e->data-&words[0];
|
index=(word_count_word_t *)e->data-&words[0];
|
||||||
words[index].count++;
|
words[index].count++;
|
||||||
//sentence=w.word+w.len;
|
|
||||||
//sentence+=w.len;
|
|
||||||
# ifdef DEBUG
|
|
||||||
printf("count_words: index=%d\n", index);
|
|
||||||
printf("offset=%d\n", (int)(sentence-s));
|
|
||||||
# endif
|
|
||||||
}
|
}
|
||||||
h_destroy(hash);
|
h_destroy(hash);
|
||||||
return current;
|
return current;
|
||||||
@@ -139,7 +117,6 @@ static void print_wtable(int n)
|
|||||||
{
|
{
|
||||||
for (int i=0; i<n; ++i) {
|
for (int i=0; i<n; ++i) {
|
||||||
printf ("%2d: %2d x \"%s\"\n", i, wtable[i].count, wtable[i].text);
|
printf ("%2d: %2d x \"%s\"\n", i, wtable[i].count, wtable[i].text);
|
||||||
//djb2_hash(wtable[i].text));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -148,15 +125,11 @@ int main(int ac, char **av)
|
|||||||
{
|
{
|
||||||
int arg=1;
|
int arg=1;
|
||||||
int res;
|
int res;
|
||||||
//hash=h_create(16);
|
|
||||||
for (; arg<ac; ++arg) {
|
for (; arg<ac; ++arg) {
|
||||||
reset_wtable();
|
reset_wtable();
|
||||||
res=count_words(av[arg], wtable);
|
res=count_words(av[arg], wtable);
|
||||||
printf ("res=%d\n", res);
|
printf ("res=%d\n", res);
|
||||||
print_wtable(res);
|
print_wtable(res);
|
||||||
}
|
}
|
||||||
//printf("h_destroy 1\n");
|
|
||||||
//h_destroy(hash);
|
|
||||||
//printf("h_destroy 1\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user