Algorithm-ConsistentHash-CHash
view release on metacpan or search on metacpan
CODE:
if ( (items-1) % 2 )
croak("Even number of parameters expected!");
params = (HV *)sv_2mortal( (SV*)newHV() );
for (i = 1; i < items; i += 2) {
SV *keyname = ST(i);
SV *value = ST(i+1);
SvREFCNT_inc(value); /* hv_store_ent acquires a refcount ownership */
hv_store_ent(params, keyname, value, 0);
}
/* Find the ids part */
svp = hv_fetchs(params, "ids", 0);
if (!svp || !SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVAV)
croak("Expected an 'ids' parameter that is an array reference");
ids = (AV *)SvRV(*svp);
/* Now find replicas */
svp = hv_fetchs(params, "replicas", 0);
if (!svp)
croak("Expected an 'replicas' parameter");
replicas = SvIV(*svp);
if (replicas == 0)
croak("Cannot work with zero replicas!");
nkeys = av_len(ids)+1;
/* Allocate memory in an exception-safe manner */
keys_guard = sv_2mortal( newSV( nkeys * sizeof(char *) ) );
keys = (const char **)SvPVX(keys_guard);
lens_guard = sv_2mortal( newSV( nkeys * sizeof(size_t) ) );
lens = (size_t *)SvPVX(lens_guard);
for (i = 0; i < nkeys; ++i) {
char *k;
STRLEN len;
svp = av_fetch(ids, i, 0);
if (svp == NULL) {
/* this is wrong */
len = 0;
k = NULL;
}
else {
k = SvPVbyte(*svp, len); /* FIXME is this correct for UTF8? */
}
keys[i] = k;
lens[i] = len;
/* fprintf(stderr, "node => '%s', len => %u\n", k, len); */
}
/* fprintf(stderr, "nkeys => %u, replicas => %u\n", nkeys, replicas); */
RETVAL = chash_create(keys, lens, nkeys, replicas);
if (RETVAL == NULL)
croak("Unknown error");
OUTPUT: RETVAL
void
DESTROY(self)
struct chash_t *self
CODE:
chash_free(self);
SV *
lookup(self, key)
struct chash_t *self
SV *key;
PREINIT:
const char *out_str;
size_t out_str_len;
const char *key_str;
STRLEN key_len;
CODE:
key_str = SvPVbyte(key, key_len);
chash_lookup(self, key_str, key_len, &out_str, &out_str_len);
RETVAL = newSVpvn(out_str, out_str_len);
OUTPUT: RETVAL
( run in 0.346 second using v1.01-cache-2.11-cpan-119454b85a5 )