Algorithm-ConsistentHash-Ketama

 view release on metacpan or  search on metacpan

xs/Ketama.xs  view on Meta::CPAN


    return ketama->hashfunc(ketama, ptr, len, &hash);
}


#define PerlKetama_xs_create PerlKetama_create

static PerlKetama *
PerlKetama_clone(PerlKetama * const ketama)
{
    PerlKetama_Bucket * const buckets = ketama->buckets;
    PerlKetama_Continuum_Point * const continuum = ketama->continuum;
    unsigned int i, j;
    PerlKetama *newketama = PerlKetama_create(NULL, 1);

    newketama->hashfunc = ketama->hashfunc;
    newketama->totalweight = ketama->totalweight;

    if (ketama->numpoints <= 0) {
        newketama->continuum = NULL;
        newketama->numpoints = 0;
    } else {
        Newxz(newketama->continuum, ketama->numpoints, PerlKetama_Continuum_Point);
        for (i = 0; i < ketama->numpoints; i++) {
            StructCopy(&(continuum[i]), &(newketama->continuum[i]), PerlKetama_Continuum_Point);
        }
        newketama->numpoints = ketama->numpoints;
    }

    if (ketama->numbuckets <= 0) {
        newketama->buckets = NULL;
        newketama->numbuckets = 0;
    } else {
        Newxz(newketama->buckets, ketama->numbuckets, PerlKetama_Bucket);
        for (i = 0; i < ketama->numbuckets; i++ ) {
            StructCopy(&(buckets[i]), &(newketama->buckets[i]), PerlKetama_Bucket);
            Newxz(newketama->buckets[i].label, strlen(buckets[i].label) + 1, char);
            Copy(buckets[i].label, newketama->buckets[i].label, strlen(buckets[i].label) + 1, char);
            if ( ketama->numpoints > 0) {
                int found = 0;
                for (j = 0; j < ketama->numpoints; j++) {
                    if ( strEQ( buckets[i].label, continuum[j].bucket->label ) ) {
                        newketama->continuum[j].bucket = newketama->buckets + i;
                        found = 1;
                        j = ketama->numpoints;
                    }
                }
                if (! found) {
                    croak("SANITY CHECK FAILED: Should not get here");
                }
            }
        }
        newketama->numbuckets = ketama->numbuckets;
    }
    return newketama;
}

static int
PerlKetama_mg_dup(pTHX_ MAGIC* const mg, CLONE_PARAMS* const param){
    PERL_UNUSED_VAR(param);
#ifdef USE_ITHREADS /* single threaded perl has no "xxx_dup()" APIs */
    PerlKetama* const ketama = (PerlKetama*)mg->mg_ptr;
    mg->mg_ptr = (char *) PerlKetama_clone(ketama);
#else
    PERL_UNUSED_VAR(mg);
#endif
    return 0;
}

static MGVTBL PerlKetama_vtbl = { /* for identity */
    NULL, /* get */
    NULL, /* set */
    NULL, /* len */
    NULL, /* clear */
    PerlKetama_mg_free, /* free */
    NULL, /* copy */
    PerlKetama_mg_dup, /* dup */
    NULL,  /* local */
};

MODULE = Algorithm::ConsistentHash::Ketama   PACKAGE = Algorithm::ConsistentHash::Ketama  PREFIX=PerlKetama_

PROTOTYPES: DISABLE

PerlKetama *
PerlKetama_xs_create(class_sv, hashfunc)
        SV *class_sv;
        int hashfunc;

void
PerlKetama_add_bucket(ketama, label, weight)
        PerlKetama *ketama;
        char *label;
        int weight;

void
PerlKetama_remove_bucket(ketama, label)
        PerlKetama *ketama;
        char *label;

void
PerlKetama_buckets(ketama)
        PerlKetama *ketama;
    PPCODE:
        /* since PerlKetama_buckets may push an unknown number of items
           into the Perl stash, this is required */
        XSRETURN( PerlKetama_buckets(ketama) );

char *
PerlKetama_hash(ketama, thing)
        PerlKetama* ketama;
        SV *thing;

void
PerlKetama_hash_with_hashnum(ketama, thing)
        PerlKetama* ketama;
        SV *thing;
    PREINIT:
        unsigned int hash;
        char *ptr;
        STRLEN len;



( run in 0.730 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )