summaryrefslogtreecommitdiff
path: root/girepository/cmph/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'girepository/cmph/hash.c')
-rw-r--r--girepository/cmph/hash.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/girepository/cmph/hash.c b/girepository/cmph/hash.c
new file mode 100644
index 00000000..be86d6e7
--- /dev/null
+++ b/girepository/cmph/hash.c
@@ -0,0 +1,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;
+}