X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/369233927c6fc7f398d6ff4ea14ac8d648e19eae..b3bf9b9df95137a3a43248be9599d919b04877af:/hashtable.c diff --git a/hashtable.c b/hashtable.c index d1be1b8a..d5f1d110 100644 --- a/hashtable.c +++ b/hashtable.c @@ -1,7 +1,7 @@ /* * Routines to provide a memory-efficient hashtable. * - * Copyright (C) 2007 Wayne Davison + * Copyright (C) 2007-2009 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,13 +23,13 @@ struct hashtable *hashtable_create(int size, int key64) { + int req = size; struct hashtable *tbl; - int node_size = key64 ? sizeof (struct ht_int64_node ) + int node_size = key64 ? sizeof (struct ht_int64_node) : sizeof (struct ht_int32_node); /* Pick a power of 2 that can hold the requested size. */ if (size & (size-1) || size < 16) { - int req = size; size = 16; while (size < req) size *= 2; @@ -41,12 +41,27 @@ struct hashtable *hashtable_create(int size, int key64) tbl->size = size; tbl->entries = 0; tbl->node_size = node_size; + tbl->key64 = (short)key64; + + if (DEBUG_GTE(HASH, 1)) { + char buf[32]; + if (req != size) + snprintf(buf, sizeof buf, "req: %d, ", req); + else + *buf = '\0'; + rprintf(FINFO, "[%s] created hashtable %lx (%ssize: %d, keys: %d-bit)\n", + who_am_i(), (long)tbl, buf, size, key64 ? 64 : 32); + } return tbl; } void hashtable_destroy(struct hashtable *tbl) { + if (DEBUG_GTE(HASH, 1)) { + rprintf(FINFO, "[%s] destroyed hashtable %lx (size: %d, keys: %d-bit)\n", + who_am_i(), (long)tbl, tbl->size, tbl->key64 ? 64 : 32); + } free(tbl->nodes); free(tbl); } @@ -55,7 +70,7 @@ void hashtable_destroy(struct hashtable *tbl) * already existing. Returns NULL if not allocating and not found. */ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing) { - int key64 = (tbl->node_size > sizeof (struct ht_int32_node)); + int key64 = tbl->key64; struct ht_int32_node *node; uint32 ndx; @@ -69,6 +84,11 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing) tbl->size = size; tbl->entries = 0; + if (DEBUG_GTE(HASH, 1)) { + rprintf(FINFO, "[%s] growing hashtable %lx (size: %d, keys: %d-bit)\n", + who_am_i(), (long)tbl, size, key64 ? 64 : 32); + } + for (i = size / 2; i-- > 0; ) { struct ht_int32_node *move_node = HT_NODE(tbl, old_nodes, i); int64 move_key = HT_KEY(move_node, key64); @@ -103,7 +123,9 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing) a = b = c = 0xdeadbeef + (8 << 2); #define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k)))) +#if SIZEOF_INT64 >= 8 b += (uint32)(key >> 32); +#endif a += (uint32)key; c ^= b; c -= rot(b, 14); a ^= c; a -= rot(c, 11); @@ -139,7 +161,7 @@ void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing) if (key64) ((struct ht_int64_node*)node)->key = key; else - node->key = key; + node->key = (int32)key; tbl->entries++; return node; }