btree.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
-------------------------> GNU Sather - sourcefile <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute and/or modify it under the terms of the GNU Library General --
-- Public License (LGPL) as published by the Free Software Foundation; --
-- either version 2 of the license, or (at your option) any later version. --
-- This library is distributed in the hope that it will be useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details. --
-- The license text is also available from: Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
--------------> Please email comments to <bug-sather@gnu.org> <--------------
class B_TREE{KEY < $IS_LT{KEY}, ELT, NODE < $BT_NODE{KEY,ELT,NODE}}
class B_TREE{KEY < $IS_LT{KEY}, ELT, NODE < $BT_NODE{KEY,ELT,NODE}}
< $MAP{ KEY, ELT } is
-- This is an implementation of the standard balanced tree abstraction
-- based upon the kind of node given in BT_NODE (derived from $BY_NODE).
-- Balnced trees can be used as an alternative to a map. This
-- implementation is optimised for use where there is slow access to
-- individual elements.
-- Version 1.2 Nov 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 22 Mar 95 hk Original
-- 13 Mar 97 kh Changed to CARD from INT
-- 12 Nov 98 kh Revised for 1.2, added pre/post conditions.
include MAP_INCL{KEY,ELT} ;
private attr root : NODE ;
readonly attr size : CARD ;
create : SAME is
-- This creation routine simply returns a new object, relying on
-- the language specification for the components to be void!
return new
end ;
copy : SAME
pre ~void(self)
post true -- (result = self)
is
-- This routine returns a new copy of self.
res : SAME := create ;
loop
pair : TUP{KEY,ELT} := pair! ;
res[pair.t1] := pair.t2
end ;
return res
end ;
has_ind(
key : KEY
) : BOOL
pre ~void(self)
post true
is
-- This predicate returns true if and only if the given key exists in
-- the btree, otherwise false.
if void(root) then
return false
end ;
stack : A_STACK{TUP{CARD,NODE}} := A_STACK{TUP{CARD,NODE}}::create ;
res : BOOL := root.find(key,stack) ;
return res
end ;
contains(
elem : ELT
) : BOOL
pre ~void(self)
post true
is
-- This predicate returns true if and only if the given element is in
-- the btree, otherwise false.
loop
other : ELT := root.elt! ;
if ELT_EQ{ELT}::elt_eq(elem,other) then
return true
end
end ;
return false
end ;
aset(
key : KEY,
data : ELT
)
pre ~void(self)
post contains(TUP{KEY,ELT}::create(key,data))
is
-- This routine associates the data value with the given key in the tree.
-- If the key already exists then the associated node data will be over-
-- ritten. Note that associating void with a key is the equivalent of
-- deleting the key and data.
node,
elem : NODE ;
pos : CARD ;
found : BOOL ;
stack : A_STACK{TUP{CARD,NODE}} := A_STACK{TUP{CARD,NODE}}::create ;
item : TUP{KEY,ELT} := TUP{KEY,ELT}::create(key,data) ;
if void(root) then
root := NODE::create(item) ;
size := 1 ;
return
end ;
found := root.find(key,stack) ;
node := stack.top.t2 ;
pos := stack.pop.t1 ;
if found then
node.set_item(pos,item)
else
size := size + 1 ;
elem := NODE::create(item) ;
loop
if node.size < node.Max_Size then
node.node_insert(elem,pos) ;
break!
elsif node = root then
root := node.split(elem,pos) ;
break!
elsif node.right_free(stack) then
node.push_right(elem,pos,stack) ;
break!
elsif node.left_free(stack) then
node.push_left(elem,pos,stack) ;
break!
end ;
elem := node.split(elem,pos) ;
node := stack.top.t2 ;
pos := stack.pop.t1
end
end
end ;
aget(
key : KEY
) : ELT
pre ~void(self)
post has_ind(key)
or void(result)
is
-- This routine retrives the alement associated with the given key,
-- unless the key is not present when void is returned.
stack : A_STACK{TUP{CARD,NODE}} := A_STACK{TUP{CARD,NODE}}::create ;
if root.find(key,stack) then
return stack.top.t2[stack.top.t1].item.t2
else
return void
end
end ;
insert(
elem : TUP{KEY,ELT}
) : SAME
pre true
post ~void(result)
is
-- This insertion routine inserts elem into the tree, which is returned.
return insert(elem.t1,elem.t2)
end ;
delete(
key : KEY
) : ELT
pre ~void(self)
post true
is
-- This routine removes the key and associated data from the btree and
-- returns the element deleted (or void if not found!).
node,
del_node : NODE ;
pos,
del_posn : CARD ;
found : BOOL ;
if void(root) then
return void
end ;
stack : A_STACK{TUP{CARD,NODE}} := A_STACK{TUP{CARD,NODE}}::create ;
found := root.find(key,stack) ;
if ~found then
return void
end ;
size := size - 1 ;
del_node := stack.top.t2 ;
del_posn := stack.top.t1 ;
res : ELT := del_node[del_posn].item.t2 ;
if ~void(del_node[del_posn].node) then -- not a true leaf
del_node.find_pred(stack) ;
node := stack.top.t2 ;
pos := stack.pop.t1 - 1 ;
del_node.set_item(del_posn,node[pos].item)
else -- as del_posn but need to pop!
node := del_node ;
pos := stack.pop.t1
end ;
loop
if node = root then
node.node_delete(pos) ;
if node.size = 0 then
root := node[0].node
end ;
break!
elsif node.size > node.Min_Size then
node.node_delete(pos) ;
break!
elsif node.left_spare(stack) then
node.pull_left(pos,stack) ;
break!
elsif node.right_spare(stack) then
node.pull_right(pos,stack) ;
break!
end ;
if stack.top.t1 < stack.top.t2.size then
node.join_right(pos,stack)
else
node.join_left(pos,stack)
end ;
node := stack.top.t2 ;
pos := stack.pop.t1
end ;
return res
end ;
delete(
key : KEY
)
pre ~void(self)
post ~has_ind(key)
is
-- This routine deletes the item with the given key (if it exists).
dummy : ELT := delete(key)
end ;
ind! : KEY
pre ~void(self)
post has_ind(result)
is
-- This iter yields all keys in order.
loop
yield root.ind!
end
end ;
target! : ELT
pre ~void(self)
post contains(result)
is
-- This iter yields all key/element pairs in order.
loop
yield root.elt!
end
end ;
pair! : TUP{KEY,ELT}
pre ~void(self)
post contains(result)
is
-- This iter yields all key/element pairs in order.
loop
yield root.pair!
end
end ;
elt! : TUP{KEY,ELT}
pre ~void(self)
post contains(result)
is
-- This iter yields the elements of self in the order of the keys.
loop
yield pair!
end
end ;
end ; -- B_TREE
class B_TREE{KEY < $IS_LT{KEY}, ELT}
class B_TREE{KEY < $IS_LT{KEY}, ELT} is
-- This implementation is provided by including a version with
-- the class BT_NODE. It implements the standard balanced tree abstraction.
-- Version 1.1 Mar 97. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 22 Mar 95 hk Original
-- 13 Mar 97 kh Revised for style conformance.
include B_TREE{KEY,ELT,BT_NODE{KEY,ELT}} ;
end ; -- B_TREE