Skip to content

Commit 978870c

Browse files
committed
Now that RDF::HamsterRepo has been extracted into the rdf-hamster-repo gem, replace the builtin implementation for RDF::Repository with that used in RDF::OrderedRepo.
1 parent acce579 commit 978870c

File tree

3 files changed

+14
-103
lines changed

3 files changed

+14
-103
lines changed

lib/rdf/repository.rb

Lines changed: 14 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,16 @@ def begin_transaction(mutable: false, graph_name: nil)
243243
#
244244
# @see RDF::Repository
245245
module Implementation
246-
require 'hamster'
247246
DEFAULT_GRAPH = false
248247

249248
##
250249
# @private
251250
def self.extend_object(obj)
252251
obj.instance_variable_set(:@data, obj.options.delete(:data) ||
253-
Hamster::Hash.new)
252+
Hash.new)
254253
obj.instance_variable_set(:@tx_class,
255254
obj.options.delete(:transaction_class) ||
256-
SerializedTransaction)
255+
DEFAULT_TX_CLASS)
257256
super
258257
end
259258

@@ -263,7 +262,6 @@ def self.extend_object(obj)
263262
def supports?(feature)
264263
case feature.to_sym
265264
when :graph_name then @options[:with_graph_name]
266-
when :inference then false # forward-chaining inference
267265
when :validity then @options.fetch(:with_validity, true)
268266
when :literal_equality then true
269267
when :atomic_write then true
@@ -381,7 +379,7 @@ def apply_changeset(changeset)
381379
##
382380
# @see RDF::Dataset#isolation_level
383381
def isolation_level
384-
:serializable
382+
:snapshot
385383
end
386384

387385
##
@@ -471,7 +469,7 @@ def delete_statement(statement)
471469
# @private
472470
# @see RDF::Mutable#clear
473471
def clear_statements
474-
@data = @data.clear
472+
@data = @data.class.new
475473
end
476474

477475
##
@@ -513,14 +511,11 @@ def insert_to(data, statement)
513511
unless statement_in?(data, statement)
514512
s, p, o, c = statement.to_quad
515513
c ||= DEFAULT_GRAPH
516-
517-
return data.put(c) do |subs|
518-
(subs || Hamster::Hash.new).put(s) do |preds|
519-
(preds || Hamster::Hash.new).put(p) do |objs|
520-
(objs || Hamster::Hash.new).put(o, statement.options)
521-
end
522-
end
523-
end
514+
515+
data = data.has_key?(c) ? data.dup : data.merge(c => {})
516+
data[c] = data[c].has_key?(s) ? data[c].dup : data[c].merge(s => {})
517+
data[c][s] = data[c][s].has_key?(p) ? data[c][s].dup : data[c][s].merge(p => {})
518+
data[c][s][p] = data[c][s][p].merge(o => statement.options)
524519
end
525520
data
526521
end
@@ -529,93 +524,18 @@ def insert_to(data, statement)
529524
# @private
530525
# @return [Hamster::Hash] a new, updated hamster hash
531526
def delete_from(data, statement)
532-
if statement_in?(data, statement)
527+
if has_statement_in?(data, statement)
533528
s, p, o, g = statement.to_quad
534529
g = DEFAULT_GRAPH unless supports?(:graph_name)
535530
g ||= DEFAULT_GRAPH
536531

537-
os = data[g][s][p].delete(o)
538-
ps = os.empty? ? data[g][s].delete(p) : data[g][s].put(p, os)
539-
ss = ps.empty? ? data[g].delete(s) : data[g].put(s, ps)
540-
return ss.empty? ? data.delete(g) : data.put(g, ss)
532+
os = data[g][s][p].dup.delete_if {|k,v| k == o}
533+
ps = os.empty? ? data[g][s].dup.delete_if {|k,v| k == p} : data[g][s].merge(p => os)
534+
ss = ps.empty? ? data[g].dup.delete_if {|k,v| k == s} : data[g].merge(s => ps)
535+
return ss.empty? ? data.dup.delete_if {|k,v| k == g} : data.merge(g => ss)
541536
end
542537
data
543538
end
544-
545-
##
546-
# A transaction for the Hamster-based `RDF::Repository::Implementation`
547-
# with full serializability.
548-
#
549-
# @todo refactor me!
550-
# @see RDF::Transaction
551-
class SerializedTransaction < Transaction
552-
##
553-
# @see Transaction#initialize
554-
def initialize(*args, **options, &block)
555-
super(*args, **options, &block)
556-
@base_snapshot = @snapshot
557-
end
558-
559-
##
560-
# Inserts the statement to the transaction's working snapshot.
561-
#
562-
# @see Transaction#insert_statement
563-
def insert_statement(statement)
564-
@snapshot = @snapshot.class
565-
.new(data: @snapshot.send(:insert_to,
566-
@snapshot.send(:data),
567-
process_statement(statement)))
568-
end
569-
570-
##
571-
# Deletes the statement from the transaction's working snapshot.
572-
#
573-
# @see Transaction#insert_statement
574-
def delete_statement(statement)
575-
@snapshot = @snapshot.class
576-
.new(data: @snapshot.send(:delete_from,
577-
@snapshot.send(:data),
578-
process_statement(statement)))
579-
end
580-
581-
##
582-
# @see RDF::Dataset#isolation_level
583-
def isolation_level
584-
:serializable
585-
end
586-
587-
##
588-
# @note this is a simple object equality check.
589-
#
590-
# @see RDF::Transaction#mutated?
591-
def mutated?
592-
!@snapshot.send(:data).equal?(repository.send(:data))
593-
end
594-
595-
##
596-
# Replaces repository data with the transaction's snapshot in a safely
597-
# serializable fashion.
598-
#
599-
# @note this transaction uses a pessimistic merge strategy which
600-
# fails the transaction if any data has changed in the repository
601-
# since transaction start time. However, the specific guarantee is
602-
# softer: multiple concurrent conflicting transactions will not
603-
# succeed. We may choose to implement a less pessimistic merge
604-
# strategy as a non-breaking change.
605-
#
606-
# @raise [TransactionError] when the transaction can't be merged.
607-
# @see Transaction#execute
608-
def execute
609-
raise TransactionError, 'Cannot execute a rolled back transaction. ' \
610-
'Open a new one instead.' if instance_variable_defined?(:@rolledback) && @rolledback
611-
612-
raise TransactionError, 'Error merging transaction. Repository' \
613-
'has changed during transaction time.' unless
614-
repository.send(:data).equal? @base_snapshot.send(:data)
615-
616-
repository.send(:data=, @snapshot.send(:data))
617-
end
618-
end
619539
end # Implementation
620540
end # Repository
621541
end # RDF

rdf.gemspec

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ Gem::Specification.new do |gem|
3030
gem.required_ruby_version = '>= 2.6'
3131
gem.requirements = []
3232
gem.add_runtime_dependency 'link_header', '~> 0.0', '>= 0.0.8'
33-
gem.add_runtime_dependency 'hamster', '~> 3.0'
3433
gem.add_development_dependency 'rdf-spec', '~> 3.2'
3534
gem.add_development_dependency 'rdf-turtle', '~> 3.2'
3635
gem.add_development_dependency 'rdf-vocab', '~> 3.2'

spec/transaction_spec.rb

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,3 @@ class MyTx < described_class; end
7676
end
7777
end
7878
end
79-
80-
describe RDF::Repository::Implementation::SerializedTransaction do
81-
let(:repository) { RDF::Repository.new }
82-
83-
# @see lib/rdf/spec/transaction.rb in rdf-spec
84-
it_behaves_like "an RDF::Transaction",
85-
RDF::Repository::Implementation::SerializedTransaction
86-
end

0 commit comments

Comments
 (0)