uint32_t vb__hash_ketama(const char *key, size_t key_length) { unsigned char digest[16]; vb__hash_md5(key, key_length, digest); return (uint32_t) ( (digest[3] << 24) |(digest[2] << 16) |(digest[1] << 8) | digest[0]); }
static int update_ketama(lcbvb_CONFIG *cfg) { char host[MAX_AUTHORITY_SIZE+10] = ""; int nhost; unsigned pp, hh, ss, nn; unsigned char digest[16]; lcbvb_CONTINUUM *new_continuum, *old_continuum; qsort(cfg->servers, cfg->ndatasrv, sizeof(*cfg->servers), server_cmp); new_continuum = calloc(160 * cfg->ndatasrv, sizeof(*new_continuum)); /* 40 hashes, 4 numbers per hash = 160 points per server */ for (ss = 0, pp = 0; ss < cfg->ndatasrv; ++ss) { /* we can add more points to server which have more memory */ for (hh = 0; hh < 40; ++hh) { lcbvb_SERVER *srv = cfg->servers + ss; nhost = snprintf(host, MAX_AUTHORITY_SIZE+10, "%s-%u", srv->authority, hh); vb__hash_md5(host, nhost, digest); for (nn = 0; nn < 4; ++nn, ++pp) { new_continuum[pp].index = ss; new_continuum[pp].point = ((uint32_t) (digest[3 + nn * 4] & 0xFF) << 24) | ((uint32_t) (digest[2 + nn * 4] & 0xFF) << 16) | ((uint32_t) (digest[1 + nn * 4] & 0xFF) << 8) | (digest[0 + nn * 4] & 0xFF); } } } qsort(new_continuum, pp, sizeof *new_continuum, continuum_item_cmp); old_continuum = cfg->continuum; cfg->continuum = new_continuum; cfg->ncontinuum = pp; free(old_continuum); return 1; }