Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Pål-Erik Martinsen <palmarti@cisco.com>
Joe Hildeabrand <jhildebr@cisco.com>
Peng Fan <fanpeng@chinamobile.com>
10 changes: 10 additions & 0 deletions include/tube.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ typedef struct _tube_manager tube_manager;

typedef struct _tube tube;

//id and remote peer addr used to distinguish tubes
typedef struct _tuple
{
uint64_t id;
struct sockaddr peer;
} tuple;

typedef ssize_t (*tube_sendmsg_func)(int socket,
const struct msghdr *message,
int flags);
Expand Down Expand Up @@ -102,3 +109,6 @@ LS_API void tube_get_id(tube *t, spud_tube_id *id);

LS_API void tube_set_socket_functions(tube_sendmsg_func send,
tube_recvmsg_func recv);

unsigned int tube_hash_tuple(const void *t);
int tube_compare_tuple(const void *key1, const void *key2);
37 changes: 34 additions & 3 deletions src/tube.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ LS_API void tube_get_id(tube *t, spud_tube_id *id)
{
spud_copy_id(&t->id, id);
}

/*
static unsigned int hash_id(const void *id) {
// treat the 8 bytes of tube ID like a long long.
uint64_t key = *(uint64_t *)id;
Expand All @@ -295,8 +295,25 @@ static unsigned int hash_id(const void *id) {
key = key + (key << 6);
key = key ^ (key >> 22);
return (unsigned int) key;
}
}*/

unsigned int tube_hash_tuple(const void *t) {
// currently only id and remote sockaddr are taken into consideration
const tuple *tup = t;
const struct sockaddr_in6 * p_in6 = (const struct sockaddr_in6 *) &tup->peer;
uint64_t key = (uint64_t)tup->id + (uint64_t)(*(uint64_t *)p_in6);

// from
// https://gist.github.com/badboy/6267743#64-bit-to-32-bit-hash-functions
key = (~key) + (key << 18);
key = key ^ (key >> 31);
key = key * 21;
key = key ^ (key >> 11);
key = key + (key << 6);
key = key ^ (key >> 22);
return (unsigned int) key;
}
/*
static int compare_id(const void *key1, const void *key2) {
int ret = 0;
uint64_t k1 = *(uint64_t *)key1;
Expand All @@ -307,6 +324,20 @@ static int compare_id(const void *key1, const void *key2) {
ret = (k1==k2) ? 0 : 1;
}
return ret;
}*/

int tube_compare_tuple(const void *key1, const void *key2) {
//compares two tuple key1 and key2, returns 0 if they are the same and 1 if not.
tuple k1 = *(tuple *)key1;
tuple k2 = *(tuple *)key2;

if (k1.id == k2.id) {
if (k1.peer.sa_family == k2.peer.sa_family && strcmp(k1.peer.sa_data, k2.peer.sa_data) == 0) {
return 0;
}
}

return 1;
}

LS_API bool tube_manager_create(int buckets,
Expand All @@ -327,7 +358,7 @@ LS_API bool tube_manager_create(int buckets,
if (buckets <= 0) {
buckets = DEFAULT_HASH_SIZE;
}
if (!ls_htable_create(buckets, hash_id, compare_id, &ret->tubes, err)) {
if (!ls_htable_create(buckets, tube_hash_tuple, tube_compare_tuple, &ret->tubes, err)) {
goto cleanup;
}

Expand Down
28 changes: 28 additions & 0 deletions test/tube_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ uint8_t spud[] = { 0xd8, 0x00, 0x00, 0xd8,
0x41, 0x61 };
bool first = true;

//manmade different ID/peer tuples used to test tubemanager hash function
tuple t1 = {
0x01020304FAFBFCFD,
{
AF_INET,
{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}
}
};
tuple t2 = {
0x01020304FAFBFCFD,
{
AF_INET,
{0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D}
}
};

static ssize_t _mock_sendmsg(int socket,
const struct msghdr *hdr,
int flags)
Expand Down Expand Up @@ -276,6 +292,16 @@ START_TEST (tube_manager_loop_test)
}
END_TEST


START_TEST (tube_manager_hash_test)
{
unsigned int key1 = tube_hash_tuple(&t1);
unsigned int key2 = tube_hash_tuple(&t2);
ck_assert_int_ne(key1-key2, 0);
ck_assert_int_ne(tube_compare_tuple(&t1, &t2), 0);
}
END_TEST

Suite * tube_suite (void)
{
Suite *s = suite_create ("tube");
Expand All @@ -291,6 +317,8 @@ Suite * tube_suite (void)
tcase_add_test (tc_tube, tube_data_test);
tcase_add_test (tc_tube, tube_close_test);
tcase_add_test (tc_tube, tube_manager_loop_test);
tcase_add_test (tc_tube, tube_manager_hash_test);


suite_add_tcase (s, tc_tube);
}
Expand Down