Algorithm-ConsistentHash-CHash

 view release on metacpan or  search on metacpan

CHash.xs  view on Meta::CPAN

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"

#include "libchash.h"

MODULE = Algorithm::ConsistentHash::CHash PACKAGE = Algorithm::ConsistentHash::CHash

TYPEMAP: <<HERE
struct chash_t *	O_OBJECT

OUTPUT

O_OBJECT
  sv_setref_pv( $arg, CLASS, (void*)$var );

INPUT

O_OBJECT
  if ( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) )
    $var = INT2PTR($type, SvIV((SV*)SvRV( $arg )));
  else
    croak( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );
HERE


### new({ids => [key1, key2, key3], replicas => 123})

struct chash_t *
new(CLASS, ...)
    char *CLASS
  PREINIT:
    HV *params;
    I32 i;
    SV **svp;
    AV *ids;
    size_t replicas;
    const char **keys;
    size_t *lens;
    size_t nkeys;
    SV *keys_guard;
    SV *lens_guard;
  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;



( run in 0.818 second using v1.01-cache-2.11-cpan-7fcb06a456a )