class PEROBS::ClassMap

PEROBS will usually store objects with a relatively small number of classes. Rather than storing the class name with each object, we map the class name to a numerical ID that represents the class in the store. This class handles the mapping and can convert class names into IDs and vice versa.

Public Class Methods

new(db) click to toggle source

Create a ClassMap object for a given data base. @param db [DataBase]

# File lib/perobs/ClassMap.rb, line 41
def initialize(db)
  @db = db
  @by_class = {}
  @by_id = []
  read_map
end

Public Instance Methods

class_to_id(klass) click to toggle source

Get the ID for a given class. @param klass [String] Class @return [Integer] ID. If klass is not yet known a new ID will be

allocated.
# File lib/perobs/ClassMap.rb, line 52
def class_to_id(klass)
  @by_class[klass] || new_id(klass)
end
classes() click to toggle source

Get a list of all classes used in the Store. @return [Array] list of Ruby classes

# File lib/perobs/ClassMap.rb, line 65
def classes
  @by_class.keys
end
id_to_class(id) click to toggle source

Get the klass for a given ID. @param id [Integer] @return [String] String version of the class

# File lib/perobs/ClassMap.rb, line 59
def id_to_class(id)
  @by_id[id]
end
keep(classes) click to toggle source

Delete all classes unless they are contained in classes. @param classes [Array of String] List of the class names

# File lib/perobs/ClassMap.rb, line 89
def keep(classes)
  @by_id.each.with_index do |klass, id|
    unless classes.include?(klass)
      # Delete the class from the @by_id list by setting the entry to nil.
      @by_id[id] = nil
      # Delete the corresponding @by_class entry as well.
      @by_class.delete(klass)
    end
  end
end
rename(rename_map) click to toggle source

Rename a set of classes to new names. @param rename_map [Hash] Hash that maps old names to new names

# File lib/perobs/ClassMap.rb, line 71
def rename(rename_map)
  @by_id.each.with_index do |klass, id|
    # Some entries can be nil. Ignore them.
    next unless klass

    if (new_name = rename_map[klass])
      # We have a rename request. Update the current @by_id entry.
      @by_id[id] = new_name
      # Remove the old class name from @by_class hash.
      @by_class.delete(klass)
      # Insert the new one with the current ID.
      @by_class[new_name] = id
    end
  end
end

Private Instance Methods

new_id(klass) click to toggle source
# File lib/perobs/ClassMap.rb, line 102
def new_id(klass)
  # Find the first 'nil' entry and return the index.
  idx = @by_id.find_index(nil) || @by_id.length

  # Insert the new class/ID touple into the hash and reverse map.
  @by_class[klass] = idx
  @by_id[idx] = klass
  # Write the updated version into the data base.
  write_map

  # Return the new ID.
  idx
end
read_map() click to toggle source
# File lib/perobs/ClassMap.rb, line 116
def read_map
  # Get the hash from the data base
  @by_class = @db.get_hash('class_map')
  # Build the reverse map from the hash.
  @by_class.each do |klass, id|
    @by_id[id] = klass
  end
end
write_map() click to toggle source
# File lib/perobs/ClassMap.rb, line 125
def write_map
  @db.put_hash('class_map', @by_class)
end