File Coverage

blib/lib/RDF/Core/Storage/Memory.pm
Criterion Covered Total %
statement 6 108 5.5
branch 0 50 0.0
condition 0 89 0.0
subroutine 2 11 18.1
pod 6 6 100.0
total 14 264 5.3


line stmt bran cond sub pod time code
1             #
2             # The contents of this file are subject to the Mozilla Public
3             # License Version 1.1 (the "License"); you may not use this file
4             # except in compliance with the License. You may obtain a copy of
5             # the License at http://www.mozilla.org/MPL/
6             #
7             # Software distributed under the License is distributed on an "AS
8             # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9             # implied. See the License for the specific language governing
10             # rights and limitations under the License.
11             #
12             # The Original Code is the RDF::Core module
13             #
14             # The Initial Developer of the Original Code is Ginger Alliance Ltd.
15             # Portions created by Ginger Alliance are
16             # Copyright (C) 2001 Ginger Alliance Ltd.
17             # All Rights Reserved.
18             #
19             # Contributor(s):
20             #
21             # Alternatively, the contents of this file may be used under the
22             # terms of the GNU General Public License Version 2 or later (the
23             # "GPL"), in which case the provisions of the GPL are applicable
24             # instead of those above. If you wish to allow use of your
25             # version of this file only under the terms of the GPL and not to
26             # allow others to use your version of this file under the MPL,
27             # indicate your decision by deleting the provisions above and
28             # replace them with the notice and other provisions required by
29             # the GPL. If you do not delete the provisions above, a recipient
30             # may use your version of this file under either the MPL or the
31             # GPL.
32             #
33              
34             package RDF::Core::Storage::Memory;
35              
36 1     1   618 use strict;
  1         3  
  1         46  
37             require Exporter;
38              
39             our @ISA = qw(RDF::Core::Storage);
40              
41 1     1   4 use Carp;
  1         3  
  1         15621  
42             require RDF::Core::Storage;
43             require RDF::Core::Enumerator::Memory;
44             sub new {
45 0     0 1   my ($pkg) = @_;
46 0   0       $pkg = ref $pkg || $pkg;
47 0           my $self = {};
48             #data
49 0           $self->{_data} = {};
50             #indexes - each element keeps an array of its statements
51 0           $self->{_subjects} = {};
52 0           $self->{_objects} = {};
53 0           $self->{_predicates} = {};
54 0           bless $self, $pkg;
55             }
56             sub addStmt {
57 0     0 1   my ($self, $stmt) = @_;
58 0 0         return 0 if $self->existsStmt($stmt->getSubject,$stmt->getPredicate,$stmt->getObject);
59 0           my $clone = $stmt->clone;
60 0           my $index = $self->_getCounter('statement');
61              
62 0 0         $self->{_subjects}->{$stmt->getSubject->getURI}=[]
63             unless (exists $self->{_subjects}->{$stmt->getSubject->getURI});
64 0           push(@{$self->{_subjects}->{$stmt->getSubject->getURI}},$index);
  0            
65 0 0         $self->{_predicates}->{$stmt->getPredicate->getURI}=[]
66             unless (exists $self->{_predicates}->{$stmt->getPredicate->getURI});
67 0           push(@{$self->{_predicates}->{$stmt->getPredicate->getURI}},$index);
  0            
68 0 0         $self->{_objects}->{$stmt->getObject->getLabel}=[]
69             unless (exists $self->{_objects}->{$stmt->getObject->getLabel});
70 0           push(@{$self->{_objects}->{$stmt->getObject->getLabel}},$index);
  0            
71              
72 0           $self->{_data}->{$index} = $clone;
73 0           return 1;
74             }
75             sub removeStmt {
76 0     0 1   my ($self, $stmt) = @_;
77             return unless
78 0 0         my $key = $self->_getKey($stmt);
79 0           my $index;
80             #remove from subjects index
81 0           my $label = $stmt->getSubject->getLabel;
82 0           my $lastIndex = @{$self->{_subjects}->{$label}} - 1;
  0            
83 0           for (my $i = 0;$i <= $lastIndex; $i++) {
84 0 0         if ($key eq $self->{_subjects}->{$label}->[$i]) {
85 0           $index = $i;
86 0           last;
87             }
88             }
89 0 0         $self->{_subjects}->{$label}->[$index] = $self->{_subjects}->{$label}->[$lastIndex]
90             unless $index == $lastIndex;
91 0           delete $self->{_subjects}->{$label}->[$lastIndex];
92 0 0         delete $self->{_subjects}->{$label}
93             if $lastIndex == 0;
94              
95             #remove from predicates index
96 0           $label = $stmt->getPredicate->getLabel;
97 0           $lastIndex = @{$self->{_predicates}->{$label}} - 1;
  0            
98 0           for (my $i = 0;$i <= $lastIndex;$i++) {
99 0 0         if ($key eq $self->{_predicates}->{$label}->[$i]) {
100 0           $index = $i;
101 0           last;
102             }
103             }
104 0 0         $self->{_predicates}->{$label}->[$index] = $self->{_predicates}->{$label}->[$lastIndex]
105             unless $index == $lastIndex;
106 0           delete $self->{_predicates}->{$label}->[$lastIndex];
107 0 0         delete $self->{_predicates}->{$label}
108             if $lastIndex == 0;
109              
110             #remove from objects index
111 0           $label = $stmt->getObject->getLabel;
112 0           $lastIndex = @{$self->{_objects}->{$label}} - 1;
  0            
113 0           for (my $i = 0;$i <= $lastIndex;$i++) {
114 0 0         if ($key eq $self->{_objects}->{$label}->[$i]) {
115 0           $index = $i;
116 0           last;
117             }
118             }
119 0 0         $self->{_objects}->{$label}->[$index] = $self->{_objects}->{$label}->[$lastIndex]
120             unless $index == $lastIndex;
121 0           delete $self->{_objects}->{$label}->[$lastIndex];
122 0 0         delete $self->{_objects}->{$label}
123             if $lastIndex == 0;
124              
125 0           delete $self->{_data}->{$key};
126              
127             }
128             sub existsStmt {
129 0     0 1   my ($self, $subject, $predicate, $object) = @_;
130              
131 0           my $indexArray = $self->_getIndexArray($subject, $predicate, $object);
132 0           foreach (@$indexArray) {
133 0 0 0       if ((!defined $subject || $self->{_data}->{$_}->getSubject->getURI eq $subject->getURI) &&
      0        
      0        
      0        
      0        
134             (!defined $predicate || $self->{_data}->{$_}->getPredicate->getURI eq $predicate->getURI) &&
135             (!defined $object || (
136             $self->{_data}->{$_}->getObject->isLiteral
137             ? ($object->equals($self->{_data}->{$_}->getObject))
138             : $self->{_data}->{$_}->getObject->getLabel eq $object->getLabel
139             ))) {
140 0           return 1; #found statement
141             }
142             }
143 0           return 0; #didn't find statement
144             }
145             sub getStmts {
146 0     0 1   my ($self, $subject, $predicate, $object) = @_;
147 0           my @data ;
148              
149 0           my @indexArray = @{$self->_getIndexArray($subject, $predicate, $object)};
  0            
150 0           foreach (@indexArray) {
151 0 0 0       if ((!defined $subject || $self->{_data}->{$_}->getSubject->getURI eq $subject->getURI) &&
      0        
      0        
      0        
      0        
152             (!defined $predicate || $self->{_data}->{$_}->getPredicate->getURI eq $predicate->getURI) &&
153             (!defined $object || (
154             $self->{_data}->{$_}->getObject->isLiteral
155             ? ($object->equals($self->{_data}->{$_}->getObject))
156             : $self->{_data}->{$_}->getObject->getLabel eq $object->getLabel
157             ))) {
158 0           push(@data,$self->{_data}->{$_});
159             }
160             }
161 0           return RDF::Core::Enumerator::Memory->new(\@data) ;
162              
163             }
164             sub countStmts {
165 0     0 1   my ($self, $subject, $predicate, $object) = @_;
166              
167 0           my $count = 0;
168 0 0 0       return $count = keys %{$self->{_data}}
  0   0        
169             unless defined $subject || defined $predicate || defined $object;
170 0           my @indexArray = @{$self->_getIndexArray($subject, $predicate, $object)};
  0            
171 0           foreach (@indexArray) {
172 0 0 0       if ((!defined $subject || $self->{_data}->{$_}->getSubject->getURI eq $subject->getURI) &&
      0        
      0        
      0        
      0        
173             (!defined $predicate || $self->{_data}->{$_}->getPredicate->getURI eq $predicate->getURI) &&
174             (!defined $object || (
175             $self->{_data}->{$_}->getObject->isLiteral
176             ? ($object->equals($self->{_data}->{$_}->getObject))
177             : $self->{_data}->{$_}->getObject->getLabel eq $object->getLabel
178             ))) {
179 0           $count++;
180             }
181             }
182 0           return $count;
183              
184             }
185             sub _getCounter {
186 0     0     my ($self,$counterName) = @_;
187 0   0       return $self->{'_'.$counterName} = ++$self->{'_'.$counterName} || 1;
188             }
189             sub _getKey {
190             #Same as existsStmt, but returns key of statement and doesn't handle undef elements (takes $stmt as a parameter)
191 0     0     my ($self, $stmt) = @_;
192              
193 0           my @indexArray = @{$self->_getIndexArray($stmt->getSubject, $stmt->getPredicate, $stmt->getObject)};
  0            
194 0           foreach (@indexArray) {
195 0 0 0       if ($self->{_data}->{$_}->getSubject->getURI eq $stmt->getSubject->getURI &&
    0 0        
196             $self->{_data}->{$_}->getPredicate->getURI eq $stmt->getPredicate->getURI &&
197             ($self->{_data}->{$_}->getObject->isLiteral
198             ? ($stmt->getObject->equals($self->{_data}->{$_}->getObject))
199             : $self->{_data}->{$_}->getObject->getLabel eq $stmt->getObject->getLabel)) {
200 0           return $_; #found statement
201             }
202             }
203 0           return 0; #didn't find statement
204             }
205             sub _getIndexArray {
206             #find the smallest index to search statement
207 0     0     my ($self, $subject, $predicate, $object) = @_;
208 0           my $indexArray;
209 0           my $found = 0;
210              
211 0 0 0       return [] #if didn't find the subject|predicate|object
      0        
      0        
      0        
      0        
212             unless ((!defined $subject || exists $self->{_subjects}->{$subject->getURI})&&
213             (!defined $predicate || exists $self->{_predicates}->{$predicate->getURI}) &&
214             (!defined $object || exists $self->{_objects}->{$object->getLabel}));
215              
216              
217 0 0         $indexArray = $self->{_subjects}->{$subject->getURI}
218             if defined $subject;
219             $indexArray = $self->{_predicates}->{$predicate->getURI}
220 0 0 0       if defined $predicate && (!defined $indexArray || @$indexArray gt @{$self->{_predicates}->{$predicate->getURI}});
      0        
221             $indexArray = $self->{_objects}->{$object->getLabel}
222 0 0 0       if defined $object && (!defined $indexArray || @$indexArray gt @{$self->{_objects}->{$object->getLabel}});
      0        
223 0 0         if (!defined $indexArray) {
224 0           my @allData = keys %{$self->{_data}};
  0            
225 0           $indexArray = \@allData; #\@{keys %{$self->{_data}}};
226             }
227 0           return $indexArray;
228             }
229             1;
230             __END__