Apophis

 view release on metacpan or  search on metacpan

lib/Apophis.pm  view on Meta::CPAN


Identifies the content and writes it to the sharded store.  Returns the
UUID.  If the content already exists, returns immediately (CAS dedup).
Writes are atomic via temp file + rename.

=head2 fetch

    my $data_ref = $ca->fetch($id);

Returns a scalar reference to the stored content, or C<undef> if not found.

=head2 exists

    if ($ca->exists($id)) { ... }

Returns true if the content exists in the store.

=head2 remove

    $ca->remove($id);

Removes the content and its metadata sidecar (if any) from the store.

=head2 path_for

    my $path = $ca->path_for($id);

Returns the 2-level sharded filesystem path for the given UUID:

    a3bb189e-8bf9-... → /store/a3/bb/a3bb189e-8bf9-...

=head2 verify

    my $ok = $ca->verify($id);

Re-reads the stored content, re-identifies it, and compares the UUID.
Returns true if the content is intact.

=head2 store_many

    my @ids = $ca->store_many(\@content_refs);

Stores multiple content items.  Returns a list of UUIDs.

=head2 find_missing

    my @missing = $ca->find_missing(\@ids);

Returns the subset of IDs that do not exist in the store.

=head2 namespace

    my $ns = $ca->namespace();

Returns the namespace UUID string.

=head1 C ABI

Apophis publishes its content-addressing primitives as a C function-pointer
table, so another XS module can identify, shard and write a blob without a
Perl frame in between. The header is C<ap_abi.h>, installed through
L<ExtUtils::Depends>, and C<Apophis::_abi_ptr> returns the address of the
process-wide table as a UV.

This is for XS authors. Nothing in it is reachable or useful from Perl, and
the Perl API above remains the supported one.

    use ExtUtils::Depends;
    my $pkg = ExtUtils::Depends->new('My::Module', 'Apophis');

    #include "ap_abi.h"

    /* at boot, once */
    if (call_pv("Apophis::_abi_ptr", G_SCALAR | G_EVAL) > 0) {
        UV p = SvUV(POPs);
        const ap_abi *A = INT2PTR(const ap_abi *, p);
        if (A && A->abi_version >= AP_ABI_VERSION) ...
    }

The table is B<append only>: new members go at the end, C<AP_ABI_VERSION>
bumps, and a consumer requires C<< abi_version >= >> the version it compiled
against - never C<==>, which would make every release of this module a
breaking change for everything that uses it.

C<store_of> unpacks a blessed Apophis object into its namespace bytes and
store directory, and is the only member that touches the object. It never
croaks, so a consumer can probe with it before deciding whether the C path is
available at all. Everything else takes those two values directly, which
means there is still exactly one source of truth for what a store is.

A consumer must not reimplement C<build_path>. The sharded layout is this
module's to change, and a second copy of the rule means the day it changes,
every blob already on disk becomes unreachable through the consumer while
remaining perfectly findable here.

C<ap_abi.h> documents each member; L<Punk::Plugin::Blob> is the reference
consumer.

=head1 DEPENDENCIES

B<Horus> — pure C UUID library (header-only, RFC 9562).

=head1 AUTHOR

LNATION E<lt>email@lnation.orgE<gt>

=head1 LICENSE

This module is free software; you may redistribute and/or modify it under
the same terms as Perl itself.

=cut



( run in 1.346 second using v1.01-cache-2.11-cpan-2e0ccfb7a10 )