Class: Tupelo::Archiver::PersistentTuplespace

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/tupelo/archiver/persistent-tuplespace.rb

Defined Under Namespace

Classes: Rec

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(persist_dir: nil, zero_tolerance: Tupelo::Archiver::ZERO_TOLERANCE) ⇒ PersistentTuplespace

Returns a new instance of PersistentTuplespace.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 27

def initialize(
    persist_dir: nil,
    zero_tolerance: Tupelo::Archiver::ZERO_TOLERANCE)

  @next_id = 0
  @tuple_rec = Hash.new {|h,k| h[k] = Rec.new(self, k)}
  @nzero = 0
  @zero_tolerance = zero_tolerance
  @next_rec_to_save = nil

  if persist_dir
    require 'tupelo/archiver/persister.rb'
    @persister = Persister.new persist_dir
    read_from_persister
  else
    @persister = nil
  end
end

Instance Attribute Details

#zero_toleranceObject (readonly)

Returns the value of attribute zero_tolerance.



5
6
7
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 5

def zero_tolerance
  @zero_tolerance
end

Instance Method Details

#clear_excess_zerosObject



117
118
119
120
121
122
123
124
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 117

def clear_excess_zeros
  nd = (@nzero - zero_tolerance / 2)
  @nzero -= nd
  @tuple_rec.delete_if {|tuple, rec| rec.count == 0 && (nd-=1) >= 0}
  @nzero += nd
  
  @persister.clear_excess_zeros if @persister
end

#delete_once(tuple) ⇒ Object



84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 84

def delete_once tuple
  rec = @tuple_rec[tuple]
  if rec.count > 0
    rec.count -= 1
    if rec.count == 0
      @nzero += 1
      clear_excess_zeros if @nzero > zero_tolerance
    end
    mark_to_save rec if @persister
    true
  else
    false
  end
end

#eachObject

note: multiple equal tuples are yielded once



64
65
66
67
68
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 64

def each
  @tuple_rec.each do |tuple, rec|
    yield tuple, rec.count if rec.count > 0
  end
end

#find_distinct_matches_for(tuples) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 126

def find_distinct_matches_for tuples
  h = Hash.new(0)
  tuples.map do |tuple|
    if @tuple_rec[tuple].count > h[tuple]
      h[tuple] += 1
      tuple
    else
      nil
    end
  end
end

#find_match_for(tuple) ⇒ Object



138
139
140
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 138

def find_match_for tuple
  @tuple_rec[tuple].count > 0 && tuple
end

#flush(tick) ⇒ Object



111
112
113
114
115
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 111

def flush tick
  if @persister
    @persister.flush(@next_rec_to_save, @next_id, tick)
  end
end

#insert(tuple) ⇒ Object



78
79
80
81
82
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 78

def insert tuple
  rec = @tuple_rec[tuple]
  rec.count += 1
  mark_to_save rec if @persister
end

#mark_to_save(rec) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 70

def mark_to_save rec
  unless rec.next_rec_to_save
    rec.next_rec_to_save = @next_rec_to_save
    @next_rec_to_save = rec
    nil
  end
end

#next_idObject



59
60
61
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 59

def next_id
  @next_id += 1
end

#read_from_persisterObject



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 46

def read_from_persister
  @persister.each do |tuple_row|
    packed = tuple_row[:packed]
    tuple = MessagePack.unpack(packed)
    rec = @tuple_rec[tuple]
    rec.count = tuple_row[:count]
    rec.id = tuple_row[:id]
    rec.packed = packed
  end
  @next_id = @persister.next_id
  ## @persister.tick # how to send this back to worker? do we need to?
end

#transaction(inserts: [], deletes: [], tick: nil) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/tupelo/archiver/persistent-tuplespace.rb', line 99

def transaction inserts: [], deletes: [], tick: nil
  deletes.each do |tuple|
    delete_once tuple or raise "bug"
  end

  inserts.each do |tuple|
    insert tuple.freeze ## freeze recursively
  end
  
  flush tick
end