class Garcon::Stash::Store
Stash::Store
contains the public api for Stash
. It includes Enumerable
for functional goodies like map, each, reduce and friends.
@api public
Attributes
Set default value, can be a callable
Public Class Methods
A handler that will ensure that stashs are closed and synced when the current process exits.
@private
# File lib/garcon/stash/store.rb, line 409 def self.exit_handler loop do stash = @@stashs_mutex.synchronize { @@stashs.shift } break unless stash warn "Stash #{stash.file} was not closed, state might be inconsistent" begin stash.close rescue Exception => e warn "Failed to close stash store: #{e.message}" end end end
Create a new Stash::Store
. 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 Stash Store file.
@param [Hash] opts
Options hash for creating a new stash.
@option opts [Class] :serializer
Serializer class
@option opts [Class] :format
Format class
@option opts [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/garcon/stash/store.rb, line 79 def initialize(file, opts = {}, &block) opts = { serializer: opts.fetch(:serializer, Serializer::Default), format: opts.fetch(:format, Format), default: opts.fetch(:default, nil) } @format = (opts[:format]).new @serializer = (opts[:serializer]).new @table = Hash.new(&method(:hash_default)) @journal = Journal.new(file, @format, @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 : opts[:default] @mutex = Mutex.new @@stashs_mutex.synchronize { @@stashs << self } end
Public Instance Methods
Retrieve a value at key from the stash. If the default value was specified when this stash was created, that value will be set and returned. Aliased as ‘#get`.
@param [Object] key
the value to retrieve from the stash
@return [Object]
the value
# File lib/garcon/stash/store.rb, line 134 def [](key) @table[@serializer.key_for(key)] end
Set a key in the stash to be written at some future date. If the data needs to be persisted immediately, call ‘#store.set(key, value, true)`.
@param [Object] key
the key of the storage slot in the stash
@param [Object] value
the value to store
@return [Object]
the value
# File lib/garcon/stash/store.rb, line 151 def []=(key, value) key = @serializer.key_for(key) @journal << [key, value] @table[key] = value end
Utility method that will return the size of the stash in bytes, useful for determining when to compact.
@return [Fixnum]
# File lib/garcon/stash/store.rb, line 271 def bytesize @journal.bytesize end
Remove all keys and values from the stash.
@return [Stash] self
# File lib/garcon/stash/store.rb, line 364 def clear @table.clear @journal.clear self end
Close the stash for reading and writing.
@return nil
# File lib/garcon/stash/store.rb, line 383 def close @journal.close @@stashs_mutex.synchronize { @@stashs.delete(self) } nil end
Check to see if we’ve already closed the stash.
@return [Boolean]
# File lib/garcon/stash/store.rb, line 393 def closed? @journal.closed? end
Compact the stash to remove stale commits and reduce the file size.
@return [Stash] self
# File lib/garcon/stash/store.rb, line 374 def compact @journal.compact { @table } self end
Return default value belonging to key.
@param [Object] key
the default value to retrieve.
@return [Object]
value the default value
# File lib/garcon/stash/store.rb, line 120 def default(key = nil) @table.default(@serializer.key_for(key)) end
Delete a key from the stash.
@param [Object] key
the key of the storage slot in the stash
@return [Object]
the value
# File lib/garcon/stash/store.rb, line 183 def delete(key) key = @serializer.key_for(key) @journal << [key] @table.delete(key) end
Immediately delete the key on disk.
@param [Object] key
the key of the storage slot in the stash
@return [Object]
the value
# File lib/garcon/stash/store.rb, line 197 def delete!(key) value = delete(key) flush value end
Iterate over the key, value pairs in the stash.
@yield [key, value] block
the iterator for each key value pair
@yieldparam key the key.
@yieldparam value the value from the stash.
# File lib/garcon/stash/store.rb, line 300 def each(&block) @table.each(&block) end
Return true if stash is empty.
@return [Boolean]
# File lib/garcon/stash/store.rb, line 287 def empty? @table.empty? end
Stash
store file name.
@return [String]
stash store file name
# File lib/garcon/stash/store.rb, line 108 def file @journal.file end
Flush all changes to disk.
@return [Stash] self
# File lib/garcon/stash/store.rb, line 316 def flush @journal.flush self end
Does this stash have this key?
@param [Object] key
the key to check if the stash has it
@return [Boolean]
# File lib/garcon/stash/store.rb, line 238 def has_key?(key) @table.has_key?(@serializer.key_for(key)) end
Does this stash have this value?
@param [Object] value
the value to check if the Stash has it
@return [Boolean]
# File lib/garcon/stash/store.rb, line 252 def has_value?(value) @table.has_value?(value) end
The block used in @table for new records.
# File lib/garcon/stash/store.rb, line 426 def hash_default(_, key) if @default != nil value = @default.respond_to?(:call) ? @default.call(key) : @default @journal << [key, value] @table[key] = value end end
Return the keys in the stash.
@return [Array<String>]
# File lib/garcon/stash/store.rb, line 308 def keys @table.keys end
Sync the stash with what is on disk, by first flushing changes, and then loading the new records if necessary.
@return [Stash] self
# File lib/garcon/stash/store.rb, line 326 def load @journal.load self end
Lock the stash 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 stash is synced @yieldparam [Stash] stash @return result of the block
# File lib/garcon/stash/store.rb, line 341 def lock synchronize { @journal.lock { yield self } } end
Counter of how many records are in the journal.
@return [Fixnum]
# File lib/garcon/stash/store.rb, line 279 def logsize @journal.size end
Flushes data immediately to disk.
@param [Object] key
the key of the storage slot in the stash
@param [Object] value
the value to store
@return [Object]
the value
# File lib/garcon/stash/store.rb, line 169 def set!(key, value) set(key, value) flush value end
Return the number of stored items.
@return [Fixnum]
# File lib/garcon/stash/store.rb, line 261 def size @table.size end
Synchronize access to the stash from multiple threads. @note Stash
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 stash is synced
@yieldparam [Stash] stash
@return result of the block
# File lib/garcon/stash/store.rb, line 356 def synchronize @mutex.synchronize { yield self } end
Update stash with hash (fast batch update).
@param [Hash] hash
the key/value hash
@return [Stash] self
# File lib/garcon/stash/store.rb, line 210 def update(hash) shash = {} hash.each { |key, value| shash[@serializer.key_for(key)] = value } @journal << shash @table.update(shash) self end
Updata stash and flush data to disk.
@param [Hash] hash
the key/value hash
@return [Stash] self
# File lib/garcon/stash/store.rb, line 225 def update!(hash) update(hash) @journal.flush end