lib/perobs/BTreeNode.rb in perobs-4.3.0 vs lib/perobs/BTreeNode.rb in perobs-4.4.0
- old
+ new
@@ -76,11 +76,11 @@
@children = children || []
@values = nil
end
end
- # Create a new SpaceTreeNode. This method should be used for the creation
+ # Create a new BTreeNode. This method should be used for the creation
# of new nodes instead of calling the constructor directly.
# @param tree [BTree] The tree the new node should belong to
# @param parent [BTreeNode] The parent node
# @param is_leaf [Boolean] True if the node has no children, false
# otherwise
@@ -128,11 +128,12 @@
PEROBS.log.fatal "Checksum failure in BTreeNode entry @#{address}"
end
ary = bytes.unpack(BTreeNode::node_bytes_format(tree))
# Read is_leaf
if ary[0] != 0 && ary[0] != 1
- PEROBS.log.fatal "First byte of a BTreeNode entry must be 0 or 1"
+ PEROBS.log.fatal "First byte of a BTreeNode entry at address " +
+ "#{address} must be 0 or 1 but is #{ary[0]}"
end
is_leaf = ary[0] == 0 ? false : true
# This is the number of keys this node has.
key_count = ary[1]
data_count = ary[2]
@@ -348,10 +349,11 @@
# @return [BTreeNodeLink] common parent of the two nodes
def split_node
unless @parent
# The node is the root node. We need to create a parent node first.
self.parent = link(BTreeNode::create(@tree, nil, false))
+ @tree.node_cache.insert(self)
@parent.set_child(0, self)
@tree.set_root(@parent)
end
# Create the new sibling that will take the 2nd half of the
@@ -380,30 +382,29 @@
if @keys.size >= @tree.order
PEROBS.log.fatal "Cannot insert into a full BTreeNode"
end
i = search_key_index(key)
+ @tree.node_cache.insert(self)
if @keys[i] == key
# Overwrite existing entries
@keys[i] = key
if is_leaf
@values[i] = value_or_child
else
@children[i + 1] = link(value_or_child)
end
- @tree.node_cache.insert(self)
return false
else
# Create a new entry
@keys.insert(i, key)
if is_leaf
@values.insert(i, value_or_child)
else
@children.insert(i + 1, link(value_or_child))
end
- @tree.node_cache.insert(self)
return true
end
end
@@ -415,12 +416,12 @@
"@#{@node_address}"
end
update_branch_key(key) if index == 0
# Delete the corresponding value.
- removed_value = @values.delete_at(index)
@tree.node_cache.insert(self)
+ removed_value = @values.delete_at(index)
if @keys.length < min_keys
if @prev_sibling && @prev_sibling.parent == @parent
borrow_from_previous_sibling(@prev_sibling) ||
@prev_sibling.merge_with_leaf_node(self)
@@ -479,28 +480,28 @@
def merge_with_leaf_node(node)
if @keys.length + node.keys.length > @tree.order
PEROBS.log.fatal "Leaf nodes are too big to merge"
end
+ @tree.node_cache.insert(self)
@keys += node.keys
@values += node.values
- @tree.node_cache.insert(self)
node.parent.remove_child(node)
end
def merge_with_branch_node(node)
if @keys.length + 1 + node.keys.length > @tree.order
PEROBS.log.fatal "Branch nodes are too big to merge"
end
index = @parent.search_node_index(node) - 1
+ @tree.node_cache.insert(self)
@keys << @parent.keys[index]
@keys += node.keys
node.children.each { |c| c.parent = link(self) }
@children += node.children
- @tree.node_cache.insert(self)
node.parent.remove_child(node)
end
def search_node_index(node)
@@ -523,10 +524,11 @@
if dest_node.is_leaf != @is_leaf
PEROBS.log.fatal "Source #{@is_leaf} and destination " +
"#{dest_node.is_leaf} node must be of same kind"
end
+ @tree.node_cache.insert(dest_node)
dest_node.keys[dst_idx, count] = @keys[src_idx, count]
if @is_leaf
# For leaves we copy the keys and corresponding values.
dest_node.values[dst_idx, count] = @values[src_idx, count]
else
@@ -535,64 +537,62 @@
# moved-up key.
(count + 1).times do |i|
dest_node.set_child(dst_idx + i, @children[src_idx + i])
end
end
- @tree.node_cache.insert(dest_node)
end
def parent=(p)
- @parent = p
@tree.node_cache.insert(self)
+ @parent = p
p
end
def prev_sibling=(node)
+ @tree.node_cache.insert(self)
@prev_sibling = node
if node.nil? && @is_leaf
# If this node is a leaf node without a previous sibling we need to
# register it as the first leaf node.
@tree.set_first_leaf(BTreeNodeLink.new(@tree, self))
end
- @tree.node_cache.insert(self)
-
node
end
def next_sibling=(node)
- @next_sibling = node
@tree.node_cache.insert(self)
+ @next_sibling = node
if node.nil? && @is_leaf
# If this node is a leaf node without a next sibling we need to
# register it as the last leaf node.
@tree.set_last_leaf(BTreeNodeLink.new(@tree, self))
end
node
end
def set_child(index, child)
+ @tree.node_cache.insert(self)
if child
@children[index] = link(child)
@children[index].parent = link(self)
else
@children[index] = nil
end
- @tree.node_cache.insert(self)
child
end
def trim(idx)
+ @tree.node_cache.insert(self)
@keys.slice!(idx, @keys.length - idx)
if @is_leaf
@values.slice!(idx, @values.length - idx)
else
@children.slice!(idx + 1, @children.length - idx - 1)
end
- @tree.node_cache.insert(self)
end
# Search the keys of the node that fits the given key. The result is
# either the index of an exact match or the index of the position where
# the given key would have to be inserted.