Apophis

 view release on metacpan or  search on metacpan

lib/Apophis.xs  view on Meta::CPAN


    if (!SvROK(content_ref_sv))
        croak("Apophis: pp_identify: argument must be a scalar reference");
    content_sv = SvRV(content_ref_sv);
    content = SvPV(content_sv, content_len);

    apophis_identify_content(uuid, ns, content, content_len);

    EXTEND(SP, 1);
    PUSHs(sv_2mortal(apophis_uuid_to_sv(aTHX_ uuid)));
    PUTBACK;
    return NORMAL;
}

/*
 * pp_apophis_store - Custom op: fused identify + mkdir + atomic write
 *
 * Stack input:  self_sv, content_ref_sv
 * Stack output: uuid_string_sv
 *
 * Fuses the entire store pipeline into a single op:

lib/Apophis.xs  view on Meta::CPAN

                       id_str, HORUS_FMT_STR_LEN);

    /* CAS dedup: only write if not already stored */
    if (stat(path, &st) != 0) {
        apophis_ensure_parent_dir(path);
        apophis_atomic_write(aTHX_ path, content, content_len);
    }

    EXTEND(SP, 1);
    PUSHs(sv_2mortal(newSVpvn(id_str, HORUS_FMT_STR_LEN)));
    PUTBACK;
    return NORMAL;
}

/*
 * pp_apophis_exists - Custom op: UUID → boolean existence check
 *
 * Stack input:  self_sv, id_sv
 * Stack output: bool_sv
 *
 * Fuses: path computation + stat() into a single op.

lib/Apophis.xs  view on Meta::CPAN

    hv = (HV *)SvRV(self_sv);

    store_dir = apophis_get_store_dir(aTHX_ hv, NULL, &store_dir_len);
    id_str = SvPV(id_sv, id_len);

    apophis_build_path(path, sizeof(path),
                       store_dir, store_dir_len, id_str, id_len);

    EXTEND(SP, 1);
    PUSHs(stat(path, &st) == 0 ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/*
 * pp_apophis_fetch - Custom op: UUID → content scalar ref or undef
 *
 * Stack input:  self_sv, id_sv
 * Stack output: \$content or undef
 *
 * Fuses: path computation + stat + open + read into a single op.

lib/Apophis.xs  view on Meta::CPAN


        if (nread < 0) {
            SvREFCNT_dec(content);
            croak("Apophis: pp_fetch: read error on '%s'", path);
        }
        SvCUR_set(content, (STRLEN)nread);
        *SvEND(content) = '\0';

        PUSHs(sv_2mortal(newRV_noinc(content)));
    }
    PUTBACK;
    return NORMAL;
}

/*
 * pp_apophis_verify - Custom op: fused re-read + re-hash + compare
 *
 * Stack input:  self_sv, id_sv
 * Stack output: bool_sv
 *
 * Fuses: path computation + open + streaming SHA-1 + format + memcmp.

lib/Apophis.xs  view on Meta::CPAN

        PUSHs(&PL_sv_no);
    } else {
        apophis_identify_stream(aTHX_ uuid, ns, fh);
        PerlIO_close(fh);

        horus_format_uuid(recomputed, uuid, HORUS_FMT_STR);
        PUSHs((id_len == HORUS_FMT_STR_LEN &&
               memcmp(id_str, recomputed, HORUS_FMT_STR_LEN) == 0)
              ? &PL_sv_yes : &PL_sv_no);
    }
    PUTBACK;
    return NORMAL;
}

/*
 * pp_apophis_remove - Custom op: fused path + unlink + meta cleanup
 *
 * Stack input:  self_sv, id_sv
 * Stack output: bool_sv
 *
 * Fuses: path computation + unlink + meta sidecar cleanup.

lib/Apophis.xs  view on Meta::CPAN

                                   id_str, id_len);

    removed = (unlink(path) == 0);

    apophis_build_meta_path(meta_path, sizeof(meta_path),
                            path, path_len);
    unlink(meta_path);  /* ignore error — may not exist */

    EXTEND(SP, 1);
    PUSHs(removed ? &PL_sv_yes : &PL_sv_no);
    PUTBACK;
    return NORMAL;
}

/*
 * apophis_make_custom_op - Create a custom OP node
 *
 * Used by the optimize/import system to inject custom ops into optrees.
 */
static OP *
apophis_make_custom_op(pTHX_ OP *(*pp_func)(pTHX))

lib/Apophis.xs  view on Meta::CPAN

        self = newHV();
        hv_stores(self, "_ns_bytes", newSVpvn((const char *)ns_bytes, 16));
        hv_stores(self, "_ns_str", apophis_uuid_to_sv(aTHX_ ns_bytes));

        if (store_dir)
            hv_stores(self, "store_dir", newSVpvn(store_dir, store_dir_len));

        self_ref = newRV_noinc((SV *)self);
        sv_bless(self_ref, gv_stashpv(class, GV_ADD));
        RETVAL = self_ref;
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# namespace() -> UUID string                                           #
# ------------------------------------------------------------------ #

SV *
namespace(self)
        SV *self
    PREINIT:
        HV *hv;
        SV **svp;
    CODE:
        if (!sv_isobject(self))
            croak("Apophis::namespace: not an object");
        hv = (HV *)SvRV(self);
        svp = hv_fetchs(hv, "_ns_str", 0);
        if (!svp || !SvOK(*svp))
            croak("Apophis: object has no namespace");
        RETVAL = newSVsv(*svp);
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# identify(\$content) -> UUID string                                   #
# ------------------------------------------------------------------ #

SV *
identify(self, content_ref)
        SV *self
        SV *content_ref

lib/Apophis.xs  view on Meta::CPAN

        hv = (HV *)SvRV(self);
        ns = apophis_get_ns(aTHX_ hv);

        if (!SvROK(content_ref))
            croak("Apophis::identify: argument must be a scalar reference");
        content_sv = SvRV(content_ref);
        content = SvPV(content_sv, content_len);

        apophis_identify_content(uuid, ns, content, content_len);
        RETVAL = apophis_uuid_to_sv(aTHX_ uuid);
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# identify_file($path) -> UUID string                                  #
# ------------------------------------------------------------------ #

SV *
identify_file(self, path)
        SV *self
        const char *path

lib/Apophis.xs  view on Meta::CPAN


        fh = PerlIO_open(path, "rb");
        if (!fh)
            croak("Apophis::identify_file: cannot open '%s': %s",
                  path, strerror(errno));

        apophis_identify_stream(aTHX_ uuid, ns, fh);
        PerlIO_close(fh);

        RETVAL = apophis_uuid_to_sv(aTHX_ uuid);
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# path_for($id, %opts) -> path string                                 #
# ------------------------------------------------------------------ #

SV *
path_for(self, id, ...)
        SV *self
        SV *id

lib/Apophis.xs  view on Meta::CPAN

            }
        }

        store_dir = apophis_get_store_dir(aTHX_ hv, opts, &store_dir_len);
        id_str = SvPV(id, id_len);

        path_len = apophis_build_path(path, sizeof(path),
                                       store_dir, store_dir_len,
                                       id_str, id_len);
        RETVAL = newSVpvn(path, path_len);
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# store(\$content, %opts) -> UUID string                               #
# ------------------------------------------------------------------ #

SV *
store(self, content_ref, ...)
        SV *self
        SV *content_ref

lib/Apophis.xs  view on Meta::CPAN


        /* Write metadata sidecar if provided */
        if (meta) {
            char meta_path[APOPHIS_PATH_MAX];
            apophis_build_meta_path(meta_path, sizeof(meta_path),
                                    path, path_len);
            apophis_meta_write(aTHX_ meta_path, meta);
        }

        RETVAL = newSVpvn(id_str, HORUS_FMT_STR_LEN);
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# fetch($id, %opts) -> \$content or undef                             #
# ------------------------------------------------------------------ #

SV *
fetch(self, id, ...)
        SV *self
        SV *id

lib/Apophis.xs  view on Meta::CPAN


            if (nread < 0) {
                SvREFCNT_dec(content);
                croak("Apophis::fetch: read error on '%s'", path);
            }
            SvCUR_set(content, (STRLEN)nread);
            *SvEND(content) = '\0';

            RETVAL = newRV_noinc(content);
        }
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# exists($id, %opts) -> bool                                          #
# ------------------------------------------------------------------ #

bool
exists(self, id, ...)
        SV *self
        SV *id

lib/Apophis.xs  view on Meta::CPAN

                hv_store(opts, k, klen, SvREFCNT_inc(ST(i+1)), 0);
            }
        }

        store_dir = apophis_get_store_dir(aTHX_ hv, opts, &store_dir_len);
        id_str = SvPV(id, id_len);
        apophis_build_path(path, sizeof(path),
                           store_dir, store_dir_len, id_str, id_len);

        RETVAL = (stat(path, &st) == 0) ? TRUE : FALSE;
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# remove($id, %opts) -> bool                                          #
# ------------------------------------------------------------------ #

bool
remove(self, id, ...)
        SV *self
        SV *id

lib/Apophis.xs  view on Meta::CPAN

                                       id_str, id_len);

        removed = (unlink(path) == 0);

        /* Also remove metadata sidecar if it exists */
        apophis_build_meta_path(meta_path, sizeof(meta_path),
                                path, path_len);
        unlink(meta_path);  /* ignore error — may not exist */

        RETVAL = removed ? TRUE : FALSE;
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# verify($id, %opts) -> bool                                          #
# ------------------------------------------------------------------ #

bool
verify(self, id, ...)
        SV *self
        SV *id

lib/Apophis.xs  view on Meta::CPAN

            RETVAL = FALSE;
        } else {
            apophis_identify_stream(aTHX_ uuid, ns, fh);
            PerlIO_close(fh);

            horus_format_uuid(recomputed, uuid, HORUS_FMT_STR);
            RETVAL = (id_len == HORUS_FMT_STR_LEN &&
                      memcmp(id_str, recomputed, HORUS_FMT_STR_LEN) == 0)
                     ? TRUE : FALSE;
        }
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# store_many(\@refs, %opts) -> @ids                                    #
# ------------------------------------------------------------------ #

void
store_many(self, refs, ...)
        SV *self
        SV *refs

lib/Apophis.xs  view on Meta::CPAN

                                       id_str, id_len);
        apophis_build_meta_path(meta_path, sizeof(meta_path),
                                path, path_len);

        meta = apophis_meta_read(aTHX_ meta_path);
        if (meta) {
            RETVAL = newRV_noinc((SV *)meta);
        } else {
            RETVAL = &PL_sv_undef;
        }
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# Custom op direct invocation XSUBs                                    #
#                                                                      #
# These call the pp_ functions directly, giving the same speedup      #
# as injected custom ops but accessible as regular function calls.     #
# ------------------------------------------------------------------ #

# op_identify($self, \$content) -> UUID string

lib/Apophis.xs  view on Meta::CPAN

        hv = (HV *)SvRV(self);
        ns = apophis_get_ns(aTHX_ hv);

        if (!SvROK(content_ref))
            croak("Apophis::op_identify: argument must be a scalar reference");
        content_sv = SvRV(content_ref);
        content = SvPV(content_sv, content_len);

        apophis_identify_content(uuid, ns, content, content_len);
        RETVAL = apophis_uuid_to_sv(aTHX_ uuid);
    OUTPUT:
        RETVAL

# op_store($self, \$content) -> UUID string
# Fused identify + mkdir + atomic write — single call, no intermediates.

SV *
op_store(self, content_ref)
        SV *self
        SV *content_ref
    PREINIT:

lib/Apophis.xs  view on Meta::CPAN

        apophis_build_path(path, sizeof(path),
                           store_dir, store_dir_len,
                           id_str, HORUS_FMT_STR_LEN);

        if (stat(path, &st) != 0) {
            apophis_ensure_parent_dir(path);
            apophis_atomic_write(aTHX_ path, content, content_len);
        }

        RETVAL = newSVpvn(id_str, HORUS_FMT_STR_LEN);
    OUTPUT:
        RETVAL

# op_exists($self, $id) -> bool
# Fused path computation + stat — single call.

bool
op_exists(self, id)
        SV *self
        SV *id
    PREINIT:

lib/Apophis.xs  view on Meta::CPAN

        if (!sv_isobject(self))
            croak("Apophis::op_exists: not an object");
        hv = (HV *)SvRV(self);

        store_dir = apophis_get_store_dir(aTHX_ hv, NULL, &store_dir_len);
        id_str = SvPV(id, id_len);
        apophis_build_path(path, sizeof(path),
                           store_dir, store_dir_len, id_str, id_len);

        RETVAL = (stat(path, &st) == 0) ? TRUE : FALSE;
    OUTPUT:
        RETVAL

# op_fetch($self, $id) -> \$content or undef
# Fused path computation + stat + read — single call.

SV *
op_fetch(self, id)
        SV *self
        SV *id
    PREINIT:

lib/Apophis.xs  view on Meta::CPAN


            if (nread < 0) {
                SvREFCNT_dec(content);
                croak("Apophis::op_fetch: read error on '%s'", path);
            }
            SvCUR_set(content, (STRLEN)nread);
            *SvEND(content) = '\0';

            RETVAL = newRV_noinc(content);
        }
    OUTPUT:
        RETVAL

# op_verify($self, $id) -> bool
# Fused read + streaming SHA-1 + compare — single call.

bool
op_verify(self, id)
        SV *self
        SV *id
    PREINIT:

lib/Apophis.xs  view on Meta::CPAN

            RETVAL = FALSE;
        } else {
            apophis_identify_stream(aTHX_ uuid, ns, fh);
            PerlIO_close(fh);

            horus_format_uuid(recomputed, uuid, HORUS_FMT_STR);
            RETVAL = (id_len == HORUS_FMT_STR_LEN &&
                      memcmp(id_str, recomputed, HORUS_FMT_STR_LEN) == 0)
                     ? TRUE : FALSE;
        }
    OUTPUT:
        RETVAL

# op_remove($self, $id) -> bool
# Fused path + unlink + meta cleanup — single call.

bool
op_remove(self, id)
        SV *self
        SV *id
    PREINIT:

lib/Apophis.xs  view on Meta::CPAN

                                       store_dir, store_dir_len,
                                       id_str, id_len);

        removed = (unlink(path) == 0);

        apophis_build_meta_path(meta_path, sizeof(meta_path),
                                path, path_len);
        unlink(meta_path);  /* ignore error — may not exist */

        RETVAL = removed ? TRUE : FALSE;
    OUTPUT:
        RETVAL

# ------------------------------------------------------------------ #
# Custom op introspection and testing                                  #
# ------------------------------------------------------------------ #

# _make_op($type) -> confirmation string
# Creates a custom OP node and returns its pp_addr name for testing.

SV *

lib/Apophis.xs  view on Meta::CPAN

            OP *op = apophis_make_custom_op(aTHX_ pp_apophis_verify);
            RETVAL = newSVpvf("CUSTOM_OP@apophis_verify[%p]", (void *)op->op_ppaddr);
            FreeOp(op);
        } else if (strEQ(type, "remove")) {
            OP *op = apophis_make_custom_op(aTHX_ pp_apophis_remove);
            RETVAL = newSVpvf("CUSTOM_OP@apophis_remove[%p]", (void *)op->op_ppaddr);
            FreeOp(op);
        } else {
            croak("Apophis::_make_op: unknown type '%s'", type);
        }
    OUTPUT:
        RETVAL

ppport.h  view on Meta::CPAN

PUSH_MULTICALL_FLAGS|5.018000||Viu
PUSHn|5.006000|5.003007|
PUSHp|5.003007|5.003007|
PUSHs|5.003007|5.003007|
push_scope|5.003007|5.003007|u
PUSHSTACK|5.005000||Viu
PUSHSTACKi|5.005000||Viu
PUSHSTACK_INIT_HWM|5.027002||Viu
PUSHTARG|5.003007||Viu
PUSHu|5.004000|5.003007|p
PUTBACK|5.003007|5.003007|
putc|5.003007||Viu
put_charclass_bitmap_innards|5.021004||Viu
put_charclass_bitmap_innards_common|5.023008||Viu
put_charclass_bitmap_innards_invlist|5.023008||Viu
put_code_point|5.021004||Viu
putc_unlocked|5.003007||Viu
putenv|5.005000||Viu
put_range|5.019009||Viu
putw|5.003007||Viu
pv_display|5.006000|5.003007|p

ppport.h  view on Meta::CPAN

{
    dSP;
    SV* sv = newSVpv(p, 0);

    PUSHMARK(sp);
    eval_sv(sv, G_SCALAR);
    SvREFCNT_dec(sv);

    SPAGAIN;
    sv = POPs;
    PUTBACK;

    D_PPP_CROAK_IF_ERROR(croak_on_error);

    return sv;
}

#endif
#endif

#if ! defined(vload_module) && defined(start_subparse)



( run in 0.922 second using v1.01-cache-2.11-cpan-13bb782fe5a )