Example #1
0
void testRemoveNode() {
    printf("Test removing a node...\n");
    hash_ring_t *ring = hash_ring_create(1, HASH_FUNCTION_SHA1);
    hash_ring_node_t *node;
    char *mynode = "mynode";
    char *mynode1 = "mynode1";
    char *mynode2 = "mynode2";
    char *mykey = "mykey";
    
    
    assert(hash_ring_add_node(ring, (uint8_t*)mynode, strlen(mynode)) == HASH_RING_OK);
    assert(hash_ring_add_node(ring, (uint8_t*)mynode1, strlen(mynode2)) == HASH_RING_OK);
    assert(hash_ring_add_node(ring, (uint8_t*)mynode2, strlen(mynode2)) == HASH_RING_OK);
    assert(ring->numNodes == 3);
    
    node = hash_ring_find_node(ring, (uint8_t*)mykey, strlen(mykey));
    assert(node != NULL && node->nameLen == strlen(mynode) && memcmp(mynode, node->name, node->nameLen) == 0);
    
    assert(hash_ring_remove_node(ring, (uint8_t*)mynode, strlen(mynode)) == HASH_RING_OK);
    assert(ring->numNodes == 2);
    
    assert(hash_ring_get_node(ring, (uint8_t*)mynode, strlen(mynode)) == NULL);
    
    // remove node1, and try to search for a key that went to it before, and verify it goes to node2
    assert(hash_ring_remove_node(ring, (uint8_t*)mynode1, strlen(mynode1)) == HASH_RING_OK);
    assert(ring->numNodes == 1);
    
    node = hash_ring_find_node(ring, (uint8_t*)mykey, strlen(mykey));
    assert(node != NULL && node->nameLen == strlen(mynode2) && memcmp(mynode2, node->name, node->nameLen) == 0);
    
    hash_ring_free(ring);
}
Example #2
0
int main (int argc, char *argv [])
{
        zctx_t *ctx = zctx_new ();
	publishers_info *pub_interface = malloc(sizeof(publishers_info));

	pub_interface->publisher_ring = hash_ring_create(REPLICATION_FACTOR, HASH_FUNCTION_SHA1);
	pub_interface->publisher_socks = g_hash_table_new(g_str_hash, g_str_equal);
	pub_interface->publisher_socks_locks = g_hash_table_new(g_str_hash, g_str_equal);

	//self_register(ctx, REGISTER_DISPATCHER_SANITY_CHECK, "");

	void *subscriber = create_socket(ctx, ZMQ_PULL, SOCK_CONNECT, RECEIVE_ADDR);
	void *worker = create_socket(ctx, ZMQ_PUSH, SOCK_BIND, WORKER_SOCKET);
	
	create_parser_threads(THREAD_COUNT, ctx, pub_interface);
	
	zthread_fork(ctx, publisher_updater, pub_interface);
	while(true)
	{
		int size;
		char *string = _recv_buff(subscriber, &size);
		_send_string(worker, string, size);
		//fprintf(stderr, "\n Flush came in");
		free (string);
	}
	zctx_destroy (&ctx);
	hash_ring_free(pub_interface->publisher_ring);
	return 0;
}
Example #3
0
void testKnownSlotsOnRing() {
    printf("Test getting known nodes on ring...\n");
    hash_ring_t *ring = hash_ring_create(8, HASH_FUNCTION_SHA1);
    char *slotA = "slotA";
    char *slotB = "slotB";
    
    char *keyA = "keyA";
    char *keyB = "keyBBBB";
    char *keyC = "keyB_";
    
    hash_ring_node_t *node;
    
    assert(hash_ring_add_node(ring, (uint8_t*)slotA, strlen(slotA)) == HASH_RING_OK);
    assert(hash_ring_add_node(ring, (uint8_t*)slotB, strlen(slotB)) == HASH_RING_OK);
    
    node = hash_ring_find_node(ring, (uint8_t*)keyA, strlen(keyA));
    assert(node != NULL && node->nameLen == strlen(slotA) && memcmp(node->name, slotA, strlen(slotA)) == 0);
    
    node = hash_ring_find_node(ring, (uint8_t*)keyB, strlen(keyB));
    assert(node != NULL && node->nameLen == strlen(slotA) && memcmp(node->name, slotA, strlen(slotA)) == 0);
    
    node = hash_ring_find_node(ring, (uint8_t*)keyC, strlen(keyC));
    assert(node != NULL && node->nameLen == strlen(slotB) && memcmp(node->name, slotB, strlen(slotB)) == 0);

    hash_ring_free(ring);
}
Example #4
0
void testLibmemcachedCompat() {
    printf("Testing libmemcached compatibility mode..\n");

    // make sure the mode can't be set to libmemcached if the function is not md5
    hash_ring_t *ring = hash_ring_create(1, HASH_FUNCTION_SHA1);
    assert(hash_ring_set_mode(ring, HASH_RING_MODE_LIBMEMCACHED_COMPAT) == HASH_RING_ERR);
    hash_ring_free(ring);

    ring = hash_ring_create(1, HASH_FUNCTION_MD5);
    assert(hash_ring_set_mode(ring, HASH_RING_MODE_LIBMEMCACHED_COMPAT) == HASH_RING_OK);

    /**
     * TODO - Add tests to make sure libmemcached compat hashes correctly.
     */

    hash_ring_free(ring);
}
Example #5
0
void testEmptyRingSearchReturnsNull() {
    printf("Test empty ring search returns null node...\n");
    hash_ring_t *ring = hash_ring_create(8, HASH_FUNCTION_SHA1);
    char *key = "key";
    assert(hash_ring_find_node(ring, (uint8_t*)key, strlen(key)) == NULL);
    
    hash_ring_free(ring);
}
Example #6
0
void testEmptyRingItemSearchReturnsNull() {
    printf("Test empty ring search returns null item...\n");
    hash_ring_t *ring = hash_ring_create(8, HASH_FUNCTION_SHA1);
    
    assert(hash_ring_find_next_highest_item(ring, 0) == NULL);
    
    hash_ring_free(ring);
}
Example #7
0
void testAddMultipleTimes() {
    printf("Test adding a node multiple times...\n");
    hash_ring_t *ring = hash_ring_create(1, HASH_FUNCTION_SHA1);
    assert(ring != NULL);
    char *mynode = "mynode";
    hash_ring_add_node(ring, (uint8_t*)mynode, strlen(mynode));

    assert(ring->numNodes == 1);
    
    assert(hash_ring_add_node(ring, (uint8_t*)mynode, strlen(mynode)) == HASH_RING_ERR);
    assert(ring->numNodes == 1);
    
    hash_ring_free(ring);
}
Example #8
0
void testRingSorting(int num) {
    printf("Test that the ring is sorted [%d item(s)]...\n", num);
    hash_ring_t *ring = hash_ring_create(num, HASH_FUNCTION_SHA1);
    char *slotA = "slotA";
    
    assert(hash_ring_add_node(ring, (uint8_t*)slotA, strlen(slotA)) == HASH_RING_OK);
    int x;
    uint64_t cur = 0;
    for(x = 0; x < ring->numItems; x++) {
        assert(ring->items[x]->number > cur);
        cur = ring->items[x]->number;
    }
    
    hash_ring_free(ring);
}
Example #9
0
static void hash_ring_drv_stop(ErlDrvData handle)
{
    hash_ring_data *d = (hash_ring_data*)handle;
    
    int x;
    for(x = 0; x < d->numRings; x++) {
        if(d->ring_usage[x] == 1) {
            hash_ring_free(d->rings[x]);
        }
    }
    
    driver_free(d->rings);
    driver_free(d->ring_usage);

    driver_free((char*)handle);
}
Example #10
0
void runBench(HASH_FUNCTION hash_fn, int numReplicas, int numNodes, int numKeys, int keySize) {
    char *hash = NULL;
    if(hash_fn == HASH_FUNCTION_MD5) hash = "MD5";
    else if(hash_fn == HASH_FUNCTION_SHA1) hash = "SHA1";
    
    printf("----------------------------------------------------\n");
    printf("bench (%s): replicas = %d, nodes = %d, keys: %d, ring size: %d\n", hash, numReplicas, numNodes, numKeys, numReplicas * numNodes);
    printf("----------------------------------------------------\n");
    hash_ring_t *ring = hash_ring_create(numReplicas, hash_fn);
    
    addNodes(ring, numNodes);
    
    uint8_t *keys = (uint8_t*)malloc(keySize * numKeys);
    generateKeys(keys, numKeys, keySize);
    
    printf("running...\r");
    
    uint64_t min = 0;
    uint64_t max = 0;
    uint64_t total = 0;
    int times = 100;
    
    int x, y;
    for(y = 0; y < times; y++) {
        startTiming();
        for(x = 0; x < numKeys; x++) {
            assert(hash_ring_find_node(ring, keys + (keySize * x), keySize) != NULL);
        }
        uint64_t result = endTiming();
        if(result > max) max = result;
        if(min == 0 || result < min) min = result;
        total += result;
    }
    
    printf("stats: total = %.5fs, avg/lookup: %.5fus, min: %.5fus, max: %.5fus, ops/sec: %.0f\n", 
        (double)total / 1000000000,
        (((double)(total / numKeys)) / 1000) / times,
        (double)min / numKeys / 1000,
        (double)max / numKeys / 1000,
        1000000000 / ((double)(total / (numKeys * times))));
    
    free(keys);
    hash_ring_free(ring);
}
Example #11
0
void testKnownNextHighestItemOnRing() {
    printf("Test getting next highest item on ring...\n");
    hash_ring_t *ring = hash_ring_create(8, HASH_FUNCTION_SHA1);
    char *slotA = "slotA";
    char *slotB = "slotB";
    
    assert(hash_ring_add_node(ring, (uint8_t*)slotA, strlen(slotA)) == HASH_RING_OK);
    assert(hash_ring_add_node(ring, (uint8_t*)slotB, strlen(slotB)) == HASH_RING_OK);
    
    // next highest for first item should yield the second
    assert(hash_ring_find_next_highest_item(ring, 2351641940735260693u)->number == 2584980261350711786u);
    
    // number less than the first should yield the first
    assert(hash_ring_find_next_highest_item(ring, 2351641940735260692u)->number == 2351641940735260693u);
    
    // number in the middle should yield the next
    assert(hash_ring_find_next_highest_item(ring, 5908063426886290069u)->number == 6065789416862870789u);
    
    // number equal to the last should wrap around to the first
    assert(hash_ring_find_next_highest_item(ring, 17675051572751928939u)->number == 2351641940735260693u);
    
    hash_ring_free(ring);
}
Example #12
0
static void hash_ring_drv_output(ErlDrvData handle, char *buff, ErlDrvSizeT bufflen)
{
    hash_ring_data* d = (hash_ring_data*)handle;
    char res = RETURN_ERR;
    
    // Check the command
    if(bufflen == 6 && buff[0] == COMMAND_CREATE_RING) {
        uint32_t numReplicas;
        memcpy(&numReplicas, &buff[1], 4);
        numReplicas = ntohl(numReplicas);

        int index = find_open_ring_space(d);
        if(index != -1) {
            d->ring_usage[index] = 1;
            
            d->rings[index] = hash_ring_create(numReplicas, buff[5]);
            
            index = htonl(index);
            driver_output(d->port, (char*)&index, 4);
            return;
        }
    }
    else if(bufflen == 5 && buff[0] == COMMAND_DELETE_RING) {
        uint32_t index;
        memcpy(&index, &buff[1], 4);
        index = ntohl(index);

        if(d->numRings > index) {
            if(d->ring_usage[index] == 1) {
                d->ring_usage[index] = 0;
                hash_ring_free(d->rings[index]);
                res = RETURN_OK;
            }
        }
    }
    else if(bufflen >= 9 && buff[0] == COMMAND_ADD_NODE) {
        uint32_t index = readUint32((unsigned char*)&buff[1]);
        uint32_t nodeLen = readUint32((unsigned char*)&buff[5]);
        if((bufflen - 9) == nodeLen && d->numRings > index && d->ring_usage[index] == 1) {
            hash_ring_add_node(d->rings[index], (unsigned char*)&buff[9], nodeLen);
            res = RETURN_OK;
        }
    }
    else if(bufflen >= 9 && buff[0] == COMMAND_REMOVE_NODE) {
        uint32_t index = readUint32((unsigned char*)&buff[1]);
        uint32_t nodeLen = readUint32((unsigned char*)&buff[5]);
        if((bufflen - 9) == nodeLen && d->numRings > index && d->ring_usage[index] == 1) {
            hash_ring_remove_node(d->rings[index], (unsigned char*)&buff[9], nodeLen);
            res = RETURN_OK;
        }
    }
    else if(bufflen >= 9 && buff[0] == COMMAND_FIND_NODE) {
        uint32_t index = readUint32((unsigned char*)&buff[1]);
        uint32_t keyLen = readUint32((unsigned char*)&buff[5]);
        if((bufflen - 9) == keyLen && d->numRings > index && d->ring_usage[index] == 1) {
            hash_ring_node_t *node = hash_ring_find_node(d->rings[index], (unsigned char*)&buff[9], keyLen);
            if(node != NULL) {
                driver_output(d->port, (char*)node->name, node->nameLen);
                return;
            }
        }
    }
    else if(bufflen == 6 && buff[0] == COMMAND_SET_MODE) {
        uint32_t index = readUint32((unsigned char*)&buff[1]);
        uint8_t mode = (uint8_t)buff[5];
        if(d->numRings > index && d->ring_usage[index] == 1) {
            if(hash_ring_set_mode(d->rings[index], mode) == HASH_RING_OK) {
               res = RETURN_OK;
            }
        }
    }
    
    // default return
    driver_output(d->port, &res, 1);
}
Example #13
0
void testKnownMultipleSlotsOnRing() {
    printf("\n\nTest getting multiple known nodes on ring...\n\n");

    hash_ring_t *ring = hash_ring_create(8, HASH_FUNCTION_SHA1);
    char *slotA = "slotA";
    char *slotB = "slotB";
    char *slotC = "slotC";

    // hashes to a low number
    char *keyA = "keyA";
    // hashes to high number
    char *keyB = "keyB*_*_*_";

    int x;
    hash_ring_node_t *nodes[3];

    assert(hash_ring_add_node(ring, (uint8_t*)slotA, strlen(slotA)) == HASH_RING_OK);
    assert(hash_ring_add_node(ring, (uint8_t*)slotB, strlen(slotB)) == HASH_RING_OK);

    x = hash_ring_find_nodes(ring, (uint8_t*)keyA, strlen(keyA), nodes, 3);
    assert(
        x == 2 &&
        nodes[0] != NULL &&
            nodes[0]->nameLen == strlen(slotA) &&
            memcmp(nodes[0]->name, slotA, strlen(slotA)) == 0 &&
        nodes[1] != NULL &&
            nodes[1]->nameLen == strlen(slotB) &&
            memcmp(nodes[1]->name, slotB, strlen(slotB)) == 0);

    x = hash_ring_find_nodes(ring, (uint8_t*)keyB, strlen(keyB), nodes, 3);
    assert(
        x == 2 &&
        nodes[0] != NULL &&
            nodes[0]->nameLen == strlen(slotB) &&
            memcmp(nodes[0]->name, slotB, strlen(slotB)) == 0 &&
        nodes[1] != NULL &&
            nodes[1]->nameLen == strlen(slotA) &&
            memcmp(nodes[1]->name, slotA, strlen(slotA)) == 0);

    assert(hash_ring_add_node(ring, (uint8_t*)slotC, strlen(slotC)) == HASH_RING_OK);

    x = hash_ring_find_nodes(ring, (uint8_t*)keyA, strlen(keyA), nodes, 3);
    assert(
        x == 3 &&
        nodes[0] != NULL &&
            nodes[0]->nameLen == strlen(slotC) &&
            memcmp(nodes[0]->name, slotC, strlen(slotC)) == 0 &&
        nodes[1] != NULL &&
            nodes[1]->nameLen == strlen(slotA) &&
            memcmp(nodes[1]->name, slotA, strlen(slotA)) == 0 &&
        nodes[2] != NULL &&
            nodes[2]->nameLen == strlen(slotB) &&
            memcmp(nodes[2]->name, slotB, strlen(slotB)) == 0);

    x = hash_ring_find_nodes(ring, (uint8_t*)keyB, strlen(keyB), nodes, 3);
    assert(
        x == 3 &&
        nodes[0] != NULL &&
            nodes[0]->nameLen == strlen(slotC) &&
            memcmp(nodes[0]->name, slotC, strlen(slotC)) == 0 &&
        nodes[1] != NULL &&
            nodes[1]->nameLen == strlen(slotB) &&
            memcmp(nodes[1]->name, slotB, strlen(slotB)) == 0 &&
        nodes[2] != NULL &&
            nodes[2]->nameLen == strlen(slotA) &&
            memcmp(nodes[2]->name, slotA, strlen(slotA)) == 0);

    hash_ring_free(ring);
}