lib/perobs/BTree.rb in perobs-3.0.2 vs lib/perobs/BTree.rb in perobs-4.0.0
- old
+ new
@@ -25,11 +25,11 @@
# 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/LockFile'
require 'perobs/EquiBlobsFile'
-require 'perobs/BTreeNodeCache'
+require 'perobs/PersistentObjectCache'
require 'perobs/BTreeNode'
module PEROBS
# This BTree class is very similar to a classic BTree implementation. It
@@ -38,11 +38,11 @@
# The order of the tree specifies how many keys each node will be able to
# hold. Leaf nodes will have a value associated with each key. Branch nodes
# have N + 1 references to child nodes instead.
class BTree
- attr_reader :order, :nodes
+ attr_reader :order, :nodes, :node_cache
# Create a new BTree object.
# @param dir [String] Directory to store the tree file
# @param name [String] Base name of the BTree related files in 'dir'
# @param order [Integer] The maximum number of keys per node. This number
@@ -62,11 +62,11 @@
@order = order
# This EquiBlobsFile contains the nodes of the BTree.
@nodes = EquiBlobsFile.new(@dir, @name,
BTreeNode::node_bytes(@order))
- @node_cache = BTreeNodeCache.new
+ @node_cache = PersistentObjectCache.new(512, BTreeNode, self)
# This BTree implementation uses a write cache to improve write
# performance of multiple successive read/write operations. This also
# means that data may not be written on the backing store until the
# sync() or close() methods have been called. A bug in the program or a
@@ -87,12 +87,14 @@
PEROBS.log.fatal "Index file #{@nodes.file_name} does not exist"
end
@node_cache.clear
@nodes.open
- set_root(new_node(nil, @nodes.total_entries == 0 ?
- nil : @nodes.first_entry))
+ node = @nodes.total_entries == 0 ?
+ BTreeNode::create(self) :
+ BTreeNode::load(self, @nodes.first_entry)
+ set_root(node)
end
# Close the tree file.
def close
sync
@@ -102,18 +104,19 @@
# Clear all pools and forget any registered spaces.
def clear
@node_cache.clear
@nodes.clear
- set_root(new_node(nil))
+ set_root(BTreeNode::create(self))
end
# Erase the backing store of the BTree. This method should only be called
# when not having the BTree open. And it obviously and permanently erases
# all stored data from the BTree.
def erase
@nodes.erase
+ @root = nil
@dirty_flag.forced_unlock
end
# Flush all pending modifications into the tree file.
def sync
@@ -130,11 +133,10 @@
# Register a new node as root node of the tree.
def set_root(node)
@root = node
@nodes.first_entry = node.node_address
- @node_cache.set_root(node)
end
# Insert a new value into the tree using the key as a unique index. If the
# key already exists the old value will be overwritten.
# @param key [Integer] Unique key
@@ -176,56 +178,19 @@
# @yield [key, value]
def each(&block)
@root.each(&block)
end
- # Mark the given node as being modified. This will cause the dirty_flag
- # lock to be taken and the @is_dirty flag to be set.
- # @param node [BTreeNode] node to mark
- def mark_node_as_modified(node)
- unless @is_dirty
- @dirty_flag.lock
- @is_dirty = true
- end
- @node_cache.mark_as_modified(node)
- end
-
# Delete the node at the given address in the BTree file.
# @param address [Integer] address in file
def delete_node(address)
@node_cache.delete(address)
@nodes.delete_blob(address)
end
# @return [String] Human reable form of the tree.
def to_s
@root.to_s
- end
-
- # Create a new BTreeNode. If the node_address is not nil, the node data is
- # read from the backing store. The parent and is_leaf arguments are
- # ignored in this case.
- # @param parent [BTreeNode] parent node
- # @param node_address [Integer or nil] address of the node to create
- # @param is_leaf[Boolean] True if node is a leaf node, false otherweise
- def new_node(parent, node_address = nil, is_leaf = true)
- node = BTreeNode.new(self, parent, node_address, is_leaf)
- @node_cache.insert(node)
-
- node
- end
-
- # Return the BTreeNode that matches the given node address. If a blob
- # address and size are given, a new node is created instead of being read
- # from the file.
- # @param node_address [Integer] Address of the node in the BTree file
- # @return [BTreeNode]
- def get_node(node_address)
- if (node = @node_cache[node_address])
- return node
- end
-
- new_node(nil, node_address)
end
end
end