Attean

 view release on metacpan or  search on metacpan

lib/AtteanX/Store/Memory.pm  view on Meta::CPAN

=head1 DESCRIPTION

AtteanX::Store::Memory provides an in-memory quad-store.

=cut

use v5.14;
use warnings;

package AtteanX::Store::Memory 0.038 {
use Moo;
use Type::Tiny::Role;
use Types::Standard qw(Int ArrayRef HashRef ConsumerOf InstanceOf);
use Encode;
use Set::Scalar;
use Digest::SHA;
use Data::Dumper;
use List::Util qw(first);
use Scalar::Util qw(refaddr reftype blessed);
use Math::Cartesian::Product;
use namespace::clean;

with 'Attean::API::RDFStarStore';
with 'Attean::API::MutableQuadStore';
with 'Attean::API::QuadStore';
with 'Attean::API::ETagCacheableQuadStore';
with 'Attean::API::TimeCacheableQuadStore';
with 'Attean::API::CostPlanner';

my @pos_names	= Attean::API::Quad->variables;

=head1 ATTRIBUTES

=over 4

=item C<< subject >>

=item C<< predicate >>

=item C<< object >>

=item C<< graph >>

=back

=head1 METHODS

Beyond the methods documented below, this class inherits methods from the
L<Attean::API::QuadStore> class.

=over 4

=item C<< new () >>

Returns a new memory-backed storage object.

=cut

has _size => (is => 'rw', isa => Int, init_arg => undef, default => 0);
has statements => (is => 'rw', isa => ArrayRef[ConsumerOf['Attean::API::Quad']], init_arg => undef, default => sub { [] });
has subject => (is => 'ro', isa => HashRef[InstanceOf['Set::Scalar']], init_arg => undef, default => sub { +{} });
has predicate => (is => 'ro', isa => HashRef[InstanceOf['Set::Scalar']], init_arg => undef, default => sub { +{} });
has object => (is => 'ro', isa => HashRef[InstanceOf['Set::Scalar']], init_arg => undef, default => sub { +{} });
has graph => (is => 'ro', isa => HashRef[InstanceOf['Set::Scalar']], init_arg => undef, default => sub { +{} });
has graph_nodes	=> (is => 'rw', isa => HashRef[ConsumerOf['Attean::API::IRI']], init_arg => undef, default => sub { +{} });
has hash		=> (is => 'rw', isa => InstanceOf['Digest::SHA'], default => sub { Digest::SHA->new });
has mtime		=> (is => 'rw', isa => Int, default => sub { return time() });

=item C<< size >>

Returns the number of quads in the store.

=cut

sub size {
	shift->_size()
}

=item C<< get_quads ( $subject, $predicate, $object, $graph ) >>

Returns a stream object of all statements matching the specified subject,
predicate and objects. Any of the arguments may be undef to match any value.

=cut

sub get_quads {
	my $self	= shift;
	my @nodes	= map { ref($_) eq 'ARRAY' ? $_ : [$_] } @_;
	my @iters;
	cartesian { push(@iters, $self->_get_quads(@_)) } @nodes;
	return Attean::IteratorSequence->new( iterators => \@iters, item_type => 'Attean::API::Quad' );
}

sub _get_quads {
	my $self		= shift;
	my @nodes		= @_;
	my @pos_names	= Attean::QuadPattern->variables;
	
	my %pattern_bound;
	foreach my $pos (0 .. 3) {
		my $n	= $nodes[ $pos ];
		$pattern_bound{ $pos_names[$pos] }	= $n;
	}
	
	# create a quadpattern that includes any embedded triple patterns (RDF-star)
	my $pattern	= Attean::QuadPattern->new(%pattern_bound);

	my %bound;
	my $bound	= 0;
	my %embedded_triple_vars;
	my $seen_embedded_triple	= 0;
	foreach my $pos (0 .. 3) {
		my $n	= $nodes[ $pos ];
		if (blessed($n) and $n->does('Attean::API::TriplePattern')) {
			# replace embedded triple patterns with variables.
			# the quads that match with the new variables will be filtered
			# in post-processing below to ensure that they also match the
			# embedded triple patterns.
			$seen_embedded_triple	= 1;
			my $v	= Attean::Variable->new();
			$embedded_triple_vars{$v->value}	= $n;
			$nodes[$pos]	= $v;
			$n				= $v;
		}



( run in 0.981 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )