Data-Log-Shared

 view release on metacpan or  search on metacpan

Shared.xs  view on Meta::CPAN

    char errbuf[LOG_ERR_BUFLEN];
  CODE:
    /* Capture the name PV only after all INPUT conversions (incl. the
     * SvUV get-magic for data_size) have run: that magic could realloc
     * or free name's PV if it were captured by the typemap first. */
    const char *nm = (SvGETMAGIC(name), SvOK(name)) ? SvPV_nolen(name) : NULL;
    LogHandle *h = log_create_memfd(nm, data_size, errbuf);
    if (!h) croak("Data::Log::Shared->new_memfd: %s", errbuf);
    MAKE_OBJ(class, h);
  OUTPUT:
    RETVAL

SV *
new_from_fd(class, fd)
    const char *class
    int fd
  PREINIT:
    char errbuf[LOG_ERR_BUFLEN];
  CODE:
    LogHandle *h = log_open_fd(fd, errbuf);
    if (!h) croak("Data::Log::Shared->new_from_fd: %s", errbuf);
    MAKE_OBJ(class, h);
  OUTPUT:
    RETVAL

void
DESTROY(self)
    SV *self
  CODE:
    if (!SvROK(self)) return;
    LogHandle *h = INT2PTR(LogHandle*, SvIV(SvRV(self)));
    if (!h) return;
    sv_setiv(SvRV(self), 0);
    log_destroy(h);

SV *
append(self, data)
    SV *self
    SV *data
  PREINIT:
    EXTRACT_LOG(self);
  CODE:
    STRLEN len;
    const char *buf = SvPV(data, len);        /* get-magic before reading SvUTF8 */
    int utf8 = SvUTF8(data) ? 1 : 0;
    if (len == 0) croak("append: data must not be empty");
    if (len >= 0x80000000u)                   /* bit 31 of the stored len = UTF8 */
        croak("append: data too large (>= 2 GiB)");
    REEXTRACT_LOG(self);
    int64_t off = log_append(h, buf, (uint32_t)len, utf8);
    RETVAL = (off >= 0) ? newSViv((IV)off) : &PL_sv_undef;
  OUTPUT:
    RETVAL

void
read_entry(self, offset, ...)
    SV *self
    UV offset
  PREINIT:
    EXTRACT_LOG(self);
  PPCODE:
    const uint8_t *out_data;
    uint32_t out_len;
    int out_utf8 = 0;
    uint64_t next_off;
    /* Optional third arg: abandon_wait_us (default LOG_ABANDON_WAIT_US).
     * Pass 0 to immediately treat any uncommitted slot as abandoned. */
    uint64_t wait_us = (items > 2 && (SvGETMAGIC(ST(2)), SvOK(ST(2)))) ? (uint64_t)SvUV(ST(2)) : (uint64_t)LOG_ABANDON_WAIT_US;
    REEXTRACT_LOG(self);
    int rc = log_read_ex(h, offset, &out_data, &out_len, &out_utf8, &next_off, wait_us);
    if (rc == LOG_READ_OK) {
        EXTEND(SP, 2);
        SV *dsv = newSVpvn((const char *)out_data, out_len);
        if (out_utf8) SvUTF8_on(dsv);
        PUSHs(sv_2mortal(dsv));
        PUSHs(sv_2mortal(newSVuv((UV)next_off)));
    } else if (rc == LOG_READ_ABANDONED || rc == LOG_READ_TRUNCATED) {
        /* Signal "skip forward" -- data is undef, next_off is set (past an
         * abandoned slot, or to the truncation point). */
        EXTEND(SP, 2);
        PUSHs(sv_newmortal());  /* undef */
        PUSHs(sv_2mortal(newSVuv((UV)next_off)));
    }
    /* LOG_READ_EMPTY: return empty list. */

UV
tail_offset(self)
    SV *self
  PREINIT:
    EXTRACT_LOG(self);
  CODE:
    RETVAL = (UV)log_tail_offset(h);
  OUTPUT:
    RETVAL

UV
entry_count(self)
    SV *self
  PREINIT:
    EXTRACT_LOG(self);
  CODE:
    RETVAL = (UV)log_entry_count(h);
  OUTPUT:
    RETVAL

UV
data_size(self)
    SV *self
  PREINIT:
    EXTRACT_LOG(self);
  CODE:
    RETVAL = (UV)log_data_size(h);
  OUTPUT:
    RETVAL

UV
available(self)
    SV *self
  PREINIT:
    EXTRACT_LOG(self);
  CODE:



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