Hashtable: widen size from int to size_t

This commit is contained in:
Christian Göttsche 2021-01-04 23:25:28 +01:00 committed by cgzones
parent 7043a93eba
commit ca2c01bd16
2 changed files with 35 additions and 34 deletions

View File

@ -21,14 +21,14 @@ in the source distribution for its full text.
typedef struct HashtableItem_ { typedef struct HashtableItem_ {
ht_key_t key; ht_key_t key;
unsigned int probe; size_t probe;
void* value; void* value;
} HashtableItem; } HashtableItem;
struct Hashtable_ { struct Hashtable_ {
unsigned int size; size_t size;
HashtableItem* buckets; HashtableItem* buckets;
unsigned int items; size_t items;
bool owner; bool owner;
}; };
@ -36,15 +36,15 @@ struct Hashtable_ {
#ifndef NDEBUG #ifndef NDEBUG
static void Hashtable_dump(const Hashtable* this) { static void Hashtable_dump(const Hashtable* this) {
fprintf(stderr, "Hashtable %p: size=%u items=%u owner=%s\n", fprintf(stderr, "Hashtable %p: size=%zu items=%zu owner=%s\n",
(const void*)this, (const void*)this,
this->size, this->size,
this->items, this->items,
this->owner ? "yes" : "no"); this->owner ? "yes" : "no");
unsigned int items = 0; size_t items = 0;
for (unsigned int i = 0; i < this->size; i++) { for (size_t i = 0; i < this->size; i++) {
fprintf(stderr, " item %5u: key = %5u probe = %2u value = %p\n", fprintf(stderr, " item %5zu: key = %5u probe = %2zu value = %p\n",
i, i,
this->buckets[i].key, this->buckets[i].key,
this->buckets[i].probe, this->buckets[i].probe,
@ -54,15 +54,15 @@ static void Hashtable_dump(const Hashtable* this) {
items++; items++;
} }
fprintf(stderr, "Hashtable %p: items=%u counted=%u\n", fprintf(stderr, "Hashtable %p: items=%zu counted=%zu\n",
(const void*)this, (const void*)this,
this->items, this->items,
items); items);
} }
static bool Hashtable_isConsistent(const Hashtable* this) { static bool Hashtable_isConsistent(const Hashtable* this) {
unsigned int items = 0; size_t items = 0;
for (unsigned int i = 0; i < this->size; i++) { for (size_t i = 0; i < this->size; i++) {
if (this->buckets[i].value) if (this->buckets[i].value)
items++; items++;
} }
@ -72,9 +72,9 @@ static bool Hashtable_isConsistent(const Hashtable* this) {
return res; return res;
} }
unsigned int Hashtable_count(const Hashtable* this) { size_t Hashtable_count(const Hashtable* this) {
unsigned int items = 0; size_t items = 0;
for (unsigned int i = 0; i < this->size; i++) { for (size_t i = 0; i < this->size; i++) {
if (this->buckets[i].value) if (this->buckets[i].value)
items++; items++;
} }
@ -94,10 +94,10 @@ static const uint64_t OEISprimes[] = {
34359738337, 68719476731, 137438953447 34359738337, 68719476731, 137438953447
}; };
static uint64_t nextPrime(unsigned int n) { static uint64_t nextPrime(size_t n) {
assert(n <= OEISprimes[ARRAYSIZE(OEISprimes) - 1]); assert(n <= OEISprimes[ARRAYSIZE(OEISprimes) - 1]);
for (unsigned int i = 0; i < ARRAYSIZE(OEISprimes); i++) { for (size_t i = 0; i < ARRAYSIZE(OEISprimes); i++) {
if (n <= OEISprimes[i]) if (n <= OEISprimes[i])
return OEISprimes[i]; return OEISprimes[i];
} }
@ -105,7 +105,7 @@ static uint64_t nextPrime(unsigned int n) {
return OEISprimes[ARRAYSIZE(OEISprimes) - 1]; return OEISprimes[ARRAYSIZE(OEISprimes) - 1];
} }
Hashtable* Hashtable_new(unsigned int size, bool owner) { Hashtable* Hashtable_new(size_t size, bool owner) {
Hashtable* this; Hashtable* this;
this = xMalloc(sizeof(Hashtable)); this = xMalloc(sizeof(Hashtable));
@ -129,7 +129,7 @@ void Hashtable_clear(Hashtable* this) {
assert(Hashtable_isConsistent(this)); assert(Hashtable_isConsistent(this));
if (this->owner) if (this->owner)
for (unsigned int i = 0; i < this->size; i++) for (size_t i = 0; i < this->size; i++)
free(this->buckets[i].value); free(this->buckets[i].value);
memset(this->buckets, 0, this->size * sizeof(HashtableItem)); memset(this->buckets, 0, this->size * sizeof(HashtableItem));
@ -139,10 +139,10 @@ void Hashtable_clear(Hashtable* this) {
} }
static void insert(Hashtable* this, ht_key_t key, void* value) { static void insert(Hashtable* this, ht_key_t key, void* value) {
unsigned int index = key % this->size; size_t index = key % this->size;
unsigned int probe = 0; size_t probe = 0;
#ifndef NDEBUG #ifndef NDEBUG
unsigned int origIndex = index; size_t origIndex = index;
#endif #endif
for (;;) { for (;;) {
@ -181,7 +181,7 @@ static void insert(Hashtable* this, ht_key_t key, void* value) {
} }
} }
void Hashtable_setSize(Hashtable* this, unsigned int size) { void Hashtable_setSize(Hashtable* this, size_t size) {
assert(Hashtable_isConsistent(this)); assert(Hashtable_isConsistent(this));
@ -189,14 +189,14 @@ void Hashtable_setSize(Hashtable* this, unsigned int size) {
return; return;
HashtableItem* oldBuckets = this->buckets; HashtableItem* oldBuckets = this->buckets;
unsigned int oldSize = this->size; size_t oldSize = this->size;
this->size = nextPrime(size); this->size = nextPrime(size);
this->buckets = (HashtableItem*) xCalloc(this->size, sizeof(HashtableItem)); this->buckets = (HashtableItem*) xCalloc(this->size, sizeof(HashtableItem));
this->items = 0; this->items = 0;
/* rehash */ /* rehash */
for (unsigned int i = 0; i < oldSize; i++) { for (size_t i = 0; i < oldSize; i++) {
if (!oldBuckets[i].value) if (!oldBuckets[i].value)
continue; continue;
@ -226,10 +226,10 @@ void Hashtable_put(Hashtable* this, ht_key_t key, void* value) {
} }
void* Hashtable_remove(Hashtable* this, ht_key_t key) { void* Hashtable_remove(Hashtable* this, ht_key_t key) {
unsigned int index = key % this->size; size_t index = key % this->size;
unsigned int probe = 0; size_t probe = 0;
#ifndef NDEBUG #ifndef NDEBUG
unsigned int origIndex = index; size_t origIndex = index;
#endif #endif
assert(Hashtable_isConsistent(this)); assert(Hashtable_isConsistent(this));
@ -244,7 +244,7 @@ void* Hashtable_remove(Hashtable* this, ht_key_t key) {
res = this->buckets[index].value; res = this->buckets[index].value;
} }
unsigned int next = (index + 1) % this->size; size_t next = (index + 1) % this->size;
while (this->buckets[next].value && this->buckets[next].probe > 0) { while (this->buckets[next].value && this->buckets[next].probe > 0) {
this->buckets[index] = this->buckets[next]; this->buckets[index] = this->buckets[next];
@ -281,11 +281,11 @@ void* Hashtable_remove(Hashtable* this, ht_key_t key) {
} }
void* Hashtable_get(Hashtable* this, ht_key_t key) { void* Hashtable_get(Hashtable* this, ht_key_t key) {
unsigned int index = key % this->size; size_t index = key % this->size;
unsigned int probe = 0; size_t probe = 0;
void* res = NULL; void* res = NULL;
#ifndef NDEBUG #ifndef NDEBUG
unsigned int origIndex = index; size_t origIndex = index;
#endif #endif
assert(Hashtable_isConsistent(this)); assert(Hashtable_isConsistent(this));
@ -310,7 +310,7 @@ void* Hashtable_get(Hashtable* this, ht_key_t key) {
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) { void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {
assert(Hashtable_isConsistent(this)); assert(Hashtable_isConsistent(this));
for (unsigned int i = 0; i < this->size; i++) { for (size_t i = 0; i < this->size; i++) {
HashtableItem* walk = &this->buckets[i]; HashtableItem* walk = &this->buckets[i];
if (walk->value) if (walk->value)
f(walk->key, walk->value, userData); f(walk->key, walk->value, userData);

View File

@ -8,6 +8,7 @@ in the source distribution for its full text.
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
typedef unsigned int ht_key_t; typedef unsigned int ht_key_t;
@ -18,17 +19,17 @@ typedef struct Hashtable_ Hashtable;
#ifndef NDEBUG #ifndef NDEBUG
unsigned int Hashtable_count(const Hashtable* this); size_t Hashtable_count(const Hashtable* this);
#endif /* NDEBUG */ #endif /* NDEBUG */
Hashtable* Hashtable_new(unsigned int size, bool owner); Hashtable* Hashtable_new(size_t size, bool owner);
void Hashtable_delete(Hashtable* this); void Hashtable_delete(Hashtable* this);
void Hashtable_clear(Hashtable* this); void Hashtable_clear(Hashtable* this);
void Hashtable_setSize(Hashtable* this, unsigned int size); void Hashtable_setSize(Hashtable* this, size_t size);
void Hashtable_put(Hashtable* this, ht_key_t key, void* value); void Hashtable_put(Hashtable* this, ht_key_t key, void* value);