Class: Higgs::MVCCCache

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/higgs/cache.rb

Overview

cache for Multi-Version Concurrency Control

Defined Under Namespace

Classes: Snapshot

Instance Method Summary collapse

Constructor Details

#initializeMVCCCache

Returns a new instance of MVCCCache.



117
118
119
120
# File 'lib/higgs/cache.rb', line 117

def initialize
  @lock = Mutex.new
  @snapshots = {}
end

Instance Method Details

#ref_count_down(cnum) ⇒ Object



168
169
170
171
172
173
174
# File 'lib/higgs/cache.rb', line 168

def ref_count_down(cnum)
  @lock.synchronize{
    @snapshots[cnum][:ref_count] -= 1
    @snapshots.delete(cnum) if (@snapshots[cnum][:ref_count] == 0)
  }
  nil
end

#ref_count_up(cnum_func) ⇒ Object



159
160
161
162
163
164
165
166
# File 'lib/higgs/cache.rb', line 159

def ref_count_up(cnum_func)
  @lock.synchronize{
    cnum = cnum_func.call
    @snapshots[cnum] = { :lock => ReadWriteLock.new, :cache => {}, :ref_count => 0 } unless (@snapshots.key? cnum)
    @snapshots[cnum][:ref_count] += 1
    return cnum, @snapshots[cnum][:lock].read_lock, @snapshots[cnum][:cache]
  }
end

#transaction(cnum_func) ⇒ Object



261
262
263
264
265
266
267
268
269
270
271
# File 'lib/higgs/cache.rb', line 261

def transaction(cnum_func)
  r = nil
  snapshot = Snapshot.new(self)
  snapshot.ref_count_up(cnum_func)
  begin
    r = yield(snapshot)
  ensure
    snapshot.ref_count_down
  end
  r
end

#write_old_values(cnum, write_list) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/higgs/cache.rb', line 125

def write_old_values(cnum, write_list)
  # new snapshot is not created until the update ends.
  snapshot_list = @lock.synchronize{ @snapshots.values }

  for snapshot in snapshot_list
    @snapshots.each_value do |snapshot|
      lock = snapshot[:lock].write_lock
      cache = snapshot[:cache]
      lock.synchronize{
        for ope, key, type, value in write_list
          case (ope)
          when :value
            if (cache.key? key) then
              if (cache[key] != :none && ! (cache[key].key? type)) then
                cache[key][type] = { :value => value, :cnum => cnum }
              end
            else
              cache[key] = { type => { :value => value, :cnum => cnum } }
            end
          when :none
            unless (cache.key? key) then
              cache[key] = :none
            end
          else
            raise "unknown operation: #{ope}"
          end
        end
      }
    end
  end

  nil
end