class PEROBS::BigHash
The BigHash
is similar to the Hash
object in that it provides a simple hash functionality. The difference is that this class scales to much larger data sets essentially limited to the amount of space available on your backing store. The data is persisted immediately and uses transactions to ensure the data consistent. It only provides a small subset of the methods provided by the native Hash
class that make sense for giant data sets.
Public Class Methods
Create a new BigHash
object. @param p [Handle] Store
handle
PEROBS::Object::new
# File lib/perobs/BigHash.rb, line 75 def initialize(p) super(p) restore self.btree = @store.new(PEROBS::BigTree) end
Public Instance Methods
Retrieve the value for the given key. If no value for the key is found nil is returned. @param key [Integer or String] @return [Any PEROBS
storable object]
# File lib/perobs/BigHash.rb, line 132 def [](key) hashed_key = hash_key(key) unless (entry = @btree.get(hashed_key)) return nil end if entry.is_a?(PEROBS::Array) entry.each do |ae| return ae.value if ae.key == key end else return entry.value if entry.key == key end nil end
Insert a value that is associated with the given key. If a value for this key already exists, the value will be overwritten with the newly provided value. @param key [Integer or String] @param value [Any PEROBS
storable object]
# File lib/perobs/BigHash.rb, line 89 def []=(key, value) hashed_key = hash_key(key) @store.transaction do entry = @store.new(Entry, key, value) if (existing_entry = @btree.get(hashed_key)) # There is already an existing entry for this hashed key. if existing_entry.is_a?(Collisions) # Find the right index to insert the new entry. If there is # already an entry with the same key overwrite that entry. index_to_insert = 0 overwrite = false existing_entry.each do |ae| if ae.key == key overwrite = true break end index_to_insert += 1 end existing_entry[index_to_insert] = entry elsif existing_entry.key == key # The existing value is for the identical key. We can safely # overwrite @btree.insert(hashed_key, entry) else # There is a single existing entry, but for a different key. Create # a new PEROBS::Array and store both entries. array_entry = @store.new(Collisions) array_entry << existing_entry array_entry << entry @btree.insert(hashed_key, array_entry) end else # No existing entry. Insert the new entry. @btree.insert(hashed_key, entry) end end end
Check if the data structure contains any errors. @return [Boolean] true if no erros were found, false otherwise
# File lib/perobs/BigHash.rb, line 233 def check return @btree.check end
Delete and return the entry for the given key. Return nil if no matching entry exists. @param key [Integer or String] @return [Object] Deleted entry
# File lib/perobs/BigHash.rb, line 175 def delete(key) hashed_key = hash_key(key) unless (entry = @btree.get(hashed_key)) return nil end if entry.is_a?(PEROBS::Array) entry.each_with_index do |ae, i| if ae.key == key return entry.delete_at(i).value end end else return entry.value if entry.key == key end nil end
Calls the given block for each key/value pair. @yield(key, value)
# File lib/perobs/BigHash.rb, line 210 def each(&block) @btree.each do |index, entry| if entry.is_a?(Collisions) break if entry.each do |c_entry| yield(c_entry.key, c_entry.value) end.nil? else yield(entry.key, entry.value) end end end
Return true if hash is empty. False otherweise. @return [TrueClass, FalseClass]
# File lib/perobs/BigHash.rb, line 204 def empty? @btree.entry_counter == 0 end
Check if the is a value stored for the given key. @param key [Integer or String] @return [TrueClass or FalseClass]
# File lib/perobs/BigHash.rb, line 152 def has_key?(key) hashed_key = hash_key(key) unless (entry = @btree.get(hashed_key)) return false end if entry.is_a?(PEROBS::Array) entry.each do |ae| return true if ae.key == key end else return true if entry.key == key end false end
This is mostly intended for debugging as the result can be very big. It returns an Array
of keys stored in the hash. @return [Array] A list of all keys
# File lib/perobs/BigHash.rb, line 225 def keys ks = [] each { |k, v| ks << k } ks end
Return the number of entries stored in the hash. @return [Integer]
# File lib/perobs/BigHash.rb, line 196 def length @btree.entry_counter end
# File lib/perobs/BigHash.rb, line 81 def restore end
Private Instance Methods
# File lib/perobs/BigHash.rb, line 239 def hash_key(key) FNV_Hash_1a_64::digest(key) end