AtteanX-Store-LMDB

 view release on metacpan or  search on metacpan

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

=cut

use v5.14;
use warnings;

package AtteanX::Store::LMDB {
our $VERSION	= '0.001';
use Moo;
use Type::Tiny::Role;
use Types::Standard qw(Bool Str InstanceOf HashRef);
use LMDB_File qw(:flags :cursor_op);
use Digest::SHA qw(sha256 sha256_hex);
use Scalar::Util qw(refaddr reftype blessed);
use Math::Cartesian::Product;
use List::Util qw(any all first);
use File::Path qw(make_path);
use DateTime::Format::W3CDTF;
use Devel::Peek;
use Encode qw(encode_utf8 decode_utf8);
use namespace::clean;

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

		my ($key, $value)	= @_;
		my @order	= unpack('Q>4', $value);
		$self->indexes->{$key}	= \@order;
	});
}

sub iterate_database {
	my $self	= shift;
	my $db		= shift;
	my $handler	= shift;
	my $cursor	= $db->Cursor;
	eval {
		local($LMDB_File::die_on_err)	= 0;
		my ($key, $value);
		unless ($cursor->get($key, $value, MDB_FIRST)) {
			while (1) {
				$handler->($key, $value);
				last if $cursor->get($key, $value, MDB_NEXT);
			}
		}
	};
}

sub iterate_database_range {
	my $self	= shift;
	my $db		= shift;
	my $from	= shift;
	my $to		= shift;
	my $handler	= shift;
	my $cursor	= $db->Cursor;
	eval {
		local($LMDB_File::die_on_err)	= 0;
		my $key	= $from;
		my $value;
		unless ($cursor->get($key, $value, MDB_SET_RANGE)) {
			while (1) {
				use bytes;
				my $c = $key cmp $to;
				last if ($c >= 0);
				$handler->($key, $value);
				last if $cursor->get($key, $value, MDB_NEXT);
			}
		}
	};
}

=item C<< size >>

Returns the number of quads in the store.

=cut

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


		my $qid			= pack('Q>', $qid_value);
		my $qids		= pack('Q>4', @ids);
		my $gid			= pack('Q>', $ids[3]);

		my $graphs_dbi	= $txn->open('graphs');
		my $quads_dbi	= $txn->open('quads');
		my $stats_dbi	= $txn->open('stats');
		$txn->put($quads_dbi, $qid, $qids);

		my $graphs_cursor = $graphs->Cursor;
		my $key	= $gid;
		my $empty	= '';
		eval {
			local($LMDB_File::die_on_err)	= 0;
			if (my $err = $graphs_cursor->get($key, $empty, MDB_SET_RANGE)) {
				$graphs_cursor->put($gid, $empty);
			} else {
				if ($key ne $gid) {
					$graphs_cursor->put($gid, $empty);
				}
			}
		};

		$self->_add_quad_to_indexes($qid, \@ids, $txn);
		$txn->put($stats_dbi, $next_quad, pack('Q>', $next));
		$txn->commit();
	}
	
	sub add_quad_with_txn {

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

		my $graphs	= $txn->OpenDB({ dbname => 'graphs', });

		my @remove_ids		= map { $self->_get_term_id($_, $t2i) } $st->values;
		unless (scalar(@remove_ids) == 4) {
			return;
		}
		unless (all { defined($_) } @remove_ids) {
			return;
		}

		my $cursor	= $quads->Cursor;
		my ($key, $value);
		eval {
			local($LMDB_File::die_on_err)	= 0;
			unless ($cursor->get($key, $value, MDB_FIRST)) {
				QUAD: while (1) {
					my $qid		= unpack('Q>', $key);
					my (@ids)	= unpack('Q>4', $value);
					if ($ids[0] == $remove_ids[0] and $ids[1] == $remove_ids[1] and $ids[2] == $remove_ids[2] and $ids[3] == $remove_ids[3]) {
						my $g		= $ids[3];
						$self->_remove_quad_to_indexes($qid, \@ids, $txn);
						$cursor->del();
						
						unless ($self->_graph_id_exists_with_txn($txn, $quads, $t2i, $g)) {
							# no more quads with this graph, so delete it from the graphs table
							my $graphs_cursor = $graphs->Cursor;
							my $gid = pack('Q>', $g);
							my $key	= $gid;
							my $empty	= '';
							unless ($graphs_cursor->get($key, $empty, MDB_SET_RANGE)) {
								if ($gid eq $key) {
									$graphs_cursor->del();
								}
							}
						}

						$txn->commit();
						return;
					}
				} continue {
					last if $cursor->get($key, $value, MDB_NEXT);
				}
			}
		};
	}

=item C<< create_graph( $graph ) >>

This is a no-op function for the memory quad-store.

=cut

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

				$graphs{$g}		= pack('Q>', $g);

				$txn->put($quads_dbi, $qid, $qids);
				$self->_add_quad_to_indexes($qid, \@ids, $txn);
			} else {
				$self->add_quad($q);
			}
		}
		if ($BULK_LOAD) {
			my $empty	= '';
			my $graphs_cursor = $graphs_dbi->Cursor;
			foreach my $gid (values %graphs) {
				my $key	= $gid;
				eval {
					local($LMDB_File::die_on_err)	= 0;
					if (my $err = $graphs_cursor->get($key, $empty, MDB_SET_RANGE)) {
						$graphs_cursor->put($gid, $empty);
					} else {
						if ($key ne $gid) {
							$graphs_cursor->put($gid, $empty);
						}
					}
				};
			}
			$txn->put($stats_dbi, $next_quad, pack('Q>', $next));
			$txn->commit();
		}
	}

	sub _quad_exists_with_txn {



( run in 0.352 second using v1.01-cache-2.11-cpan-fd5d4e115d8 )