in reply to Re^4: can I change hash keys or values directly
in thread can I change hash keys or values directly
And this means a stored key must be immutable , because that calculated array-index would change too.
The stored key is immutable in this sense, but the calculated array-index for the linked list containing that particular key can change based upon the size of the hash.
This is true:
Consequently there can't be a faster way than replacing the whole key-value pair with "delete OLD" + "store NEW".
One hashing algorithm that has been used before in Perl is:
s is a pointer to a null terminated ASCII string.unsigned int hash = 0; while (*s) hash = hash * 33 + *s++;
--UPDATE ---
Just for fun, I attach actual C code from memtracker.h from 2010 and the 2013 update.
The program uses an integer as the "hash key". Some obvious performance enhancements mentioned in the comments to version 2 were not actually coded because it just didn't matter! The longer version is much, much faster. Shorter code does not equal faster code. The HTTP addresses in the code probably don't work anymore since they are more than a decade old! Also noteworthy: this code was only tested on a 32 bit machine.
/* MT_gen_hash_bits() * Dan Bernstein's hash function - works great for short ASCII strin +gs! * This is an empirical thing that "just works" without mathematical * proof. Noteworthy: this is algorithm used by Perl. * http://burtleburtle.net/bob/hash/doobs.html */ unsigned int MT_gen_hash_bits (unsigned long int address) { char ascii[21]; // max 64 bit unsigned int is 20 decimal digits sprintf (ascii, "%lu", address); char *s = ascii; unsigned int hash = 0; while (*s) hash = hash * 33 + *s++; return hash; } /* MT_gen_hash_bits_version2() * Thomas Wang's 64-bit hash function - works well for integers, and + is significantly * faster than the DJB function since the key is not ASCII. It is a +lso slightly * better in distributing keys. * http://www.concentric.net/~Ttwang/tech/inthash.htm */ unsigned int MT_gen_hash_bits (unsigned long int address) { address = (~address) + (address << 21); // address = (address << 21) + - address - 1; address = address ^ (address >> 24); address = (address + (address << 3)) + (address << 8); // address * +265 address = address ^ (address >> 14); address = (address + (address << 2)) + (address << 4); // address * +21 address = address ^ (address >> 28); address = address + (address << 31); return (unsigned int)address; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^6: can I change hash keys or values directly
by LanX (Saint) on Feb 05, 2021 at 08:38 UTC | |
by Marshall (Canon) on Feb 05, 2021 at 09:13 UTC | |
|
Re^6: can I change hash keys or values directly
by LanX (Saint) on Feb 05, 2021 at 16:11 UTC | |
by Marshall (Canon) on Feb 08, 2021 at 18:53 UTC | |
by LanX (Saint) on Feb 08, 2021 at 19:11 UTC | |
by Marshall (Canon) on Feb 08, 2021 at 20:30 UTC |