lib/perobs/BigArray.rb in perobs-4.5.0 vs lib/perobs/BigArray.rb in perobs-4.6.0

- old
+ new

@@ -1,6 +1,6 @@ -# encoding: UTF-8 +# # frozen_string_literal: true # # = BigArray.rb -- Persistent Ruby Object Store # # Copyright (c) 2016, 2017, 2018, 2019 # by Chris Schlaeger <chris@taskjuggler.org> @@ -24,25 +24,21 @@ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -require 'perobs/Object' -require 'perobs/BigArrayNode' +require_relative 'Object' +require_relative 'BigArrayNode' module PEROBS - # The BigArray class implements an Array that stores the data in segments. It # only loads the currently needed parts of the Array into memory. To provide # an efficient access to the data by index a B+Tree like data structure is # used. Each segment is stored in a leaf node of the B+Tree. class BigArray < PEROBS::Object + Stats = Struct.new(:leaf_nodes, :branch_nodes, :min_depth, :max_depth) - class Stats < Struct.new(:leaf_nodes, :branch_nodes, :min_depth, - :max_depth) - end - attr_persist :node_size, :root, :first_leaf, :last_leaf, :entry_counter # Internal constructor. Use Store.new() instead. # @param p [Handle] # @param node_size [Integer] The size of the tree nodes. This determines @@ -51,16 +47,12 @@ # spot. Smaller values will improve write operations. Larger # values will improve read operations. 20 - 500 is a reasonable # range to try. def initialize(p, node_size = 150) super(p) - unless node_size > 3 - PEROBS.log.fatal "Node size (#{node_size}) must be larger than 3" - end - unless node_size % 2 == 0 - PEROBS.log.fatal "Node size (#{node_size}) must be an even number" - end + PEROBS.log.fatal "Node size (#{node_size}) must be larger than 3" unless node_size > 3 + PEROBS.log.fatal "Node size (#{node_size}) must be an even number" unless (node_size % 2).zero? self.node_size = node_size clear end @@ -144,15 +136,13 @@ # Delete the element at the specified index, returning that element, or # nil if the index is out of range. # @param index [Integer] Index in the BigArray # @return [Object] found value or nil def delete_at(index) - if index < 0 - index = @entry_counter + index - end + index = @entry_counter + index if index.negative? - return nil if index < 0 || index >= @entry_counter + return nil if index.negative? || index >= @entry_counter deleted_value = nil @store.transaction do deleted_value = @root.delete_at(index) self.entry_counter -= 1 @@ -174,13 +164,11 @@ # @yield [key, value] def delete_if old_root = @root clear old_root.each do |k, v| - if !yield(k, v) - insert(k, v) - end + insert(k, v) unless yield(k, v) end end # @return [Integer] The number of entries stored in the tree. def length @@ -189,11 +177,11 @@ alias size length # Return true if the BigArray has no stored entries. def empty? - @entry_counter == 0 + @entry_counter.zero? end # Return the first entry of the Array. def first return nil unless @first_leaf @@ -213,10 +201,11 @@ # @yield [key, value] def each(&block) node = @first_leaf while node break unless node.each(&block) + node = node.next_sibling end end # Iterate over all entries in the tree in reverse order. Entries are @@ -224,21 +213,22 @@ # @yield [key, value] def reverse_each(&block) node = @last_leaf while node break unless node.reverse_each(&block) + node = node.prev_sibling end end # Convert the BigArray into a Ruby Array. This is primarily intended for # debugging as real-world BigArray objects are likely too big to fit into # memory. def to_a ary = [] node = @first_leaf - while node do + while node ary += node.values node = node.next_sibling end ary @@ -265,21 +255,18 @@ end private def validate_index_range(index) - if index < 0 + if index.negative? if -index > @entry_counter - raise IndexError, "index #{index} too small for array; " + - "minimum #{-@entry_counter}" + raise IndexError, "index #{index} too small for array; " \ + "minimum #{-@entry_counter}" end index = @entry_counter + index end index end - end - end -