class Daybreak::DB

Daybreak::DB contains the public api for Daybreak. It includes Enumerable for functional goodies like map, each, reduce and friends. @api public

Attributes

default[W]

Set default value, can be a callable

Public Class Methods

new(file, options = {}, &block) click to toggle source

Create a new Daybreak::DB. The second argument is the default value to store when accessing a previously unset key, this follows the Hash standard. @param [String] file the path to the db file @param [Hash] options a hash that contains the options for creating a new database @option options [Class] :serializer Serializer class @option options [Class] :format Format class @option options [Object] :default Default value @yield [key] a block that will return the default value to store. @yieldparam [String] key the key to be stored.

# File lib/daybreak/db.rb, line 21
def initialize(file, options = {}, &block)
  @serializer = (options[:serializer] || Serializer::Default).new
  @table = Hash.new(&method(:hash_default))
  @journal = Journal.new(file, (options[:format] || Format).new, @serializer) do |record|
    if !record
      @table.clear
    elsif record.size == 1
      @table.delete(record.first)
    else
      @table[record.first] = @serializer.load(record.last)
    end
  end
  @default = block ? block : options[:default]
  @mutex = Mutex.new # Mutex used by #synchronize and #lock
  @@databases_mutex.synchronize { @@databases << self }
end

Private Class Methods

exit_handler() click to toggle source

A handler that will ensure that databases are closed and synced when the current process exits. @private

# File lib/daybreak/db.rb, line 258
def self.exit_handler
  loop do
    db = @@databases_mutex.synchronize { @@databases.shift }
    break unless db
    warn "Daybreak database #{db.file} was not closed, state might be inconsistent"
    begin
      db.close
    rescue Exception => ex
      warn "Failed to close daybreak database: #{ex.message}"
    end
  end
end

Public Instance Methods

[](key) click to toggle source

Retrieve a value at key from the database. If the default value was specified when this database was created, that value will be set and returned. Aliased as get. @param [Object] key the value to retrieve from the database. @return [Object] the value

# File lib/daybreak/db.rb, line 56
def [](key)
  @table[@serializer.key_for(key)]
end
Also aliased as: get
[]=(key, value) click to toggle source

Set a key in the database to be written at some future date. If the data needs to be persisted immediately, call db.set(key, value, true). @param [Object] key the key of the storage slot in the database @param [Object] value the value to store @return [Object] the value

# File lib/daybreak/db.rb, line 66
def []=(key, value)
  key = @serializer.key_for(key)
  @journal << [key, value]
  @table[key] = value
end
Also aliased as: set
bytesize() click to toggle source

Utility method that will return the size of the database in bytes, useful for determining when to compact @return [Fixnum]

# File lib/daybreak/db.rb, line 150
def bytesize
  @journal.bytesize
end
clear() click to toggle source

Remove all keys and values from the database. @return [DB] self

# File lib/daybreak/db.rb, line 220
def clear
  @table.clear
  @journal.clear
  self
end
close() click to toggle source

Close the database for reading and writing. @return nil

# File lib/daybreak/db.rb, line 235
def close
  @journal.close
  @@databases_mutex.synchronize { @@databases.delete(self) }
  nil
end
closed?() click to toggle source

Check to see if we’ve already closed the database. @return [Boolean]

# File lib/daybreak/db.rb, line 243
def closed?
  @journal.closed?
end
compact() click to toggle source

Compact the database to remove stale commits and reduce the file size. @return [DB] self

# File lib/daybreak/db.rb, line 228
def compact
  @journal.compact { @table }
  self
end
default(key = nil) click to toggle source

Return default value belonging to key @param [Object] key the default value to retrieve. @return [Object] value the default value

# File lib/daybreak/db.rb, line 47
def default(key = nil)
  @table.default(@serializer.key_for(key))
end
delete(key) click to toggle source

Delete a key from the database @param [Object] key the key of the storage slot in the database @return [Object] the value

# File lib/daybreak/db.rb, line 86
def delete(key)
  key = @serializer.key_for(key)
  @journal << [key]
  @table.delete(key)
end
delete!(key) click to toggle source

Immediately delete the key on disk. @param [Object] key the key of the storage slot in the database @return [Object] the value

# File lib/daybreak/db.rb, line 95
def delete!(key)
  value = delete(key)
  flush
  value
end
each(&block) click to toggle source

Iterate over the key, value pairs in the database. @yield [key, value] blk the iterator for each key value pair. @yieldparam key the key. @yieldparam value the value from the database.

# File lib/daybreak/db.rb, line 170
def each(&block)
  @table.each(&block)
end
empty?() click to toggle source

Return true if database is empty. @return [Boolean]

# File lib/daybreak/db.rb, line 162
def empty?
  @table.empty?
end
file() click to toggle source

Database file name @return [String] database file name

# File lib/daybreak/db.rb, line 40
def file
  @journal.file
end
flush() click to toggle source

Flush all changes to disk. @return [DB] self

# File lib/daybreak/db.rb, line 182
def flush
  @journal.flush
  self
end
get(key)
Alias for: []
has_key?(key) click to toggle source

Does this db have this key? @param [Object] key the key to check if the DB has it @return [Boolean]

# File lib/daybreak/db.rb, line 125
def has_key?(key)
  @table.has_key?(@serializer.key_for(key))
end
Also aliased as: key?, include?, member?
has_value?(value) click to toggle source

Does this db have this value? @param [Object] value the value to check if the DB has it @return [Boolean]

# File lib/daybreak/db.rb, line 135
def has_value?(value)
  @table.has_value?(value)
end
Also aliased as: value?
include?(key)
Alias for: has_key?
key?(key)
Alias for: has_key?
keys() click to toggle source

Return the keys in the db. @return [Array<String>]

# File lib/daybreak/db.rb, line 176
def keys
  @table.keys
end
length()
Alias for: size
load() click to toggle source

Sync the database with what is on disk, by first flushing changes, and then loading the new records if necessary. @return [DB] self

# File lib/daybreak/db.rb, line 190
def load
  @journal.load
  self
end
Also aliased as: sunrise
lock() { |self| ... } click to toggle source

Lock the database for an exclusive commit across processes and threads @note This method performs an expensive locking over process boundaries.

If you want to synchronize only between threads, use #synchronize.

@see synchronize @yield a block where every change to the database is synced @yieldparam [DB] db @return result of the block

# File lib/daybreak/db.rb, line 203
def lock
  synchronize { @journal.lock { yield self } }
end
logsize() click to toggle source

Counter of how many records are in the journal @return [Fixnum]

# File lib/daybreak/db.rb, line 156
def logsize
  @journal.size
end
member?(key)
Alias for: has_key?
set(key, value)
Alias for: []=
set!(key, value) click to toggle source

set! flushes data immediately to disk. @param [Object] key the key of the storage slot in the database @param [Object] value the value to store @return [Object] the value

# File lib/daybreak/db.rb, line 77
def set!(key, value)
  set(key, value)
  flush
  value
end
size() click to toggle source

Return the number of stored items. @return [Fixnum]

# File lib/daybreak/db.rb, line 142
def size
  @table.size
end
Also aliased as: length
sunrise()
Alias for: load
synchronize() { |self| ... } click to toggle source

Synchronize access to the database from multiple threads @note Daybreak is not thread safe, if you want to access it from

multiple threads, all accesses have to be in the #synchronize block.

@see lock @yield a block where every change to the database is synced @yieldparam [DB] db @return result of the block

# File lib/daybreak/db.rb, line 214
def synchronize
  @mutex.synchronize { yield self }
end
update(hash) click to toggle source

Update database with hash (Fast batch update) @param [Hash] hash the key/value hash @return [DB] self

# File lib/daybreak/db.rb, line 104
def update(hash)
  shash = {}
  hash.each do |key, value|
    shash[@serializer.key_for(key)] = value
  end
  @journal << shash
  @table.update(shash)
  self
end
update!(hash) click to toggle source

Updata database and flush data to disk. @param [Hash] hash the key/value hash @return [DB] self

# File lib/daybreak/db.rb, line 117
def update!(hash)
  update(hash)
  @journal.flush
end
value?(value)
Alias for: has_value?

Private Instance Methods

hash_default(_, key) click to toggle source

The block used in @table for new records

# File lib/daybreak/db.rb, line 274
def hash_default(_, key)
  if @default != nil
    value = @default.respond_to?(:call) ? @default.call(key) : @default
    @journal << [key, value]
    @table[key] = value
  end
end