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