Algorithm-BinarySearch-Vec

 view release on metacpan or  search on metacpan

Vec.xs  view on Meta::CPAN

 k = SvPV(vkeys,klen);
 ilo = items > 3 ? SvUV(ST(3)) : 0;
 ihi = items > 4 ? SvUV(ST(4)) : (vlen*8/nbits);
 n   = klen*8/nbits;
 RETVAL = newSVpv("",0);
 SvGROW(RETVAL, n*4);		//-- always use 32-bit keys
 SvCUR_set(RETVAL, n*4);
 rv = SvPV_nolen(RETVAL);
 for (i=0; i<n; ++i) {
   ABSV_UINT key   = absv_vget(k,i,nbits);
   ABSV_UINT found = absv_bsearch_ub(v,key,ilo,ihi,nbits);
   absv_vset(rv,i,32,found);
 }
OUTPUT:
 RETVAL

##=====================================================================
## SET OPERATIONS

##--------------------------------------------------------------
SV*
vunion(SV *avec, SV *bvec, ABSV_UINT nbits)
PREINIT:
  const uchar *a, *b;
  uchar *c;
  STRLEN alen,blen;
  ABSV_UINT na,nb,nc, ai,bi,ci, aval,bval;
CODE:
 if (nbits < 8)
   croak("vunion(): cannot handle nbits < 8, but you requested " ABSV_PRI, nbits);
 a = SvPV(avec,alen);
 b = SvPV(bvec,blen);
 na = alen*8/nbits;
 nb = blen*8/nbits;
 nc = na + nb;
 RETVAL = newSVpv("",0);
 SvGROW(RETVAL, nc*nbits/8);
 c = SvPV_nolen(RETVAL);
 for (ai=0,bi=0,ci=0; ai < na && bi < nb; ++ci) {
   aval = absv_vget(a,ai,nbits);
   bval = absv_vget(b,bi,nbits);
   if (aval <= bval) {
     absv_vset(c,ci,nbits,aval);
     ++ai;
     if (aval == bval) ++bi;
   } else { //-- aval > bval
     absv_vset(c,ci,nbits,bval);
     ++bi;
   }
 }
 for (; ai < na; ++ai, ++ci)
   absv_vset(c,ci,nbits,absv_vget(a,ai,nbits));
 for (; bi < nb; ++bi, ++ci)
   absv_vset(c,ci,nbits,absv_vget(b,bi,nbits));
 SvCUR_set(RETVAL, ci*nbits/8);
OUTPUT:
 RETVAL

##--------------------------------------------------------------
SV*
vintersect(SV *avec, SV *bvec, ABSV_UINT nbits)
PREINIT:
  const uchar *a, *b;
  uchar *c;
  STRLEN alen,blen;
  ABSV_UINT na,nb,nc, ai,blo,bi,ci, aval,bval;
CODE:
 if (nbits < 8)
   croak("vintersect(): cannot handle nbits < 8, but you requested " ABSV_PRI, nbits);
 a = SvPV(avec,alen);
 b = SvPV(bvec,blen);
 if (blen < alen) {
   //-- ensure smaller set is "a"
   const uchar *tmp = b;
   STRLEN tmplen = blen;
   b = a;
   a = tmp;
   blen = alen;
   alen = tmplen;
 }
 na = alen*8/nbits;
 nb = blen*8/nbits;
 nc = na;
 RETVAL = newSVpv("",0);
 SvGROW(RETVAL, nc*nbits/8);
 c = SvPV_nolen(RETVAL);
 for (ai=0,blo=0,ci=0; ai < na; ++ai) {
   aval = absv_vget(a,ai,nbits);
   bi   = absv_bsearch_ub(b,aval,blo,nb,nbits);
   if (bi   == KEY_NOT_FOUND) break;
   if (aval == absv_vget(b,bi,nbits)) {
     absv_vset(c,ci++,nbits,aval);
   }
   blo = bi;
 }
 SvCUR_set(RETVAL, ci*nbits/8);
OUTPUT:
 RETVAL

##--------------------------------------------------------------
SV*
vsetdiff(SV *avec, SV *bvec, ABSV_UINT nbits)
PREINIT:
  const uchar *a, *b;
  uchar *c;
  STRLEN alen,blen;
  ABSV_UINT na,nb,nc, ai,blo,bi,ci, aval,bval;
CODE:
 if (nbits < 8)
   croak("vsetdiff(): cannot handle nbits < 8, but you requested " ABSV_PRI, nbits);
 a = SvPV(avec,alen);
 b = SvPV(bvec,blen);
 na = alen*8/nbits;
 nb = blen*8/nbits;
 nc = na;
 RETVAL = newSVpv("",0);
 SvGROW(RETVAL, nc*nbits/8);
 c = SvPV_nolen(RETVAL);
 for (ai=0,blo=0,ci=0; ai < na; ++ai) {
   aval = absv_vget(a,ai,nbits);
   bi   = absv_bsearch_ub(b,aval,blo,nb,nbits);
   if (bi   == KEY_NOT_FOUND) break;
   if (aval != absv_vget(b,bi,nbits)) {
     absv_vset(c,ci++,nbits,aval);
   }
   blo = bi;
 }
 for ( ; ai < na; ++ai)
   absv_vset(c,ci++,nbits,absv_vget(a,ai,nbits));



( run in 0.547 second using v1.01-cache-2.11-cpan-39bf76dae61 )