This fixes an issus in Hashtable_dump where `"(nil"` is passed as an
argument to `%p` in fprintf. This prints the static address of `"(nil)"`
not "(nil)". This commit changes the code to just pass the NULL pointer
to fprintf, which will consistently print "0x0".
With a size of 2 or 3 the grow factor does not reach 70% for one empty
entry. This will cause the following assert violation:
htop: Hashtable.c:236: void Hashtable_put(Hashtable *, ht_key_t, void *): Assertion `this->size > this->items' failed.
Due to the use of prime numbers Hashtable_remove used to never shrink
from some sizes. For example, a size 8191 hashtable would try to shrink
to 4095, which nextPrime would round back to 8191 instead of the
intended 4093. A factor of 3 is enough to allow every prime size used to
shrink to the previous one.
Dynamically increase the hashmap size to not exceed the load factor and
avoid too long chains.
Switch from Separate Chaining to Robin Hood linear probing to improve
cache locality.
Use primes as size to further avoid collisions.
E.g. on a standard kde system the number of entries in the ProcessTable
might be around 650.
Use NDEBUG conditional instead of DEBUG.
Do not call static functions in extern inline ones.
Vector.c:67:11: error: static function 'Vector_isConsistent' is used in an inline function with external linkage [-Werror,-Wstatic-in-inline]
Reasoning:
- implementation was unsound -- broke down when I added a fairly
basic macro definition expanding to a struct initializer in a *.c
file.
- made it way too easy (e.g. via otherwise totally innocuous git
commands) to end up with timestamps such that it always ran
MakeHeader.py but never used its output, leading to overbuild noise
when running what should be a null 'make'.
- but mostly: it's just an awkward way of dealing with C code.
disable useless code in release builds such as runtime type-checking on
dynamic data structures and process fields that are not being computed,
faster(?) method for verifying the process owner (still need to ensure
correctness), don't destroy and create process objects for hidden kernel
threads over and over. Phew. I shouldn't be doing all this today, but I
could not resist.