DBIx-SpatialKey

 view release on metacpan or  search on metacpan

SpatialKey.xs  view on Meta::CPAN

DESTROY(obj)
	SV *	obj
        CODE:
        keydef *kd = (keydef*)SvIV(SvRV(obj));
        Safefree (kd->mask);
        Safefree (kd->shift);
        Safefree (kd->dim);
        Safefree (kd);

SV *
index(obj,...)
	SV *	obj
        CODE:
        keydef *kd = (keydef*)SvIV(SvRV(obj));
        U32 *val;
        U32 mask;
        u8 *out;
        u8 out_mask;
        UI i;
        if (items-1 != kd->dims)
	  croak ("expected %d values, not %d", kd->dims, items-1);

        RETVAL = neuSV (kd->len);

        out = SvPV (RETVAL, PL_na);
        out_mask = 0; out--;

        mask = kd->maxmask;
        New (0, val, kd->dims, U32);

        for (i = 1; i < items; i++)
          val[i-1] = (SvIV(ST(i))) << kd->shift[i-1];

        do
          {
            for (i = 0; i < kd->dims; i++)
              if (kd->mask[i] & mask)
                {
                  if (!out_mask)
                    {
                      out++;
                      out_mask = 128;
                    }
                  if (val[i] & mask)
                    *out |= out_mask;
                  out_mask >>= 1;
                }

            mask >>= 1;
          }
        while (mask);

        Safefree (val);
	OUTPUT:
        RETVAL

void
unpack(obj,key)
	SV *	obj
        SV *	key
        PPCODE:
        keydef *kd = (keydef*)SvIV(SvRV(obj));
        U32 *val;
        U32 mask;
        u8 *out;
        u8 out_mask;
        UI i;

        out = SvPV (key, PL_na);
        out_mask = 0; out--;

        mask = kd->maxmask;
        Newz (0, val, kd->dims, U32);

        do
          {
            for (i = 0; i < kd->dims; i++)
              if (kd->mask[i] & mask)
                {
                  if (!out_mask)
                    {
                      out++;
                      out_mask = 128;
                    }
                  if (*out & out_mask)
                    val[i] |= mask;
                  out_mask >>= 1;
                }

            mask >>= 1;
          }
        while (mask);

        EXTEND(SP,kd->dims);
        for (i = 0; i < kd->dims; i++)
          PUSHs (sv_2mortal (newSViv (val[i] >> kd->shift[i])));

        Safefree (val);

void
ranges(obj,...)
	SV *	obj
        PPCODE:
        keydef *kd = (keydef*)SvIV(SvRV(obj));
#if 1
        croak ("ranges not supported in this version");
#else
        U32 *min, *max;
        U32 mask;
        I32 out;
        u8 out_mask;
        AV *av = newAV ();
        UI i;
        if (items-1 != 2*kd->dims)
	  croak ("expected %d values, not %d", 2*kd->dims, items-1);

        New (0, min, kd->dims, U32);
        New (0, max, kd->dims, U32);

        for (i = 0; i < kd->dims; i++)
          {
            min[i] = SvIV(ST(i*2+1));
            max[i] = SvIV(ST(i*2+2));
          }

        av_push (av, neuSV (kd->len));
        av_push (av, neuSV (kd->len));

        out = -1;
        out_mask = 0;

        mask = kd->maxmask << 1;

        //gen_indices (kd, min, max, av, 0, kd->dims, mask, out, out_mask);

        Safefree (min);
        Safefree (max);

        for (i = 0; i <= av_len (av); i++)
          PUSHs (sv_2mortal (SvREFCNT_inc (*av_fetch (av, i, 0))));
        
        av_undef (av);
#endif
        



( run in 0.685 second using v1.01-cache-2.11-cpan-5511b514fd6 )