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
21
# File 'lib/factbase/lazy_taped.rb', line 12

def initialize(origin)
  @origin = origin
  @copied = false
  @maps = nil
  @pairs = nil
  @inverted_pairs = nil
  @inserted = []
  @deleted = []
  @added = []
end

Instance Method Details

#&(other) ⇒ Object



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

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

#<<(map) ⇒ Object



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

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).



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

def added
  @added.uniq
end

#delete_ifObject



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

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.



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

def deleted
  @deleted.uniq
end

#eachObject



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

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:



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

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

#ensure_copied!Object



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/factbase/lazy_taped.rb', line 118

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

#find_by_object_id(oid) ⇒ Object



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

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

#get_copied_map(original_map) ⇒ Object



132
133
134
135
# File 'lib/factbase/lazy_taped.rb', line 132

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.



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

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.



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

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

#repack(other) ⇒ Object



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

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

#sizeObject



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

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

#to_aObject



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

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

#|(other) ⇒ Object



110
111
112
113
114
115
116
# File 'lib/factbase/lazy_taped.rb', line 110

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