Class: Arachni::Database::Hash
- Defined in:
- lib/arachni/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: Tasos “Zapotek” Laskos
<[email protected]>
<[email protected]>
@version: 0.1
Instance Method Summary collapse
-
#==(h) ⇒ Object
(also: #eql?)
Returns true if self and the given hash contain the same key-pair values.
-
#[](k) ⇒ Object
Retrieves the value object corresponding to the key object, nil otherwise.
-
#[]=(k, v) ⇒ Object
(also: #store)
Associates the given value with the given key.
- #_eql_h ⇒ Object
-
#_internal ⇒ Hash
Returns the internal representation of self.
-
#assoc(k) ⇒ Array
Returns an array containing the given key and its value.
-
#clear ⇒ Object
Removes all objects from the Queue.
-
#delete(k, &block) ⇒ Object
Removes an entry by key and returns its value.
-
#each(&block) ⇒ Object
(also: #each_pair)
Calls block with each key-value pair.
-
#each_key(&block) ⇒ Object
Calls block with each key.
-
#each_value(&block) ⇒ Object
Calls block with each value.
-
#empty? ⇒ Bool
True if the Queue if empty, false otherwise.
-
#include?(k) ⇒ Bool
(also: #member?, #key?, #has_key?)
Returns true if the given key exists in the hash, false otherwise.
-
#initialize(*args) ⇒ Hash
constructor
A new instance of Hash.
-
#key(val) ⇒ Object
Returns the key for the given value.
-
#keys ⇒ Array
Returns all keys as an array.
-
#merge(h) ⇒ Arachni::Database::Hash
Merges the contents of self with the contents of the given hash and returns them in a new object.
-
#merge!(h) ⇒ Object
(also: #update)
Merges self with the contents of the given hash and returns self.
-
#rassoc(v) ⇒ Array
Returns an array containing the key for the given value and that value.
-
#shift ⇒ Array
Removes the first key-value pair from the hash and returns it as a array,.
-
#size ⇒ Integer
(also: #length)
Size of the Queue, the number of objects it currently holds.
-
#to_a ⇒ Array
Converts self to a Ruby Array.
-
#to_hash ⇒ Hash
(also: #to_h)
Converts self to a Ruby Hash.
-
#value?(v) ⇒ Bool
Returns true if the given value exists in the hash, false otherwise.
-
#values ⇒ Array
Returns all values as an array.
Constructor Details
#initialize(*args) ⇒ Hash
Returns a new instance of Hash.
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/arachni/database/hash.rb', line 35 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) ⇒ Object Also known as: eql?
Returns true if self and the given hash contain the same key-pair values.
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.
343 344 345 346 347 348 349 350 351 352 353 354 |
# File 'lib/arachni/database/hash.rb', line 343 def ==( h ) if !h.is_a?( self.class ) eql = {} h.to_hash.each { |k, v| eql[k] = eql_hash( v.to_yaml ) } @eql_h == eql else @eql_h == h._eql_h end end |
#[](k) ⇒ Object
Retrieves the value object corresponding to the key object, nil otherwise.
71 72 73 |
# File 'lib/arachni/database/hash.rb', line 71 def []( k ) load( @h[k] ) if @h[k] end |
#[]=(k, v) ⇒ Object Also known as: store
Associates the given value with the given key.
55 56 57 58 59 60 |
# File 'lib/arachni/database/hash.rb', line 55 def []=( k, v ) @h[k] = dump( v ) { |serialized| @eql_h[k] = eql_hash( serialized ) } end |
#_eql_h ⇒ Object
372 373 374 |
# File 'lib/arachni/database/hash.rb', line 372 def _eql_h @eql_h.dup end |
#_internal ⇒ Hash
Returns the internal representation of self.
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.
368 369 370 |
# File 'lib/arachni/database/hash.rb', line 368 def _internal @h.dup end |
#assoc(k) ⇒ Array
Returns an array containing the given key and its value.
82 83 84 85 |
# File 'lib/arachni/database/hash.rb', line 82 def assoc( k ) return if !@h[k] [ k, self[k] ] end |
#clear ⇒ Object
Removes all objects from the Queue.
331 332 333 334 |
# File 'lib/arachni/database/hash.rb', line 331 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.
109 110 111 112 113 114 115 116 117 118 |
# File 'lib/arachni/database/hash.rb', line 109 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.<br/> If no block has been given it returns an enumerator.
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/arachni/database/hash.rb', line 138 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.<br/> If no block has been given it returns an enumerator.
159 160 161 162 163 164 165 166 |
# File 'lib/arachni/database/hash.rb', line 159 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 retuns self.<br/> If no block has been given it returns an enumerator.
176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/arachni/database/hash.rb', line 176 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
True if the Queue if empty, false otherwise.
324 325 326 |
# File 'lib/arachni/database/hash.rb', line 324 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.
226 227 228 |
# File 'lib/arachni/database/hash.rb', line 226 def include?( k ) @h.include?( k ) end |
#key(val) ⇒ Object
Returns the key for the given value.
204 205 206 207 208 209 210 |
# File 'lib/arachni/database/hash.rb', line 204 def key( val ) return if !value?( val ) each { |k, v| return k if val == self[val] } end |
#keys ⇒ Array
Returns all keys as an array.
193 194 195 |
# File 'lib/arachni/database/hash.rb', line 193 def keys @h.keys end |
#merge(h) ⇒ Arachni::Database::Hash
Merges the contents of self with the contents of the given hash and returns them in a new object.
254 255 256 |
# File 'lib/arachni/database/hash.rb', line 254 def merge( h ) self.class.new( serializer ).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.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/arachni/database/hash.rb', line 269 def merge!( h ) if !h.is_a?( self.class ) h.to_hash.each { |k, v| delete( k ) if @h.include?( k ) self[k] = v } else h._internal.each { |k, v| delete( k ) if @h.include?( k ) @h[k] = v } @eql_h.merge!( h._eql_h ) end self end |
#rassoc(v) ⇒ Array
Returns an array containing the key for the given value and that value.
94 95 96 97 |
# File 'lib/arachni/database/hash.rb', line 94 def rassoc( v ) return if !value?( v ) [ key( v ), v ] end |
#shift ⇒ Array
Removes the first key-value pair from the hash and returns it as a array,
125 126 127 128 |
# File 'lib/arachni/database/hash.rb', line 125 def shift k, v = @h.shift [ k, load_and_delete_file( v ) ] end |
#size ⇒ Integer Also known as: length
Size of the Queue, the number of objects it currently holds.
314 315 316 |
# File 'lib/arachni/database/hash.rb', line 314 def size @h.size end |
#to_a ⇒ Array
Converts self to a Ruby Array
305 306 307 |
# File 'lib/arachni/database/hash.rb', line 305 def to_a to_hash.to_a end |
#to_hash ⇒ Hash Also known as: to_h
Converts self to a Ruby Hash
293 294 295 296 297 |
# File 'lib/arachni/database/hash.rb', line 293 def to_hash h = {} each { |k, v| h[k] = v } return h end |
#value?(v) ⇒ Bool
Returns true if the given value exists in the hash, false otherwise.
238 239 240 241 242 243 244 |
# File 'lib/arachni/database/hash.rb', line 238 def value?( v ) each_value { |val| return true if val == v } return false end |
#values ⇒ Array
Returns all values as an array.
217 218 219 |
# File 'lib/arachni/database/hash.rb', line 217 def values each_value.to_a end |