Class: Cuboid::Support::Database::Hash

Inherits:
Base show all
Defined in:
lib/cuboid/support/database/hash.rb

Overview

Flat-file Hash implementation

Behaves pretty much like a Ruby Hash however it transparently serializes and saves its values to the file-system under the OS’s temp directory.

It’s not interchangeable with Ruby’s Hash as it lacks a lot of the stdlib methods.

Author:

Version:

  • 0.1

Constant Summary

Constants inherited from Base

Base::DISK_SPACE_FILE

Instance Method Summary collapse

Methods inherited from Base

decrement_disk_space, disk_directory, disk_space, disk_space_file, disk_space_file_for, disk_space_for, increment_disk_space, reset, #serialize, #unserialize

Constructor Details

#initialize(*args) ⇒ Hash

Returns a new instance of Hash.

See Also:

  • Database::Base#initialize


19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/cuboid/support/database/hash.rb', line 19

def initialize( *args )
    super( *args )

    # holds the internal representation of the Hash
    # same keys as self but the values are actually pointing to filepaths
    # where the real values are being stores
    @h = ::Hash.new

    # holds a key-value pair of self with digests as values
    # in order to allow comparisons without requiring to load
    # the actual values from their files.
    @eql_h = ::Hash.new
end

Instance Method Details

#==(h) ⇒ Bool Also known as: eql?

Note:

If the given hash is not of the same type as self it will be coerced to a Ruby Hash by calling ‘to_hash’ on it.

Returns ‘true` if self and the given hash contain the same key-pair values.

Returns:

  • (Bool)

    ‘true` if self and the given hash contain the same key-pair values.



264
265
266
267
268
269
270
271
272
# File 'lib/cuboid/support/database/hash.rb', line 264

def ==( h )
    if !h.is_a?( self.class )
        eql = {}
        h.to_hash.each { |k, v| eql[k] = eql_hash( serialize( v ) ) }
        @eql_h == eql
    else
        @eql_h == h._eql_h
    end
end

#[](k) ⇒ Object

Returns Object corresponding to the key object, ‘nil` otherwise.

Parameters:

  • k (Obj)

    key

Returns:

  • (Object)

    Object corresponding to the key object, ‘nil` otherwise.



53
54
55
# File 'lib/cuboid/support/database/hash.rb', line 53

def []( k )
    load( @h[k] ) if @h[k]
end

#[]=(k, v) ⇒ Object Also known as: store

Associates the given value with the given key.

Parameters:

Returns:



42
43
44
45
46
# File 'lib/cuboid/support/database/hash.rb', line 42

def []=( k, v )
    @h[k] = dump( v ) do |serialized|
        @eql_h[k] = eql_hash( serialized )
    end
end

#_eql_hObject



287
288
289
# File 'lib/cuboid/support/database/hash.rb', line 287

def _eql_h
    @eql_h.dup
end

#_internalHash

It will return a Ruby Hash with the same values as self but with filepaths as values (pointing to the files that store them).

This is used for efficient merging, i.e. without requiring to load the actual values when merging 2 objects.

Returns:

  • (Hash)

    Internal representation of ‘self`.



283
284
285
# File 'lib/cuboid/support/database/hash.rb', line 283

def _internal
    @h.dup
end

#assoc(k) ⇒ Array

Returns Array containing the given key and its value.

Parameters:

Returns:

  • (Array)

    Array containing the given key and its value.



62
63
64
65
# File 'lib/cuboid/support/database/hash.rb', line 62

def assoc( k )
    return if !@h[k]
    [ k, self[k] ]
end

#clearObject

Removes all objects.



254
255
256
257
# File 'lib/cuboid/support/database/hash.rb', line 254

def clear
    @h.values.each { |filepath| delete_file( filepath ) }
    @h.clear
end

#delete(k, &block) ⇒ Object

Removes an entry by key and returns its value.

If the key doesn’t exist and a block has been provided it’s passed the key and the method returns the result of that block.

Parameters:

Returns:



86
87
88
89
90
91
92
93
94
95
# File 'lib/cuboid/support/database/hash.rb', line 86

def delete( k, &block )
    if @h[k]
        obj = load_and_delete_file( @h[k] )
        @h.delete( k )
        @eql_h.delete( k )
        return obj
    else
        block.call( k ) if block_given?
    end
end

#each(&block) ⇒ Object Also known as: each_pair

Calls block with each key-value pair.

If a block has been given it retuns self. If no block has been given it returns an enumerator.

Parameters:

  • block (Proc)


111
112
113
114
115
116
117
118
# File 'lib/cuboid/support/database/hash.rb', line 111

def each( &block )
    if block_given?
        @h.each { |k, v| block.call( [ k, self[k] ] ) }
        self
    else
        enum_for( :each )
    end
end

#each_key(&block) ⇒ Object

Calls block with each key.

If a block has been given it returns self. If no block has been given it returns an enumerator.

Parameters:

  • block (Proc)


127
128
129
130
131
132
133
134
# File 'lib/cuboid/support/database/hash.rb', line 127

def each_key( &block )
    if block_given?
        @h.each_key( &block )
        self
    else
        enum_for( :each_key )
    end
end

#each_value(&block) ⇒ Object

Calls block with each value.

If a block has been given it returns ‘self`. If no block has been given it returns an enumerator.

Parameters:

  • block (Proc)


142
143
144
145
146
147
148
149
# File 'lib/cuboid/support/database/hash.rb', line 142

def each_value( &block )
    if block_given?
        @h.keys.each { |k| block.call( self[k] ) }
        self
    else
        enum_for( :each_value )
    end
end

#empty?Bool

Returns ‘true` if the Hash if empty, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the Hash if empty, `false` otherwise.



249
250
251
# File 'lib/cuboid/support/database/hash.rb', line 249

def empty?
    @h.empty?
end

#include?(k) ⇒ Bool Also known as: member?, key?, has_key?

Returns ‘true` if the given key exists in the hash, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the given key exists in the hash, `false` otherwise.



175
176
177
# File 'lib/cuboid/support/database/hash.rb', line 175

def include?( k )
    @h.include?( k )
end

#key(val) ⇒ Object

Returns key key for the given value.

Parameters:

Returns:

  • (Object)

    key key for the given value.



161
162
163
164
165
# File 'lib/cuboid/support/database/hash.rb', line 161

def key( val )
    return if !value?( val )
    each { |k, v| return k if val == self[k] }
    nil
end

#keysArray

Returns Keys.

Returns:



153
154
155
# File 'lib/cuboid/support/database/hash.rb', line 153

def keys
    @h.keys
end

#merge(h) ⇒ Cuboid::Database::Set

Merges the contents of self with the contents of the given hash and returns them in a new object.

Parameters:

Returns:

  • (Cuboid::Database::Set)


195
196
197
# File 'lib/cuboid/support/database/hash.rb', line 195

def merge( h )
    self.class.new( @options ).merge!( self ).merge!( h )
end

#merge!(h) ⇒ Object Also known as: update

Merges self with the contents of the given hash and returns self.

If the given Hash is of the same type as self then the values will not be loaded during the merge in order to keep memory usage down.

If the given Hash is any other kind of object it will be coerced to a Hash by calling ‘to_hash’ on it and the merging it with self.

Parameters:



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/cuboid/support/database/hash.rb', line 208

def merge!( h )
    if !h.is_a?( self.class )
        h.to_hash.each do |k, v|
            delete( k ) if @h.include?( k )
            self[k] = v
        end
    else
        h._internal.each do |k, v|
            delete( k ) if @h.include?( k )
            @h[k] = v
        end
        @eql_h.merge!( h._eql_h )
    end
    self
end

#rassoc(v) ⇒ Array

Returns Array containing the key for the given value and that value.

Parameters:

Returns:

  • (Array)

    Array containing the key for the given value and that value.



72
73
74
75
# File 'lib/cuboid/support/database/hash.rb', line 72

def rassoc( v )
    return if !value?( v )
    [ key( v ), v ]
end

#shiftArray

Removes the first key-value pair from the hash and returns it as a array,

Returns:



100
101
102
103
# File 'lib/cuboid/support/database/hash.rb', line 100

def shift
    k, v = @h.first
    [ k, delete( k ) ]
end

#sizeInteger Also known as: length

Returns Number of objects.

Returns:

  • (Integer)

    Number of objects.



242
243
244
# File 'lib/cuboid/support/database/hash.rb', line 242

def size
    @h.size
end

#to_aArray

Returns ‘self` as a Ruby Array.

Returns:

  • (Array)

    ‘self` as a Ruby Array.



236
237
238
# File 'lib/cuboid/support/database/hash.rb', line 236

def to_a
    to_hash.to_a
end

#to_hashHash Also known as: to_h

Returns ‘self` as Ruby Hash.

Returns:

  • (Hash)

    ‘self` as Ruby Hash



227
228
229
230
231
# File 'lib/cuboid/support/database/hash.rb', line 227

def to_hash
    h = {}
    each { |k, v| h[k] = v }
    h
end

#value?(v) ⇒ Bool

Returns ‘true` if the given value exists in the hash, `false` otherwise.

Returns:

  • (Bool)

    ‘true` if the given value exists in the hash, `false` otherwise.



184
185
186
187
# File 'lib/cuboid/support/database/hash.rb', line 184

def value?( v )
    each_value { |val| return true if val == v }
    false
end

#valuesArray

Returns Values.

Returns:



169
170
171
# File 'lib/cuboid/support/database/hash.rb', line 169

def values
    each_value.to_a
end