class Puppet::Graph::RbTreeMap
Algorithms and Containers project is Copyright © 2009 Kanwei Li
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 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.
A RbTreeMap is a map that is stored in sorted order based on the order of its keys. This ordering is determined by applying the function <=> to compare the keys. No duplicate values for keys are allowed, so duplicate values are overwritten.
A major advantage of RBTreeMap over a Hash is the fact that keys are stored in order and can thus be iterated over in order. This is useful for many datasets.
The implementation is adapted from Robert Sedgewick's Left Leaning Red-Black Tree implementation, which can be found at www.cs.princeton.edu/~rs/talks/LLRB/Java/RedBlackBST.java
Most methods have O(log n) complexity.
Attributes
Public Class Methods
Create and initialize a new empty TreeMap.
# File lib/puppet/graph/rb_tree_map.rb 42 def initialize 43 @root = nil 44 @size = 0 45 end
Public Instance Methods
Deletes the item and key if it's found, and returns the item. Returns nil if key is not present.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.delete("MA") #=> "Massachusetts"
# File lib/puppet/graph/rb_tree_map.rb 122 def delete(key) 123 result = nil 124 if @root 125 return unless has_key? key 126 @root, result = delete_recursive(@root, key) 127 @root.color = :black if @root 128 @size -= 1 129 end 130 result 131 end
Deletes the item with the largest key and returns the item. Returns nil if key is not present.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.delete_max #=> "Georgia" map.size #=> 1
# File lib/puppet/graph/rb_tree_map.rb 168 def delete_max 169 result = nil 170 if @root 171 @root, result = delete_max_recursive(@root) 172 @root.color = :black if @root 173 @size -= 1 174 end 175 result 176 end
Deletes the item with the smallest key and returns the item. Returns nil if key is not present.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.delete_min #=> "Massachusetts" map.size #=> 1
# File lib/puppet/graph/rb_tree_map.rb 148 def delete_min 149 result = nil 150 if @root 151 @root, result = delete_min_recursive(@root) 152 @root.color = :black if @root 153 @size -= 1 154 end 155 result 156 end
Yields [key, value] pairs in order by key.
# File lib/puppet/graph/rb_tree_map.rb 179 def each(&blk) 180 recursive_yield(@root, &blk) 181 end
Returns true if the tree is empty, false otherwise
# File lib/puppet/graph/rb_tree_map.rb 134 def empty? 135 @root.nil? 136 end
# File lib/puppet/graph/rb_tree_map.rb 183 def first 184 return nil unless @root 185 node = min_recursive(@root) 186 [node.key, node.value] 187 end
Return the item associated with the key, or nil if none found.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.get("GA") #=> "Georgia"
# File lib/puppet/graph/rb_tree_map.rb 82 def get(key) 83 node = get_recursive(@root, key) 84 node ? node.value : nil 85 node.value if node 86 end
Return true if key is found in the TreeMap, false otherwise
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.has_key?("GA") #=> true map.has_key?("DE") #=> false
# File lib/puppet/graph/rb_tree_map.rb 70 def has_key?(key) 71 !get_recursive(@root, key).nil? 72 end
# File lib/puppet/graph/rb_tree_map.rb 189 def last 190 return nil unless @root 191 node = max_recursive(@root) 192 [node.key, node.value] 193 end
Return the largest key in the map.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.max_key #=> "MA"
# File lib/puppet/graph/rb_tree_map.rb 109 def max_key 110 @root.nil? ? nil : max_recursive(@root).key 111 end
Return the smallest key in the map.
Complexity: O(log n)
map = Containers::TreeMap.new map.push("MA", "Massachusetts") map.push("GA", "Georgia") map.min_key #=> "GA"
# File lib/puppet/graph/rb_tree_map.rb 97 def min_key 98 @root.nil? ? nil : min_recursive(@root).key 99 end
Insert an item with an associated key into the TreeMap, and returns the item inserted
Complexity: O(log n)
map = Containers::TreeMap.new map.push(“MA”, “Massachusetts”) #=> “Massachusetts” map.get(“MA”) #=> “Massachusetts”
# File lib/puppet/graph/rb_tree_map.rb 54 def push(key, value) 55 @root = insert(@root, key, value) 56 @root.color = :black 57 value 58 end
# File lib/puppet/graph/rb_tree_map.rb 195 def to_hash 196 @root ? @root.to_hash : {} 197 end
Private Instance Methods
# File lib/puppet/graph/rb_tree_map.rb 332 def delete_max_recursive(node) 333 if (isred(node.left)) 334 node = node.rotate_right 335 end 336 return nil, node.value if node.right.nil? 337 if ( !isred(node.right) && !isred(node.right.left) ) 338 node.move_red_right 339 end 340 node.right, result = delete_max_recursive(node.right) 341 342 return node.fixup, result 343 end
# File lib/puppet/graph/rb_tree_map.rb 320 def delete_min_recursive(node) 321 if node.left.nil? 322 return nil, node.value 323 end 324 if ( !isred(node.left) && !isred(node.left.left) ) 325 node.move_red_left 326 end 327 node.left, result = delete_min_recursive(node.left) 328 329 return node.fixup, result 330 end
# File lib/puppet/graph/rb_tree_map.rb 295 def delete_recursive(node, key) 296 if (key <=> node.key) == -1 297 node.move_red_left if ( !isred(node.left) && !isred(node.left.left) ) 298 node.left, result = delete_recursive(node.left, key) 299 else 300 node.rotate_right if isred(node.left) 301 if ( ( (key <=> node.key) == 0) && node.right.nil? ) 302 return nil, node.value 303 end 304 if ( !isred(node.right) && !isred(node.right.left) ) 305 node.move_red_right 306 end 307 if (key <=> node.key) == 0 308 result = node.value 309 min_child = min_recursive(node.right) 310 node.value = min_child.value 311 node.key = min_child.key 312 node.right = delete_min_recursive(node.right).first 313 else 314 node.right, result = delete_recursive(node.right, key) 315 end 316 end 317 return node.fixup, result 318 end
# File lib/puppet/graph/rb_tree_map.rb 345 def get_recursive(node, key) 346 return nil if node.nil? 347 case key <=> node.key 348 when 0 then return node 349 when -1 then return get_recursive(node.left, key) 350 when 1 then return get_recursive(node.right, key) 351 end 352 end
# File lib/puppet/graph/rb_tree_map.rb 366 def insert(node, key, value) 367 unless node 368 @size += 1 369 return Node.new(key, value) 370 end 371 372 case key <=> node.key 373 when 0 then node.value = value 374 when -1 then node.left = insert(node.left, key, value) 375 when 1 then node.right = insert(node.right, key, value) 376 end 377 378 node.rotate_left if (node.right && node.right.red?) 379 node.rotate_right if (node.left && node.left.red? && node.left.left && node.left.left.red?) 380 node.colorflip if (node.left && node.left.red? && node.right && node.right.red?) 381 node 382 end
# File lib/puppet/graph/rb_tree_map.rb 384 def isred(node) 385 return false if node.nil? 386 387 node.color == :red 388 end
# File lib/puppet/graph/rb_tree_map.rb 360 def max_recursive(node) 361 return node if node.right.nil? 362 363 max_recursive(node.right) 364 end
# File lib/puppet/graph/rb_tree_map.rb 354 def min_recursive(node) 355 return node if node.left.nil? 356 357 min_recursive(node.left) 358 end
# File lib/puppet/graph/rb_tree_map.rb 288 def recursive_yield(node, &blk) 289 return unless node 290 recursive_yield(node.left, &blk) 291 yield node.key, node.value 292 recursive_yield(node.right, &blk) 293 end