Class: PEROBS::Hash

Inherits:
ObjectBase show all
Defined in:
lib/perobs/Hash.rb

Overview

A Hash that is transparently persisted in the back-end storage. It is very similar to the Ruby built-in Hash class but has some additional limitations. The hash key must always be a String.

The implementation is largely a proxy around the standard Hash class. But all mutating methods must be re-implemented to convert PEROBS::Objects to POXReference objects and to register the object as modified with the cache. However, it is not designed for large data sets as it always reads and writes the full data set for every access (unless it is cached). For data sets that could have more than a few hundred entries BigHash is the recommended alternative.

We explicitely don’t support Hash::store() as it conflicts with ObjectBase::store() method to access the store.

Constant Summary

Constants inherited from ObjectBase

ObjectBase::NATIVE_CLASSES

Instance Attribute Summary

Attributes inherited from ObjectBase

#_id, #myself, #store

Instance Method Summary collapse

Methods inherited from ObjectBase

#==, #_check_assignment_value, _finalize, #_initialize, #_restore, #_stash, #_sync, #_transfer, read, #restore

Constructor Details

#initialize(p, default = nil, &block) ⇒ Hash

New PEROBS objects must always be created by calling # Store.new(). PEROBS users should never call this method or equivalents of derived methods directly.

Parameters:

  • p (PEROBS::Handle)

    PEROBS handle

  • default (Object) (defaults to: nil)

    The default value that is returned when no value is stored for a specific key. The default must be of the supported type.



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/perobs/Hash.rb', line 112

def initialize(p, default = nil, &block)
  super(p)
  _check_assignment_value(default)
  if block_given?
    @data = ::Hash.new(&block)
  else
    @data = ::Hash.new(default)
  end

  # Ensure that the newly created object will be pushed into the database.
  @store.cache.cache_write(self)
end

Instance Method Details

#[]=(key, value) ⇒ Object

Proxy for assignment method.



126
127
128
129
130
131
132
133
134
# File 'lib/perobs/Hash.rb', line 126

def []=(key, value)
  unless key.is_a?(String)
    raise ArgumentError, "PEROBS::Hash[] key must be a String but is a " +
      "#{key.class}"
  end
  _check_assignment_value(value)
  @store.cache.cache_write(self)
  @data[key] = value
end

#_delete_reference_to_id(id) ⇒ Object

This method should only be used during store repair operations. It will delete all referenced to the given object ID.

Parameters:

  • id (Integer)

    targeted object ID



153
154
155
156
157
158
# File 'lib/perobs/Hash.rb', line 153

def _delete_reference_to_id(id)
  @data.delete_if do |k, v|
    v && v.respond_to?(:is_poxreference?) && v.id == id
  end
  @store.cache.cache_write(self)
end

#_deserialize(data) ⇒ Object

Restore the persistent data from a single data structure. This is a library internal method. Do not use outside of this library.

Parameters:

  • data (Hash)

    the actual Hash object



164
165
166
167
168
169
# File 'lib/perobs/Hash.rb', line 164

def _deserialize(data)
  @data = {}
  data.each { |k, v| @data[k] = v.is_a?(POReference) ?
                                POXReference.new(@store, v.id) : v }
  @data
end

#_referenced_object_idsArray of Integer

Return a list of all object IDs of all persistend objects that this Hash is referencing.

Returns:

  • (Array of Integer)

    IDs of referenced objects



145
146
147
148
# File 'lib/perobs/Hash.rb', line 145

def _referenced_object_ids
  @data.each_value.select { |v| v && v.respond_to?(:is_poxreference?) }.
    map { |o| o.id }
end

#default=(value) ⇒ Object

Proxy for default= method.



137
138
139
140
# File 'lib/perobs/Hash.rb', line 137

def default=(value)
  _check_assignment_value(value)
  @data.default=(value)
end

#inspectString

Textual dump for debugging purposes

Returns:

  • (String)


173
174
175
176
177
178
179
180
# File 'lib/perobs/Hash.rb', line 173

def inspect
  "<#{self.class}:#{@_id}>\n{\n" +
  @data.map do |k, v|
    "  #{k.inspect} => " + (v.respond_to?(:is_poxreference?) ?
            "<PEROBS::ObjectBase:#{v._id}>" : v.inspect)
  end.join(",\n") +
  "\n}\n"
end