perobs 2.5.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,107 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # = BTree.rb -- Persistent Ruby Object Store
4
+ #
5
+ # Copyright (c) 2016, 2017 by Chris Schlaeger <chris@taskjuggler.org>
6
+ #
7
+ # MIT License
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+
28
+ require 'perobs/BTreeNode'
29
+
30
+ module PEROBS
31
+
32
+ class BTreeNodeCache
33
+
34
+ def initialize
35
+ clear
36
+ end
37
+
38
+ def [](address)
39
+ if (node = @modified_nodes[address])
40
+ return node
41
+ end
42
+
43
+ if (node = @top_nodes[address])
44
+ return node
45
+ end
46
+
47
+ if (node = @ephemeral_nodes[address])
48
+ return node
49
+ end
50
+
51
+ nil
52
+ end
53
+
54
+ def set_root(node)
55
+ node = node.get_node if node.is_a?(BTreeNodeLink)
56
+
57
+ @top_nodes = {}
58
+ @top_nodes[node.node_address] = node
59
+ end
60
+
61
+ def insert(node)
62
+ unless node
63
+ PEROBS.log.fatal "nil cannot be cached"
64
+ end
65
+ node = node.get_node if node.is_a?(BTreeNodeLink)
66
+
67
+ @ephemeral_nodes[node.node_address] = node
68
+
69
+ if !@top_nodes.include?(node) && node.is_top?
70
+ @top_nodes[node.node_address] = node
71
+ end
72
+ end
73
+
74
+ def mark_as_modified(node)
75
+ node = node.get_node if node.is_a?(BTreeNodeLink)
76
+ @modified_nodes[node.node_address] = node
77
+ insert(node)
78
+ end
79
+
80
+ # Remove a node from the cache.
81
+ # @param address [Integer] address of node to remove.
82
+ def delete(address)
83
+ @ephemeral_nodes.delete(address)
84
+ @top_nodes.delete(address)
85
+ @modified_nodes.delete(address)
86
+ end
87
+
88
+ # Flush all dirty nodes into the backing store.
89
+ def flush(now = false)
90
+ if now || @modified_nodes.size > 1024
91
+ @modified_nodes.each_value { |node| node.write_node }
92
+ @modified_nodes = {}
93
+ end
94
+ @ephemeral_nodes = {}
95
+ end
96
+
97
+ # Remove all nodes from the cache.
98
+ def clear
99
+ @top_nodes = {}
100
+ @ephemeral_nodes = {}
101
+ @modified_nodes = {}
102
+ end
103
+
104
+ end
105
+
106
+ end
107
+
@@ -0,0 +1,141 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # = BTreeNodeLink.rb -- Persistent Ruby Object Store
4
+ #
5
+ # Copyright (c) 2016, 2017 by Chris Schlaeger <chris@taskjuggler.org>
6
+ #
7
+ # MIT License
8
+ #
9
+ # Permission is hereby granted, free of charge, to any person obtaining
10
+ # a copy of this software and associated documentation files (the
11
+ # "Software"), to deal in the Software without restriction, including
12
+ # without limitation the rights to use, copy, modify, merge, publish,
13
+ # distribute, sublicense, and/or sell copies of the Software, and to
14
+ # permit persons to whom the Software is furnished to do so, subject to
15
+ # the following conditions:
16
+ #
17
+ # The above copyright notice and this permission notice shall be
18
+ # included in all copies or substantial portions of the Software.
19
+ #
20
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
+
28
+ module PEROBS
29
+
30
+ # This class is used to form the links between the in-memory BTreeNode
31
+ # objects. The link is based on the address of the node in the file. The
32
+ # class objects transparently convert the address into a corresponding
33
+ # BTreeNode object and pass on all method calls.
34
+ class BTreeNodeLink
35
+
36
+ attr_reader :node_address
37
+
38
+ # Create a new BTreeNodeLink object.
39
+ # @param tree [BTree] The BTree that holds the nodes.
40
+ # @param node_or_address [BTreeNode or BTreeNodeLink or Integer] a
41
+ # BTreeNode, BTreeNodeLink reference or the node
42
+ # address in the file.
43
+ def initialize(tree, node_or_address)
44
+ @tree = tree
45
+ if node_or_address.is_a?(BTreeNode) ||
46
+ node_or_address.is_a?(BTreeNodeLink)
47
+ @node_address = node_or_address.node_address
48
+ elsif node_or_address.is_a?(Integer)
49
+ @node_address = node_or_address
50
+ else
51
+ PEROBS.log.fatal "Unsupported argument type #{node_or_address.class}"
52
+ end
53
+ if @node_address == 0
54
+ PEROBS.log.fatal "Node address may not be 0"
55
+ end
56
+ end
57
+
58
+ # All calls to a BTreeNodeLink object will be forwarded to the
59
+ # corresponding BTreeNode object. If that
60
+ def method_missing(method, *args, &block)
61
+ #$stderr.puts "Method missing: #{method}"
62
+ get_node.send(method, *args, &block)
63
+ end
64
+
65
+ # Make it properly introspectable.
66
+ def respond_to?(method, include_private = false)
67
+ get_node.respond_to?(method)
68
+ end
69
+
70
+ def is_leaf
71
+ get_node.is_leaf
72
+ end
73
+
74
+ def keys
75
+ get_node.keys
76
+ end
77
+
78
+ def values
79
+ get_node.values
80
+ end
81
+
82
+ def children
83
+ get_node.children
84
+ end
85
+
86
+ def get(key)
87
+ get_node.get(key)
88
+ end
89
+
90
+ def search_key_index(key)
91
+ get_node.search_key_index(key)
92
+ end
93
+
94
+ def insert_element(key, voc)
95
+ get_node.insert_element(key, voc)
96
+ end
97
+
98
+ # Compare this node to another node.
99
+ # @return [Boolean] true if node address is identical, false otherwise
100
+ def ==(node)
101
+ @node_address == node.node_address
102
+ end
103
+
104
+ # Compare this node to another node.
105
+ # @return [Boolean] true if node address is not identical, false otherwise
106
+ def !=(node)
107
+ if node.nil?
108
+ return !@node_address.nil?
109
+ end
110
+
111
+ @node_address != node.node_address
112
+ end
113
+
114
+ def is_top?
115
+ get_node.is_top?
116
+ end
117
+
118
+ # Check the link to a sub-node. This method silently ignores all errors if
119
+ # the sub-node does not exist.
120
+ # @return [Boolean] True if link is OK, false otherweise
121
+ def check_node_link(branch, stack)
122
+ begin
123
+ return get_node.check_node_link(branch, stack)
124
+ rescue
125
+ return false
126
+ end
127
+ end
128
+
129
+ # @return Textual version of the BTreeNode
130
+ def to_s
131
+ get_node.to_s
132
+ end
133
+
134
+ def get_node
135
+ @tree.get_node(@node_address)
136
+ end
137
+
138
+ end
139
+
140
+ end
141
+