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