2004-10-18 18:24:54 +00:00
|
|
|
|
2011-06-13 10:19:44 +00:00
|
|
|
#include <stasis/util/crc32.h>
|
2011-10-06 17:11:22 +00:00
|
|
|
#include <stasis/util/log2.h>
|
2008-10-03 02:42:25 +00:00
|
|
|
#include <stasis/common.h>
|
2004-10-12 02:44:47 +00:00
|
|
|
|
2004-10-18 18:24:54 +00:00
|
|
|
#ifndef __HASH_H
|
|
|
|
#define __HASH_H
|
2006-05-25 00:02:46 +00:00
|
|
|
|
2009-08-14 06:31:13 +00:00
|
|
|
#ifndef HASH_ENTRY
|
|
|
|
#define HASH_ENTRY(x) stasis_linear_hash##x
|
|
|
|
#define HASH_FCN(x,y,z) stasis_crc32(x,y,z)
|
|
|
|
#endif
|
|
|
|
|
2009-02-20 23:42:54 +00:00
|
|
|
static inline unsigned long stasis_util_two_to_the (char x) {
|
|
|
|
return (1 << ((long)x));
|
|
|
|
}
|
|
|
|
|
2006-05-24 02:19:04 +00:00
|
|
|
/**
|
2009-02-20 23:42:54 +00:00
|
|
|
This function maps from the length of the bucket list to a appropriate set
|
2006-05-24 02:19:04 +00:00
|
|
|
of linear hash parameters to fill that size.
|
|
|
|
*/
|
2009-08-14 06:31:13 +00:00
|
|
|
static inline void HASH_ENTRY(_get_size_params)(uint64_t desiredSize,
|
2009-02-20 23:42:54 +00:00
|
|
|
unsigned char * tableBits, uint64_t* nextExtension) {
|
2011-10-06 17:11:22 +00:00
|
|
|
*tableBits = stasis_log_2_64(desiredSize)+1;
|
2009-02-20 23:42:54 +00:00
|
|
|
*nextExtension = ((desiredSize) - stasis_util_two_to_the(*tableBits-1));
|
|
|
|
}
|
|
|
|
|
2008-10-03 02:42:25 +00:00
|
|
|
/**
|
2009-02-20 23:42:54 +00:00
|
|
|
@todo despite it's interface, stasis_linear_hash can't return values > 2^32!
|
2008-10-03 02:42:25 +00:00
|
|
|
*/
|
2013-02-13 21:27:51 +00:00
|
|
|
static inline uint64_t HASH_ENTRY(fcn)(const void * val, uint64_t val_length,
|
2009-02-20 23:42:54 +00:00
|
|
|
unsigned char tableBits, uint64_t nextExtension) {
|
|
|
|
// Calculate the hash value as it was before this round of splitting.
|
|
|
|
unsigned int oldTableLength = stasis_util_two_to_the(tableBits - 1);
|
2009-08-14 06:31:13 +00:00
|
|
|
unsigned int unmixed = HASH_FCN(val, val_length, (unsigned int)-1);
|
2009-02-20 23:42:54 +00:00
|
|
|
unsigned int ret = unmixed & (oldTableLength - 1);
|
|
|
|
|
|
|
|
// If the hash value is before the point in this round where we've split,
|
|
|
|
// use the new value instead. (The new value may be the same as the
|
|
|
|
// old value.)
|
|
|
|
if(ret < nextExtension) { /* Might be too low. */
|
|
|
|
unsigned int tableLength = stasis_util_two_to_the(tableBits);
|
|
|
|
ret = unmixed & (tableLength - 1);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2004-10-18 18:24:54 +00:00
|
|
|
#endif /*__HASH_H */
|
2009-08-14 06:31:13 +00:00
|
|
|
|