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

new(p) click to toggle source

Create a new BigHash object. @param p [Handle] Store handle

Calls superclass method 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

[](key) click to toggle source

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
[]=(key, value) click to toggle source

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() click to toggle source

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(key) click to toggle source

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
each() { |key, value| ... } click to toggle source

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
empty?() click to toggle source

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
has_key?(key) click to toggle source

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
Also aliased as: include?
include?(key)
Alias for: has_key?
keys() click to toggle source

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
length() click to toggle source

Return the number of entries stored in the hash. @return [Integer]

# File lib/perobs/BigHash.rb, line 196
def length
  @btree.entry_counter
end
Also aliased as: size
restore() click to toggle source
# File lib/perobs/BigHash.rb, line 81
def restore
end
size()
Alias for: length

Private Instance Methods

hash_key(key) click to toggle source
# File lib/perobs/BigHash.rb, line 239
def hash_key(key)
  FNV_Hash_1a_64::digest(key)
end