|
这个define也太。。。。。
make_ ## 是什么意思
多次出现的##是什么意思,我查不到啊
#define HASH_CODE(HASH, HASH_KEY, HASH_VALUE, KEY_HASH, KEY_NEQ, KEY_COPY, \
KEY_FREE, NULL_VALUE, VALUE_FREE) \
\
/* HASH_HEADER(HASH, HASH_KEY, HASH_VALUE); */ \
\
HASH make_ ## HASH(size_t initial_size) \
{ \
HASH ht; \
ht = (HASH) MALLOC(sizeof(struct HASH ## _table)); \
ht->tablesize = preferred_size(initial_size); \
ht->size = 0; \
ht->table = (HASH ## _cell_ptr *) \
CALLOC(ht->tablesize, (size_t) sizeof(HASH ## _cell_ptr)); \
return ht; \
} \
\
size_t HASH ## _size(HASH ht) \
{ \
return ht->size; \
} \
\
\
static void HASH ## _resize(HASH ht) \
{ \
HASH ## _cell_ptr *oldtable = ht->table; \
size_t oldtablesize = ht->tablesize; \
size_t tablesize = preferred_size(ht->size); \
size_t i; \
HASH ## _cell_ptr p, nextp; \
\
ht->tablesize = tablesize; \
ht->table = (HASH ## _cell_ptr *) \
CALLOC(tablesize, (size_t) sizeof(HASH ## _cell_ptr)); \
\
for (i=0; i<oldtablesize; i++) \
for (p = oldtable; p; p = nextp) { \
nextp = p->next; \
p->next = ht->table[p->hashedkey%tablesize]; \
ht->table[p->hashedkey%tablesize] = p; \
} \
\
FREE(oldtable); \
} \
\
HASH ## _cell_ptr HASH ## _find(HASH ht, const HASH_KEY key) \
{ \
size_t hashedkey = KEY_HASH(key); \
size_t hashedkeymod = hashedkey%ht->tablesize; \
HASH ## _cell_ptr p = ht->table[hashedkeymod]; \
\
while (p && (p->hashedkey != hashedkey || KEY_NEQ(key, p->key))) \
p = p->next; \
\
if (p) \
return p; \
else { \
if (ht->size++ >= HASH_EXPAND_LOAD_FACTOR*ht->tablesize) { \
HASH ## _resize(ht); \
hashedkeymod = hashedkey%ht->tablesize; \
} \
p = MALLOC(sizeof(struct HASH ## _cell)); \
p->hashedkey = hashedkey; \
p->key = KEY_COPY(key); \
p->value = NULL_VALUE; \
p->next = ht->table[hashedkeymod]; \
ht->table[hashedkeymod] = p; \
return p; \
}} \
\
HASH_VALUE *HASH ## _valuep(HASH ht, const HASH_KEY key) \
{ \
return(&(HASH ## _find(ht, key)->value)); \
} \
\
HASH_VALUE HASH ## _ref(const HASH ht, const HASH_KEY key) \
{ \
size_t hashedkey = KEY_HASH(key); \
HASH ## _cell_ptr p = ht->table[hashedkey%ht->tablesize]; \
\
while (p && (p->hashedkey != hashedkey || KEY_NEQ(key, p->key))) \
p = p->next; \
\
return p ? p->value : NULL_VALUE; \
} \
\
HASH_VALUE HASH ## _set(HASH ht, HASH_KEY key, HASH_VALUE value) \
{ \
HASH ## _cell_ptr p = HASH ## _find(ht, key); \
HASH_VALUE oldvalue = p->value; \
p->value = value; \
return oldvalue; \
} \
\
HASH_VALUE HASH ## _delete(HASH ht, HASH_KEY key) \
{ \
HASH_VALUE oldvalue; \
size_t hashedkey = KEY_HASH(key); \
HASH ## _cell_ptr *p = ht->table + hashedkey%ht->tablesize; \
\
while ( *p && \
((*p)->hashedkey != hashedkey || KEY_NEQ(key, (*p)->key)) ) \
p = &((*p)->next); \
\
if (*p) { \
oldvalue = (*p)->value; \
*p = (*p)->next; \
KEY_FREE((*p)->key); \
FREE(*p); \
\
if (--ht->size < ht->tablesize/HASH_CONTRACT_LOAD_FACTOR) \
HASH ## _resize(ht); \
return oldvalue; \
} \
else \
return NULL_VALUE; \
} \
\
\
void free_ ## HASH(HASH ht) \
{ \
HASH ## _cell_ptr p, q; \
size_t i; \
\
for (i = 0; i < ht->tablesize; i++) \
for (p = ht->table; p; p = q) { \
q = p->next; \
KEY_FREE(p->key); \
VALUE_FREE(p->value); \
FREE(p); \
} \
FREE(ht->table); \
FREE(ht); \
} \
\
/*************************************************************************** \
* * \
* hash iteration * \
* * \
***************************************************************************/ \
\
\
HASH ## it HASH ## it_init(HASH ht) \
{ \
struct HASH ## it hit = {0, NULL_VALUE, ht, NULL, 0}; \
return HASH ## it_next(hit); \
} \
\
HASH ## it HASH ## it_next(HASH ## it hit0) \
{ \
if (hit0.next) { \
hit0.key = hit0.next->key; \
hit0.value = hit0.next->value; \
hit0.next = hit0.next->next; \
return hit0; \
} \
else { \
size_t i = hit0.index; \
size_t tablesize = hit0.ht->tablesize; \
HASH ## _cell_ptr *table = hit0.ht->table; \
while (i < tablesize && !table) \
i++; \
if (i==tablesize) { \
hit0.ht = NULL; \
return hit0; \
} \
else { \
hit0.key = table->key; \
hit0.value = table->value; \
hit0.next = table->next; \
hit0.index = i+1; \
return hit0; \
}}} \
\
int HASH ## it_ok(HASH ## it hit) \
{ \
return hit.ht!=NULL; \
}
#define HASH_CODE_ADD(HASH, HASH_KEY, HASH_VALUE, KEY_HASH, KEY_NEQ, \
KEY_COPY, KEY_FREE, NULL_VALUE, VALUE_FREE) \
\
HASH_CODE(HASH, HASH_KEY, HASH_VALUE, KEY_HASH, KEY_NEQ, \
KEY_COPY, KEY_FREE, NULL_VALUE, VALUE_FREE) \
\
HASH_VALUE HASH ## _inc(HASH ht, const HASH_KEY key, HASH_VALUE inc) \
{ \
/* size_t hashedkey = KEY_HASH(key); */ \
HASH ## _cell_ptr p = HASH ## _find(ht, key); \
\
p->value += inc; \
return p->value; \
} |
|