Ejemplo n.º 1
0
uint32_t
server_pool_idx(struct server_pool *pool, uint8_t *key, uint32_t keylen)
{
    uint32_t hash, idx;

    ASSERT(array_n(&pool->server) != 0);
    ASSERT(key != NULL);

    /*
     * If hash_tag: is configured for this server pool, we use the part of
     * the key within the hash tag as an input to the distributor. Otherwise
     * we use the full key
     */
    if (!string_empty(&pool->hash_tag)) {
        struct string *tag = &pool->hash_tag;
        uint8_t *tag_start, *tag_end;

        tag_start = nc_strchr(key, key + keylen, tag->data[0]);
        if (tag_start != NULL) {
            tag_end = nc_strchr(tag_start + 1, key + keylen, tag->data[1]);
            if ((tag_end != NULL) && (tag_end - tag_start > 1)) {
                key = tag_start + 1;
                keylen = (uint32_t)(tag_end - key);
            }
        }
    }

    switch (pool->dist_type) {
    case DIST_KETAMA:
        hash = server_pool_hash(pool, key, keylen);
        idx = ketama_dispatch(pool->continuum, pool->ncontinuum, hash);
        break;

    case DIST_MODULA:
        hash = server_pool_hash(pool, key, keylen);
        idx = modula_dispatch(pool->continuum, pool->ncontinuum, hash);
        break;

    case DIST_RANDOM:
        idx = random_dispatch(pool->continuum, pool->ncontinuum, 0);
        break;

    default:
        NOT_REACHED();
        return 0;
    }
    ASSERT(idx < array_n(&pool->server));
    return idx;
}
Ejemplo n.º 2
0
static struct server *
server_pool_server(struct server_pool *pool, uint8_t *key, uint32_t keylen)
{
    struct server *server;
    uint32_t hash, idx;

    ASSERT(array_n(&pool->server) != 0);
    ASSERT(key != NULL && keylen != 0);

    switch (pool->dist_type) {
    case DIST_KETAMA:
        hash = server_pool_hash(pool, key, keylen);
        idx = ketama_dispatch(pool->continuum, pool->ncontinuum, hash);
        break;

    case DIST_MODULA:
        hash = server_pool_hash(pool, key, keylen);
        idx = modula_dispatch(pool->continuum, pool->ncontinuum, hash);
        break;

    case DIST_RANDOM:
        idx = random_dispatch(pool->continuum, pool->ncontinuum, 0);
        break;

    default:
        NOT_REACHED();
        return NULL;
    }
    ASSERT(idx < array_n(&pool->server));

    server = array_get(&pool->server, idx);

    log_debug(LOG_VERB, "key '%.*s' on dist %d maps to server '%.*s'", keylen,
              key, pool->dist_type, server->pname.len, server->pname.data);

    return server;
}
Ejemplo n.º 3
0
static struct server *
dnode_peer_pool_server(struct server_pool *pool, struct rack *rack, uint8_t *key, uint32_t keylen)
{
	struct server *server;
	uint32_t hash, idx;
	struct dyn_token *token = NULL;

	ASSERT(array_n(&pool->peers) != 0);

	//ASSERT(rack != NULL);

	switch (pool->dist_type) {
	case DIST_KETAMA:
		token = dnode_peer_pool_hash(pool, key, keylen);
		hash = token->mag[0];
		idx = ketama_dispatch(rack->continuum, rack->ncontinuum, hash);
		break;

	case DIST_VNODE:
		if (keylen == 0) {
			idx = 0; //for no argument command
			break;
		}
		token = dnode_peer_pool_hash(pool, key, keylen);
		//print_dyn_token(token, 1);
		idx = vnode_dispatch(rack->continuum, rack->ncontinuum, token);
		//loga("found idx %d for rack '%.*s' ", idx, rack->name->len, rack->name->data);
		break;

	case DIST_MODULA:
		token = dnode_peer_pool_hash(pool, key, keylen);
		hash = token->mag[0];
		idx = modula_dispatch(rack->continuum, rack->ncontinuum, hash);
		break;

	case DIST_RANDOM:
		idx = random_dispatch(rack->continuum, rack->ncontinuum, 0);
		break;

	case DIST_SINGLE:
		idx = 0;
		break;

	default:
		NOT_REACHED();
		return NULL;
	}

	//TODOs: should reuse the token
	if (token != NULL) {
		deinit_dyn_token(token);
		dn_free(token);
	}
	ASSERT(idx < array_n(&pool->peers));

	server = array_get(&pool->peers, idx);

	log_debug(LOG_VERB, "dyn: key '%.*s' on dist %d maps to server '%.*s'", keylen,
			key, pool->dist_type, server->pname.len, server->pname.data);

	return server;
}