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
  @copied = false
  @maps = nil
  @pairs = nil
  @inserted = []
  @deleted = []
  @added = []
end

Instance Method Details

#&(other) ⇒ Object



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

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

#<<(map) ⇒ Object



64
65
66
67
68
# File 'lib/factbase/lazy_taped.rb', line 64

def <<(map)
  ensure_copied
  @maps << 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).



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

def added
  @added.uniq
end

#delete_ifObject



83
84
85
86
87
88
89
90
# File 'lib/factbase/lazy_taped.rb', line 83

def delete_if
  ensure_copied
  @maps.delete_if do |m|
    r = yield m
    @deleted.append(@pairs[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.



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

def deleted
  @deleted.uniq
end

#eachObject



70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/factbase/lazy_taped.rb', line 70

def each
  return to_enum(__method__) unless block_given?
  if @copied
    @maps.each do |m|
      yield Factbase::Taped::TapedHash.new(m, @added)
    end
  else
    @origin.each do |m|
      yield LazyTapedHash.new(m, self, @added)
    end
  end
end

#empty?Boolean

Returns:



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

def empty?
  (@maps || @origin).empty?
end

#ensure_copiedObject



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/factbase/lazy_taped.rb', line 111

def ensure_copied
  return if @copied
  @pairs = {}.compare_by_identity
  @maps =
    @origin.map do |m|
      n = m.transform_values(&:dup)
      @pairs[n] = m
      n
    end
  @copied = true
end

#find_by_object_id(oid) ⇒ Object



52
53
54
# File 'lib/factbase/lazy_taped.rb', line 52

def find_by_object_id(oid)
  (@maps || @origin).find { |m| m.object_id == oid }
end

#get_copied_map(original_map) ⇒ Object



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

def get_copied_map(original_map)
  ensure_copied
  @maps.find { |m| @pairs[m].equal?(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.



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

def inserted
  @inserted.uniq
end

#pairsObject

Returns a hash mapping copied maps to their originals. This is used during transaction commit to identify which original facts were modified, allowing the factbase to update the correct entries.



25
26
27
28
29
30
# File 'lib/factbase/lazy_taped.rb', line 25

def pairs
  return {} unless @pairs
  result = {}.compare_by_identity
  @pairs.each { |copied, original| result[copied] = original }
  result
end

#sizeObject



56
57
58
# File 'lib/factbase/lazy_taped.rb', line 56

def size
  (@maps || @origin).size
end

#to_aObject



92
93
94
# File 'lib/factbase/lazy_taped.rb', line 92

def to_a
  (@maps || @origin).to_a
end

#|(other) ⇒ Object



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

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