Data-IntervalTree-Shared

 view release on metacpan or  search on metacpan

Shared.xs  view on Meta::CPAN

  CODE:
    ItHandle *h = it_open_fd(fd, errbuf);
    if (!h) croak("Data::IntervalTree::Shared->new_from_fd: %s", errbuf);
    class = SvPV_nolen(ST(0));   /* re-read after argument magic; see new() */
    MAKE_OBJ(class, h);
  OUTPUT:
    RETVAL

void
DESTROY(self)
    SV *self
  CODE:
    if (sv_isobject(self) && sv_derived_from(self, "Data::IntervalTree::Shared")) {
        ItHandle *h = INT2PTR(ItHandle*, SvIV(SvRV(self)));
        if (h) { sv_setiv(SvRV(self), 0); it_destroy(h); }   /* null first: activates EXTRACT's use-after-destroy croak + makes a double DESTROY a no-op */
    }

UV
add(self, lo, hi, id = &PL_sv_undef)
    SV *self
    IV lo
    IV hi
    SV *id
  PREINIT:
    EXTRACT(self);
    int64_t slot;
    uint64_t payload;
  CODE:
    if (lo > hi) croak("Data::IntervalTree::Shared->add: lo (%" IVdf ") > hi (%" IVdf ")", (IV)lo, (IV)hi);
    /* resolve the id BEFORE locking: SvUV on a tied/overloaded SV can run Perl
     * code that dies, and a longjmp past the wrlock would strand it on a live PID. */
    int have_id = (SvGETMAGIC(id), SvOK(id));
    uint64_t id_val = have_id ? (uint64_t)SvUV(id) : 0;
    REEXTRACT(self);
    it_rwlock_wrlock(h);
    payload = have_id ? id_val : h->hdr->count;   /* default id = insertion index */
    slot = it_add_locked(h, (int64_t)lo, (int64_t)hi, payload);
    __atomic_fetch_add(&h->hdr->stat_ops, 1, __ATOMIC_RELAXED);
    it_rwlock_wrunlock(h);
    if (slot < 0) croak("Data::IntervalTree::Shared->add: tree is full (capacity %u)", (unsigned)h->capacity);
    RETVAL = (UV)slot;
  OUTPUT:
    RETVAL

void
build(self)
    SV *self
  PREINIT:
    EXTRACT(self);
  CODE:
    it_rwlock_wrlock(h);
    if (h->hdr->dirty) it_build_locked(h);
    it_rwlock_wrunlock(h);

void
stab(self, point)
    SV *self
    IV point
  PREINIT:
    EXTRACT(self);
  PPCODE:
    {
        ItRes *res = NULL;
        uint64_t got = 0, cap = h->capacity;
        if (cap) { Newx(res, (size_t)cap, ItRes); SAVEFREEPV(res); }   /* alloc BEFORE the lock */
        {
            int wr = it_query_lock(h);
            got = cap ? it_overlaps_locked(h, (int64_t)point, (int64_t)point, res, cap) : 0;
            it_query_unlock(h, wr);
        }
        PUSH_RESULTS(res, got);
    }

void
overlaps(self, lo, hi)
    SV *self
    IV lo
    IV hi
  PREINIT:
    EXTRACT(self);
  PPCODE:
    {
        ItRes *res = NULL;
        uint64_t got = 0, cap = h->capacity;
        if (lo > hi) croak("Data::IntervalTree::Shared->overlaps: lo (%" IVdf ") > hi (%" IVdf ")", (IV)lo, (IV)hi);
        if (cap) { Newx(res, (size_t)cap, ItRes); SAVEFREEPV(res); }   /* alloc BEFORE the lock */
        {
            int wr = it_query_lock(h);
            got = cap ? it_overlaps_locked(h, (int64_t)lo, (int64_t)hi, res, cap) : 0;
            it_query_unlock(h, wr);
        }
        PUSH_RESULTS(res, got);
    }

void
clear(self)
    SV *self
  PREINIT:
    EXTRACT(self);
  CODE:
    it_rwlock_wrlock(h);
    it_clear_locked(h);
    __atomic_fetch_add(&h->hdr->stat_ops, 1, __ATOMIC_RELAXED);
    it_rwlock_wrunlock(h);

UV
count(self)
    SV *self
  PREINIT:
    EXTRACT(self);
    UV n;
  CODE:
    it_rwlock_rdlock(h);
    n = (UV)h->hdr->count;
    it_rwlock_rdunlock(h);
    RETVAL = n;
  OUTPUT:
    RETVAL

UV
capacity(self)
    SV *self
  PREINIT:
    EXTRACT(self);
  CODE:
    RETVAL = (UV)h->hdr->capacity;
  OUTPUT:
    RETVAL

SV *
stats(self)
    SV *self
  PREINIT:
    EXTRACT(self);
  CODE:
    {
        uint64_t count, ops;
        uint32_t cap, dirty;
        it_rwlock_rdlock(h);
        count = h->hdr->count;
        cap   = h->hdr->capacity;



( run in 1.281 second using v1.01-cache-2.11-cpan-92ad3014f07 )