1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
|
#include "hash_state.h"
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
//#define DEBUG
#include "debug.h"
const char *cmph_hash_names[] = { "jenkins", NULL };
hash_state_t *hash_state_new(CMPH_HASH hashfunc, cmph_uint32 hashsize)
{
hash_state_t *state = NULL;
switch (hashfunc)
{
case CMPH_HASH_JENKINS:
DEBUGP("Jenkins function - %u\n", hashsize);
state = (hash_state_t *)jenkins_state_new(hashsize);
DEBUGP("Jenkins function created\n");
break;
default:
assert(0);
}
state->hashfunc = hashfunc;
return state;
}
cmph_uint32 hash(hash_state_t *state, const char *key, cmph_uint32 keylen)
{
switch (state->hashfunc)
{
case CMPH_HASH_JENKINS:
return jenkins_hash((jenkins_state_t *)state, key, keylen);
default:
assert(0);
}
assert(0);
return 0;
}
void hash_vector(hash_state_t *state, const char *key, cmph_uint32 keylen, cmph_uint32 * hashes)
{
switch (state->hashfunc)
{
case CMPH_HASH_JENKINS:
jenkins_hash_vector_((jenkins_state_t *)state, key, keylen, hashes);
break;
default:
assert(0);
}
}
void hash_state_dump(hash_state_t *state, char **buf, cmph_uint32 *buflen)
{
char *algobuf;
size_t len;
switch (state->hashfunc)
{
case CMPH_HASH_JENKINS:
jenkins_state_dump((jenkins_state_t *)state, &algobuf, buflen);
if (*buflen == UINT_MAX) return;
break;
default:
assert(0);
}
*buf = (char *)malloc(strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen);
memcpy(*buf, cmph_hash_names[state->hashfunc], strlen(cmph_hash_names[state->hashfunc]) + 1);
DEBUGP("Algobuf is %u\n", *(cmph_uint32 *)algobuf);
len = *buflen;
memcpy(*buf + strlen(cmph_hash_names[state->hashfunc]) + 1, algobuf, len);
*buflen = (cmph_uint32)strlen(cmph_hash_names[state->hashfunc]) + 1 + *buflen;
free(algobuf);
return;
}
hash_state_t * hash_state_copy(hash_state_t *src_state)
{
hash_state_t *dest_state = NULL;
switch (src_state->hashfunc)
{
case CMPH_HASH_JENKINS:
dest_state = (hash_state_t *)jenkins_state_copy((jenkins_state_t *)src_state);
break;
default:
assert(0);
}
dest_state->hashfunc = src_state->hashfunc;
return dest_state;
}
hash_state_t *hash_state_load(const char *buf, cmph_uint32 buflen)
{
cmph_uint32 i;
cmph_uint32 offset;
CMPH_HASH hashfunc = CMPH_HASH_COUNT;
for (i = 0; i < CMPH_HASH_COUNT; ++i)
{
if (strcmp(buf, cmph_hash_names[i]) == 0)
{
hashfunc = i;
break;
}
}
if (hashfunc == CMPH_HASH_COUNT) return NULL;
offset = (cmph_uint32)strlen(cmph_hash_names[hashfunc]) + 1;
switch (hashfunc)
{
case CMPH_HASH_JENKINS:
return (hash_state_t *)jenkins_state_load(buf + offset, buflen - offset);
default:
return NULL;
}
return NULL;
}
void hash_state_destroy(hash_state_t *state)
{
switch (state->hashfunc)
{
case CMPH_HASH_JENKINS:
jenkins_state_destroy((jenkins_state_t *)state);
break;
default:
assert(0);
}
return;
}
/** \fn void hash_state_pack(hash_state_t *state, void *hash_packed)
* \brief Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed.
* \param state points to the hash function
* \param hash_packed pointer to the contiguous memory area used to store the hash function. The size of hash_packed must be at least hash_state_packed_size()
*
* Support the ability to pack a hash function into a preallocated contiguous memory space pointed by hash_packed.
* However, the hash function type must be packed outside.
*/
void hash_state_pack(hash_state_t *state, void *hash_packed)
{
switch (state->hashfunc)
{
case CMPH_HASH_JENKINS:
// pack the jenkins hash function
jenkins_state_pack((jenkins_state_t *)state, hash_packed);
break;
default:
assert(0);
}
return;
}
/** \fn cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc)
* \brief Return the amount of space needed to pack a hash function.
* \param hashfunc function type
* \return the size of the packed function or zero for failures
*/
cmph_uint32 hash_state_packed_size(CMPH_HASH hashfunc)
{
cmph_uint32 size = 0;
switch (hashfunc)
{
case CMPH_HASH_JENKINS:
size += jenkins_state_packed_size();
break;
default:
assert(0);
}
return size;
}
/** \fn cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen)
* \param hash_packed is a pointer to a contiguous memory area
* \param hashfunc is the type of the hash function packed in hash_packed
* \param key is a pointer to a key
* \param keylen is the key length
* \return an integer that represents a hash value of 32 bits.
*/
cmph_uint32 hash_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen)
{
switch (hashfunc)
{
case CMPH_HASH_JENKINS:
return jenkins_hash_packed(hash_packed, k, keylen);
default:
assert(0);
}
assert(0);
return 0;
}
/** \fn hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes)
* \param hash_packed is a pointer to a contiguous memory area
* \param key is a pointer to a key
* \param keylen is the key length
* \param hashes is a pointer to a memory large enough to fit three 32-bit integers.
*/
void hash_vector_packed(void *hash_packed, CMPH_HASH hashfunc, const char *k, cmph_uint32 keylen, cmph_uint32 * hashes)
{
switch (hashfunc)
{
case CMPH_HASH_JENKINS:
jenkins_hash_vector_packed(hash_packed, k, keylen, hashes);
break;
default:
assert(0);
}
}
/** \fn CMPH_HASH hash_get_type(hash_state_t *state);
* \param state is a pointer to a hash_state_t structure
* \return the hash function type pointed by state
*/
CMPH_HASH hash_get_type(hash_state_t *state)
{
return state->hashfunc;
}
|