Skip to content

Commit

Permalink
consistent hash utility
Browse files Browse the repository at this point in the history
Signed-off-by: Aakash Arayambeth <[email protected]>
  • Loading branch information
Aakash Arayambeth authored and aakash10292 committed Apr 29, 2024
1 parent 1e5d274 commit de6604c
Show file tree
Hide file tree
Showing 12 changed files with 1,440 additions and 0 deletions.
101 changes: 101 additions & 0 deletions bbinc/consistent_hash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#ifndef CH_HASH_H
#define CH_HASH_H
#include <stddef.h>
#include <stdint.h>
#include <openssl/bn.h>
#include <list.h>
typedef struct consistent_hash ch_hash_t;
typedef struct consistent_hash_node ch_hash_node_t;
typedef int (*hash_func)(uint8_t *, size_t, uint32_t *);
enum ch_err {
CH_NOERR = 0,
CH_ERR_PARAM = 1,
CH_ERR_MALLOC = 2,
CH_ERR_HASH = 3,
CH_ERR_DUP = 4
};

struct consistent_hash_node {
uint8_t *data;
size_t data_len;
LINKC_T(struct consistent_hash_node) lnk;
};

typedef struct consistent_hash_keyhash {
uint64_t hash_val;
struct consistent_hash_node *node;
}ch_keyhash_t;

struct consistent_hash {
LISTC_T(struct consistent_hash_node) nodes; /* List of nodes for key hashes to refer to */
uint32_t num_nodes;
struct consistent_hash_keyhash **key_hashes; /* Array of key hashes of nodes and (optionally)
their copies. I went with an array over a hash
since we need this list to be sorted in order to look
up the next largest keyhash that has an associated node,
given a keyhash*/
uint32_t num_keyhashes;
pthread_rwlock_t lock;
hash_func func;
};

/*
* Create an in-mem abstraction of a consistent hash.
* num_copies -> number of copies of node to be added to the hash
* Db servers, cache servers are examples of a 'Node'
* ch_func -> pointer to the hash function to be used
* It takes a byte array and it's length as the input
* The hash is available in the OUT parameter hash as a BIGNUM
* www.openssl.org/docs/man1.0.2/man3/bn.html
*/
ch_hash_t *ch_hash_create(uint64_t num_copies, hash_func func);

/*
* Add a node to the consistent hash.
* name -> a byte array that represents the name of the node
* in the calling program.
* name_len -> length of above name
*/
int ch_hash_add_node(ch_hash_t *hash, uint8_t *name, size_t name_len, uint64_t hashval);


/*
* Add a replica for a node at hashval
* node_name -> node name for which replica is being added
* node_len -> size (in bytes) of node_name
*/
int ch_hash_add_replica(ch_hash_t *hash, uint8_t *node_name, size_t node_len, uint64_t hashval);


/*
* Remove a node from the consistent hash.
* name -> a byte array that represents the name of the node
* in the calling program.
* name_len -> length of above name
*/
int ch_hash_remove_node(ch_hash_t *hash, uint8_t *name, size_t name_len);

/*
* Given a key and it's length, return the node on the consistent hash
* that the inputs hash onto
*/
ch_hash_node_t *ch_hash_find_node(ch_hash_t *hash, uint8_t *key, size_t key_len);

/*
* Free all memory associated with a consistent hash
*/
void ch_hash_free(ch_hash_t *hash);

/*
* SHA256 and MD5 based hash funcs
*/
int ch_hash_sha(uint8_t *buf, size_t buf_len, uint32_t *hash);
int ch_hash_md5(uint8_t *buf, size_t buf_len, uint32_t *hash);


/*
* TEST HELPERS
*/
uint8_t *get_node_data(ch_hash_node_t *ch);
size_t get_node_data_len(ch_hash_node_t *ch);
#endif
12 changes: 12 additions & 0 deletions tests/consistent_hash.test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ifeq ($(TESTSROOTDIR),)
include ../testcase.mk
else
include $(TESTSROOTDIR)/testcase.mk
endif
ifeq ($(TEST_TIMEOUT),)
export TEST_TIMEOUT=1m
endif

# this is a local test, don't need cluster
unexport CLUSTER
export COMDB2_UNITTEST=1
1 change: 1 addition & 0 deletions tests/consistent_hash.test/README
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This test exercises the consistent hash utility
8 changes: 8 additions & 0 deletions tests/consistent_hash.test/runit
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

set -e
set -x

echo run executable that tests the consistent hash utility
${TESTSBUILDDIR}/test_consistent_hash

12 changes: 12 additions & 0 deletions tests/consistent_hash_bench.test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ifeq ($(TESTSROOTDIR),)
include ../testcase.mk
else
include $(TESTSROOTDIR)/testcase.mk
endif
ifeq ($(TEST_TIMEOUT),)
export TEST_TIMEOUT=1m
endif

# this is a local test, don't need cluster
unexport CLUSTER
export COMDB2_UNITTEST=1
5 changes: 5 additions & 0 deletions tests/consistent_hash_bench.test/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This test runs record distribution benchmark against the consistent hash utility
It creates 5 tables ( to simulate 5 shards) and inserts a million records into these 5 tables.
The table in which a record goes is decided by the consistent hash and the value of the field in the record
being inserted. Next, one of the tables(shards) is dropped, which causes a certain number of records to be
re-distributed. This test checks the distribution before dropping a table and after dropping a table
11 changes: 11 additions & 0 deletions tests/consistent_hash_bench.test/runit
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

set -e
set -x

echo run executable that tests the consistent hash utility
# s -> number of shards
# c -> number of copies(replicas) for each shard in the consistent hash
# r -> number of records to be inserted
${TESTSBUILDDIR}/test_consistent_hash_bench -s 5 -c 512 -r 1000000

5 changes: 5 additions & 0 deletions tests/tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,17 @@ add_exe(sqlite_clnt sqlite_clnt.c)
add_exe(ssl_multi_certs_one_process ssl_multi_certs_one_process.c)
add_exe(stepper stepper.c stepper_client.c)
add_exe(test_threadpool test_threadpool.c)
add_exe(test_consistent_hash test_consistent_hash.c)
add_exe(test_consistent_hash_bench test_consistent_hash_bench.c)
add_exe(updater updater.c testutil.c)
add_exe(utf8 utf8.c)
add_exe(verify_atomics_work verify_atomics_work.c)

target_link_libraries(cson_test cson)
target_link_libraries(stepper util mem dlmalloc util)
target_link_libraries(test_threadpool util mem dlmalloc util)
target_link_libraries(test_consistent_hash util mem dlmalloc util)
target_link_libraries(test_consistent_hash_bench util mem dlmalloc util)

list(APPEND common-deps
${READLINE_LIBRARIES}
Expand All @@ -87,6 +91,7 @@ list(APPEND common-deps
${UNWIND_LIBRARY}
${CMAKE_DL_LIBS}
m
crc32c
)

foreach(executable ${test-tools})
Expand Down
Loading

0 comments on commit de6604c

Please sign in to comment.