Class: Factbase::LazyTaped

Inherits:
Object
  • Object
show all
Defined in:
lib/factbase/lazy_taped.rb,
lib/factbase/lazy_taped_hash.rb,
lib/factbase/lazy_taped_array.rb

Overview

A lazy decorator of an Array with HashMaps that defers copying until modification.

Defined Under Namespace

Classes: LazyTapedArray, LazyTapedHash

Instance Method Summary collapse

Constructor Details

#initialize(origin) ⇒ LazyTaped

Returns a new instance of LazyTaped.



12
13
14
15
16
17
18
19
20
# File 'lib/factbase/lazy_taped.rb', line 12

def initialize(origin)
  @origin = origin
  @staged = []
  @copied = false
  @copies = {}.compare_by_identity
  @inserted = []
  @deleted = []
  @added = []
end

Instance Method Details

#&(other) ⇒ Object



109
110
111
112
113
# File 'lib/factbase/lazy_taped.rb', line 109

def &(other)
  return Factbase::Taped.new([], inserted: @inserted, deleted: @deleted, added: @added) if other == []
  return Factbase::Taped.new([], inserted: @inserted, deleted: @deleted, added: @added) if empty?
  _join(other, &:&)
end

#<<(map) ⇒ Object



67
68
69
70
71
# File 'lib/factbase/lazy_taped.rb', line 67

def <<(map)
  @staged << map
  _track(map, map)
  @inserted.append(map.object_id)
end

#addedObject

Returns the unique object IDs of maps that were modified (properties added). This is used during transaction commit to track the churn (number of changes).



49
50
51
# File 'lib/factbase/lazy_taped.rb', line 49

def added
  @added.uniq
end

#copied?Boolean

Returns:



29
30
31
# File 'lib/factbase/lazy_taped.rb', line 29

def copied?
  @copied
end

#delete_ifObject



90
91
92
93
94
95
96
97
# File 'lib/factbase/lazy_taped.rb', line 90

def delete_if
  ensure_copied!
  @staged.delete_if do |m|
    r = yield m
    @deleted.append(source_of(m).object_id) if r
    r
  end
end

#deletedObject

Returns the unique object IDs of maps that were deleted. This is used during transaction commit to identify facts that need to be removed from the factbase.



43
44
45
# File 'lib/factbase/lazy_taped.rb', line 43

def deleted
  @deleted.uniq
end

#eachObject



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/factbase/lazy_taped.rb', line 73

def each
  return to_enum(__method__) unless block_given?
  yielded_size = 0
  is_copied = copied?
  unless is_copied
    @origin.each do |m|
      yield _tape(m)
      yielded_size += 1
    end
  end
  staged = is_copied == copied? ? @staged : @staged[yielded_size..]
  staged&.each do |f|
    next if f.nil?
    yield _tape(f)
  end
end

#empty?Boolean

Returns:



63
64
65
# File 'lib/factbase/lazy_taped.rb', line 63

def empty?
  copied? ? @staged.empty? : (@origin.empty? && @staged.empty?)
end

#ensure_copied!Object



121
122
123
124
125
126
127
# File 'lib/factbase/lazy_taped.rb', line 121

def ensure_copied!
  return if copied?
  @staged = @origin.map do |o|
    o.transform_values(&:dup).tap { |c| _track(c, o) }
  end.concat(@staged)
  @copied = true
end

#find_by_object_id(oid) ⇒ Object



53
54
55
56
57
# File 'lib/factbase/lazy_taped.rb', line 53

def find_by_object_id(oid)
  r = @staged.find { |m| m.object_id == oid }
  r = @origin.find { |m| m.object_id == oid } if r.nil? && !copied?
  r
end

#get_copied_map(original_map) ⇒ Object



129
130
131
132
# File 'lib/factbase/lazy_taped.rb', line 129

def get_copied_map(original_map)
  ensure_copied!
  @copies[original_map] || original_map
end

#insertedObject

Returns the unique object IDs of maps that were inserted (newly created). This is used during transaction commit to identify new facts that need to be added to the factbase.



36
37
38
# File 'lib/factbase/lazy_taped.rb', line 36

def inserted
  @inserted.uniq
end

#repack(other) ⇒ Object



103
104
105
106
107
# File 'lib/factbase/lazy_taped.rb', line 103

def repack(other)
  ensure_copied!
  copied = other.map { |o| @copies[o] || o }
  Factbase::Taped.new(copied, inserted: @inserted, deleted: @deleted, added: @added)
end

#sizeObject



59
60
61
# File 'lib/factbase/lazy_taped.rb', line 59

def size
  copied? ? @staged.size : (@origin.size + @staged.size)
end

#source_of(copy) ⇒ Object

Returns the original map this copy was derived from. Returns nil if the base hasn’t been copied yet or if the fact is new.



24
25
26
27
# File 'lib/factbase/lazy_taped.rb', line 24

def source_of(copy)
  return nil unless @copied
  @copies.key(copy)
end

#to_aObject



99
100
101
# File 'lib/factbase/lazy_taped.rb', line 99

def to_a
  (copied? ? @staged : (@origin + @staged)).to_a
end

#|(other) ⇒ Object



115
116
117
118
119
# File 'lib/factbase/lazy_taped.rb', line 115

def |(other)
  return Factbase::Taped.new(to_a, inserted: @inserted, deleted: @deleted, added: @added) if other == []
  return Factbase::Taped.new(other, inserted: @inserted, deleted: @deleted, added: @added) if empty?
  _join(other, &:|)
end