From e6dde28c95b66a46a0dc05bfc9a5586b64e08575 Mon Sep 17 00:00:00 2001 From: niftynif Date: Mon, 4 Nov 2013 19:45:49 -0500 Subject: [PATCH 1/4] Added skeleton implementation of a B-tree with a few bells and whistles. No major functionality added yet (such as insertion and removal). --- src/libextra/btree.rs | 372 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 372 insertions(+) create mode 100644 src/libextra/btree.rs diff --git a/src/libextra/btree.rs b/src/libextra/btree.rs new file mode 100644 index 00000000000..5a4892a2391 --- /dev/null +++ b/src/libextra/btree.rs @@ -0,0 +1,372 @@ +// +// btree.rs +// Nif Ward +// 10/24/13 +// +// starting implementation of a btree for rust +// inspired by github user davidhalperin's gist + + +//What's in a BTree? +pub struct BTree{ + root: Node, + len: uint, + lower_bound: uint, + upper_bound: uint +} + + +impl BTree{ + + //Returns new BTree with root node (leaf) and user-supplied lower bound + fn new(k: K, v: V, lb: uint) -> BTree{ + BTree{ + root: Node::new_leaf(~[LeafElt::new(k, v)]), + len: 1, + lower_bound: lb, + upper_bound: 2 * lb + } + } + + //Helper function for clone + fn new_with_node_len(n: Node, length: uint, lb: uint) -> BTree{ + BTree{ + root: n, + len: length, + lower_bound: lb, + upper_bound: 2 * lb + } + } + + + fn clone(&self) -> BTree{ + return BTree::new_with_node_len(self.root.clone(), self.len, self.lower_bound); + } + + fn get(self, k: K) -> Option{ + return self.root.get(k); + } + + + fn add(self, k: K, v: V) -> bool{ + let is_get = &self.clone().get(k.clone()); + if is_get.is_some(){ return false; } + else{ + std::util::replace(&mut self.root.clone(),self.root.add(k.clone(), v)); + return true; + } + + } + + + +} + +impl ToStr for BTree{ + //Returns a string representation of the BTree + fn to_str(&self) -> ~str{ + let ret=self.root.to_str(); + return ret; + } +} + + +//Node types +enum Node{ + LeafNode(Leaf), + BranchNode(Branch) +} + + +//Node functions/methods +impl Node{ + //differentiates between leaf and branch nodes + fn is_leaf(&self) -> bool{ + match self{ + &LeafNode(*) => true, + &BranchNode(*) => false + } + } + + //Creates a new leaf or branch node + fn new_leaf(vec: ~[LeafElt]) -> Node{ + LeafNode(Leaf::new(vec)) + } + fn new_branch(vec: ~[BranchElt], right: ~Node) -> Node{ + BranchNode(Branch::new(vec, right)) + } + + fn get(&self, k: K) -> Option{ + match *self{ + LeafNode(ref leaf) => return leaf.get(k), + BranchNode(ref branch) => return branch.get(k) + } + } + + //A placeholder for add + //Currently returns a leaf node with a single value (the added one) + fn add(self, k: K, v: V) -> Node{ + return Node::new_leaf(~[LeafElt::new(k, v)]); + } +} + + +impl Clone for Node{ + fn clone(&self) -> Node{ + match *self{ + LeafNode(ref leaf) => return Node::new_leaf(leaf.elts.clone()), + BranchNode(ref branch) => return Node::new_branch(branch.elts.clone(), branch.rightmost_child.clone()) + } + } +} + +impl TotalOrd for Node{ + #[allow(unused_variable)] + fn cmp(&self, other: &Node) -> Ordering{ + //Requires a match statement--defer these procs to branch and leaf. + /* if self.elts[0].less_than(other.elts[0]) { return Less} + if self.elts[0].greater_than(other.elts[0]) {return Greater} + else {return Equal} + */ + return Equal; + } +} + +impl TotalEq for Node{ + //Making sure Nodes have TotalEq + #[allow(unused_variable)] + fn equals(&self, other: &Node) -> bool{ + /* put in a match and defer this stuff to branch and leaf + + let mut shorter = 0; + if self.elts.len() <= other.elts.len(){ + shorter = self.elts.len(); + } + else{ + shorter = other.elts.len(); + } + let mut i = 0; + while i < shorter{ + if !self.elts[i].has_key(other.elts[i].key){ + return false; + } + i +=1; + } + return true; + */ + return true; + } +} + + +impl ToStr for Node{ + fn to_str(&self) -> ~str{ + match *self{ + LeafNode(ref leaf) => leaf.to_str(), + BranchNode(*) => ~"" + } + } +} + + +//Array with no children +struct Leaf{ + elts: ~[LeafElt] +} + +//Array of values with children, plus a rightmost child (greater than all) +struct Branch{ + elts: ~[BranchElt], + rightmost_child: ~Node +} + + +impl Leaf{ + //Constructor takes in a vector of leaves + fn new(vec: ~[LeafElt]) -> Leaf{ + Leaf{ + elts: vec + } + } + + + fn get(&self, k: K) -> Option{ + for s in self.elts.iter(){ + let order=s.key.cmp(&k); + match order{ + Equal => return Some(s.value.clone()), + _ => {} + } + } + return None; + } + + //Add method in progress + fn add(&self, k: K, v: V) -> Node{ + return Node::new_leaf(~[LeafElt::new(k, v)]); + } + +} + +impl ToStr for Leaf{ + fn to_str(&self) -> ~str{ + let mut ret=~""; + for s in self.elts.iter(){ + ret = ret+" // "+ s.to_str(); + } + return ret; + } + +} + + +impl Branch{ + //constructor takes a branch vector and a rightmost child + fn new(vec: ~[BranchElt], right: ~Node) -> Branch{ + Branch{ + elts: vec, + rightmost_child: right + } + } + + fn get(&self, k: K) -> Option{ + for s in self.elts.iter(){ + let order = s.key.cmp(&k); + match order{ + Less => return s.left.get(k), + Equal => return Some(s.value.clone()), + _ => {} + } + } + return self.rightmost_child.get(k); + } + + + //Add method in progress + fn add(&self, k: K, v: V) -> Node{ + return Node::new_leaf(~[LeafElt::new(k, v)]); + } +} + +//No left child +struct LeafElt{ + key: K, + value: V +} + +//Has a left child +struct BranchElt{ + left: Node, + key: K, + value: V +} + +impl LeafElt{ + fn new(k: K, v: V) -> LeafElt{ + LeafElt{ + key: k, + value: v + } + } + + fn less_than(&self, other: LeafElt) -> bool{ + let order = self.key.cmp(&other.key); + match order{ + Less => true, + _ => false + } + } + + fn greater_than(&self, other: LeafElt) -> bool{ + let order = self.key.cmp(&other.key); + match order{ + Greater => true, + _ => false + } + } + + + fn has_key(&self, other: K) -> bool{ + let order = self.key.cmp(&other); + match order{ + Equal => true, + _ => false + } + } + +} + +impl Clone for LeafElt{ + fn clone(&self) -> LeafElt{ + return LeafElt::new(self.key.clone(), self.value.clone()); + } +} + +impl ToStr for LeafElt{ + fn to_str(&self) -> ~str{ + return "Key: "+self.key.to_str()+", value: "+self.value.to_str()+"; "; + } + +} + +impl BranchElt{ + fn new(k: K, v: V, n: Node) -> BranchElt{ + BranchElt{ + left: n, + key: k, + value: v + } + } + + //Add method in progress. Should it return a branch or a leaf elt? It will depend on implementation. + fn add(&self, k: K, v: V) -> LeafElt{ + return LeafElt::new(k, v); + } +} + +impl Clone for BranchElt{ + fn clone(&self) -> BranchElt{ + return BranchElt::new(self.key.clone(), self.value.clone(), self.left.clone()); + } +} + +#[test] +fn add_test(){ + let b = BTree::new(1, ~"abc", 2); + let is_add = b.add(2, ~"xyz"); + assert!(is_add); + +} + +#[test] +fn get_test(){ + let b = BTree::new(1, ~"abc", 2); + let val = b.get(1); + assert_eq!(val, Some(~"abc")); +} + +//Testing LeafElt functions (less_than, greater_than, and has_key) +#[test] +fn leaf_lt(){ + let l1 = LeafElt::new(1, ~"abc"); + let l2 = LeafElt::new(2, ~"xyz"); + assert!(l1.less_than(l2)); +} + +#[test] +fn leaf_gt(){ + let l1 = LeafElt::new(1, ~"abc"); + let l2 = LeafElt::new(2, ~"xyz"); + assert!(l2.greater_than(l1)); +} + +#[test] +fn leaf_hk(){ + let l1 = LeafElt::new(1, ~"abc"); + assert!(l1.has_key(1)); +} + +fn main(){ + + +} From 058d785369e3fc27f7f67b9ea019dae68603f4af Mon Sep 17 00:00:00 2001 From: niftynif Date: Tue, 5 Nov 2013 19:44:21 -0500 Subject: [PATCH 2/4] Re-arranging some things in btree.rs to accommodate testing. --- src/libextra/btree.rs | 234 ++++++++++++++++++++++-------------------- 1 file changed, 123 insertions(+), 111 deletions(-) diff --git a/src/libextra/btree.rs b/src/libextra/btree.rs index 5a4892a2391..2c594842c07 100644 --- a/src/libextra/btree.rs +++ b/src/libextra/btree.rs @@ -1,3 +1,13 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + // // btree.rs // Nif Ward @@ -17,25 +27,25 @@ pub struct BTree{ impl BTree{ - + //Returns new BTree with root node (leaf) and user-supplied lower bound fn new(k: K, v: V, lb: uint) -> BTree{ BTree{ - root: Node::new_leaf(~[LeafElt::new(k, v)]), - len: 1, - lower_bound: lb, - upper_bound: 2 * lb + root: Node::new_leaf(~[LeafElt::new(k, v)]), + len: 1, + lower_bound: lb, + upper_bound: 2 * lb } } //Helper function for clone fn new_with_node_len(n: Node, length: uint, lb: uint) -> BTree{ BTree{ - root: n, - len: length, - lower_bound: lb, - upper_bound: 2 * lb - } + root: n, + len: length, + lower_bound: lb, + upper_bound: 2 * lb + } } @@ -50,11 +60,11 @@ impl BTree{ fn add(self, k: K, v: V) -> bool{ let is_get = &self.clone().get(k.clone()); - if is_get.is_some(){ return false; } - else{ - std::util::replace(&mut self.root.clone(),self.root.add(k.clone(), v)); - return true; - } + if is_get.is_some(){ return false; } + else{ + std::util::replace(&mut self.root.clone(),self.root.add(k.clone(), v)); + return true; + } } @@ -66,7 +76,7 @@ impl ToStr for BTree{ //Returns a string representation of the BTree fn to_str(&self) -> ~str{ let ret=self.root.to_str(); - return ret; + return ret; } } @@ -83,11 +93,11 @@ impl Node{ //differentiates between leaf and branch nodes fn is_leaf(&self) -> bool{ match self{ - &LeafNode(*) => true, - &BranchNode(*) => false + &LeafNode(*) => true, + &BranchNode(*) => false } } - + //Creates a new leaf or branch node fn new_leaf(vec: ~[LeafElt]) -> Node{ LeafNode(Leaf::new(vec)) @@ -98,8 +108,8 @@ impl Node{ fn get(&self, k: K) -> Option{ match *self{ - LeafNode(ref leaf) => return leaf.get(k), - BranchNode(ref branch) => return branch.get(k) + LeafNode(ref leaf) => return leaf.get(k), + BranchNode(ref branch) => return branch.get(k) } } @@ -114,9 +124,10 @@ impl Node{ impl Clone for Node{ fn clone(&self) -> Node{ match *self{ - LeafNode(ref leaf) => return Node::new_leaf(leaf.elts.clone()), - BranchNode(ref branch) => return Node::new_branch(branch.elts.clone(), branch.rightmost_child.clone()) - } + LeafNode(ref leaf) => return Node::new_leaf(leaf.elts.clone()), + BranchNode(ref branch) => return Node::new_branch(branch.elts.clone(), + branch.rightmost_child.clone()) + } } } @@ -125,10 +136,10 @@ impl TotalOrd for Node{ fn cmp(&self, other: &Node) -> Ordering{ //Requires a match statement--defer these procs to branch and leaf. /* if self.elts[0].less_than(other.elts[0]) { return Less} - if self.elts[0].greater_than(other.elts[0]) {return Greater} - else {return Equal} - */ - return Equal; + if self.elts[0].greater_than(other.elts[0]) {return Greater} + else {return Equal} + */ + return Equal; } } @@ -140,19 +151,19 @@ impl TotalEq for Node{ let mut shorter = 0; if self.elts.len() <= other.elts.len(){ - shorter = self.elts.len(); - } - else{ - shorter = other.elts.len(); - } - let mut i = 0; - while i < shorter{ - if !self.elts[i].has_key(other.elts[i].key){ - return false; - } - i +=1; + shorter = self.elts.len(); } - return true; + else{ + shorter = other.elts.len(); + } + let mut i = 0; + while i < shorter{ + if !self.elts[i].has_key(other.elts[i].key){ + return false; + } + i +=1; + } + return true; */ return true; } @@ -163,7 +174,7 @@ impl ToStr for Node{ fn to_str(&self) -> ~str{ match *self{ LeafNode(ref leaf) => leaf.to_str(), - BranchNode(*) => ~"" + BranchNode(*) => ~"" } } } @@ -192,13 +203,13 @@ impl Leaf{ fn get(&self, k: K) -> Option{ for s in self.elts.iter(){ - let order=s.key.cmp(&k); - match order{ - Equal => return Some(s.value.clone()), - _ => {} - } - } - return None; + let order=s.key.cmp(&k); + match order{ + Equal => return Some(s.value.clone()), + _ => {} + } + } + return None; } //Add method in progress @@ -224,22 +235,22 @@ impl Branch{ //constructor takes a branch vector and a rightmost child fn new(vec: ~[BranchElt], right: ~Node) -> Branch{ Branch{ - elts: vec, - rightmost_child: right + elts: vec, + rightmost_child: right } } fn get(&self, k: K) -> Option{ for s in self.elts.iter(){ - let order = s.key.cmp(&k); - match order{ - Less => return s.left.get(k), - Equal => return Some(s.value.clone()), - _ => {} - } - } - return self.rightmost_child.get(k); - } + let order = s.key.cmp(&k); + match order{ + Less => return s.left.get(k), + Equal => return Some(s.value.clone()), + _ => {} + } + } + return self.rightmost_child.get(k); + } //Add method in progress @@ -265,33 +276,33 @@ impl LeafElt{ fn new(k: K, v: V) -> LeafElt{ LeafElt{ key: k, - value: v - } + value: v + } } fn less_than(&self, other: LeafElt) -> bool{ let order = self.key.cmp(&other.key); - match order{ - Less => true, - _ => false - } + match order{ + Less => true, + _ => false + } } fn greater_than(&self, other: LeafElt) -> bool{ let order = self.key.cmp(&other.key); - match order{ - Greater => true, - _ => false - } + match order{ + Greater => true, + _ => false + } } fn has_key(&self, other: K) -> bool{ let order = self.key.cmp(&other); - match order{ - Equal => true, - _ => false - } + match order{ + Equal => true, + _ => false + } } } @@ -318,7 +329,7 @@ impl BranchElt{ } } - //Add method in progress. Should it return a branch or a leaf elt? It will depend on implementation. + //Add method in progress. Should it return a branch or a leaf elt? fn add(&self, k: K, v: V) -> LeafElt{ return LeafElt::new(k, v); } @@ -330,43 +341,44 @@ impl Clone for BranchElt{ } } -#[test] -fn add_test(){ - let b = BTree::new(1, ~"abc", 2); - let is_add = b.add(2, ~"xyz"); - assert!(is_add); +#[cfg(test)] +mod test_btree{ + use super::*; + + #[test] + fn add_test(){ + let b = BTree::new(1, ~"abc", 2); + let is_add = b.add(2, ~"xyz"); + assert!(is_add); + } + + #[test] + fn get_test(){ + let b = BTree::new(1, ~"abc", 2); + let val = b.get(1); + assert_eq!(val, Some(~"abc")); + } + + //Testing LeafElt functions (less_than, greater_than, and has_key) + #[test] + fn leaf_lt(){ + let l1 = LeafElt::new(1, ~"abc"); + let l2 = LeafElt::new(2, ~"xyz"); + assert!(l1.less_than(l2)); + } + + #[test] + fn leaf_gt(){ + let l1 = LeafElt::new(1, ~"abc"); + let l2 = LeafElt::new(2, ~"xyz"); + assert!(l2.greater_than(l1)); + } + + #[test] + fn leaf_hk(){ + let l1 = LeafElt::new(1, ~"abc"); + assert!(l1.has_key(1)); + } } -#[test] -fn get_test(){ - let b = BTree::new(1, ~"abc", 2); - let val = b.get(1); - assert_eq!(val, Some(~"abc")); -} - -//Testing LeafElt functions (less_than, greater_than, and has_key) -#[test] -fn leaf_lt(){ - let l1 = LeafElt::new(1, ~"abc"); - let l2 = LeafElt::new(2, ~"xyz"); - assert!(l1.less_than(l2)); -} - -#[test] -fn leaf_gt(){ - let l1 = LeafElt::new(1, ~"abc"); - let l2 = LeafElt::new(2, ~"xyz"); - assert!(l2.greater_than(l1)); -} - -#[test] -fn leaf_hk(){ - let l1 = LeafElt::new(1, ~"abc"); - assert!(l1.has_key(1)); -} - -fn main(){ - - -} From fbde419b38ab988a01833c443905ef65f3055791 Mon Sep 17 00:00:00 2001 From: niftynif Date: Thu, 7 Nov 2013 13:34:20 -0500 Subject: [PATCH 3/4] Addressed style concerns in btree.rs and added it to the lib file. Added documentation within btree.rs. --- src/libextra/btree.rs | 184 ++++++++++++++++++++++++++++-------------- src/libextra/lib.rs | 1 + 2 files changed, 125 insertions(+), 60 deletions(-) diff --git a/src/libextra/btree.rs b/src/libextra/btree.rs index 2c594842c07..e3382cb6c19 100644 --- a/src/libextra/btree.rs +++ b/src/libextra/btree.rs @@ -7,17 +7,20 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. - // // btree.rs -// Nif Ward -// 10/24/13 // // starting implementation of a btree for rust // inspired by github user davidhalperin's gist -//What's in a BTree? +use std::util::replace; + + +///A B-tree contains a root node (which contains a vector of elements), +///a length (the height of the tree), and lower and upper bounds on the +///number of elements that a given node can contain. +#[allow(missing_doc)] pub struct BTree{ root: Node, len: uint, @@ -25,10 +28,14 @@ pub struct BTree{ upper_bound: uint } - +//We would probably want to remove the dependence on the Clone trait in the future. +//It is here as a crutch to ensure values can be passed around through the tree's nodes +//especially during insertions and deletions. +//Using the swap or replace methods is one option for replacing dependence on Clone, or +//changing the way in which the BTree is stored could also potentially work. impl BTree{ - //Returns new BTree with root node (leaf) and user-supplied lower bound + ///Returns new BTree with root node (leaf) and user-supplied lower bound fn new(k: K, v: V, lb: uint) -> BTree{ BTree{ root: Node::new_leaf(~[LeafElt::new(k, v)]), @@ -38,7 +45,8 @@ impl BTree{ } } - //Helper function for clone + ///Helper function for clone: returns new BTree with supplied root node, + ///length, and lower bound. For use when the length is known already. fn new_with_node_len(n: Node, length: uint, lb: uint) -> BTree{ BTree{ root: n, @@ -48,21 +56,25 @@ impl BTree{ } } - + ///Implements the Clone trait for the BTree. + ///Uses a helper function/constructor to produce a new BTree. fn clone(&self) -> BTree{ return BTree::new_with_node_len(self.root.clone(), self.len, self.lower_bound); } + ///Returns the value of a given key, which may not exist in the tree. + ///Calls the root node's get method. fn get(self, k: K) -> Option{ return self.root.get(k); } - + ///Checks to see if the key already exists in the tree, and if it is not, + ///the key-value pair is added to the tree by calling add on the root node. fn add(self, k: K, v: V) -> bool{ let is_get = &self.clone().get(k.clone()); if is_get.is_some(){ return false; } else{ - std::util::replace(&mut self.root.clone(),self.root.add(k.clone(), v)); + replace(&mut self.root.clone(),self.root.add(k.clone(), v)); return true; } @@ -73,15 +85,19 @@ impl BTree{ } impl ToStr for BTree{ - //Returns a string representation of the BTree + ///Returns a string representation of the BTree fn to_str(&self) -> ~str{ - let ret=self.root.to_str(); - return ret; + let ret = self.root.to_str(); + ret } } //Node types +//A node is either a LeafNode or a BranchNode, which contain either a Leaf or a Branch. +//Branches contain BranchElts, which contain a left child (another node) and a key-value +//pair. Branches also contain the rightmost child of the elements in the array. +//Leaves contain LeafElts, which do not have children. enum Node{ LeafNode(Leaf), BranchNode(Branch) @@ -90,7 +106,8 @@ enum Node{ //Node functions/methods impl Node{ - //differentiates between leaf and branch nodes + + ///Differentiates between leaf and branch nodes. fn is_leaf(&self) -> bool{ match self{ &LeafNode(*) => true, @@ -98,14 +115,19 @@ impl Node{ } } - //Creates a new leaf or branch node + ///Creates a new leaf node given a vector of elements. fn new_leaf(vec: ~[LeafElt]) -> Node{ - LeafNode(Leaf::new(vec)) + LeafNode(Leaf::new(vec)) } + + ///Creates a new branch node given a vector of an elements and a pointer to a rightmost child. fn new_branch(vec: ~[BranchElt], right: ~Node) -> Node{ BranchNode(Branch::new(vec, right)) } + + ///Returns the corresponding value to the provided key. + ///get() is called in different ways on a branch or a leaf. fn get(&self, k: K) -> Option{ match *self{ LeafNode(ref leaf) => return leaf.get(k), @@ -113,79 +135,91 @@ impl Node{ } } - //A placeholder for add - //Currently returns a leaf node with a single value (the added one) + ///A placeholder for add + ///Currently returns a leaf node with a single value (the added one) fn add(self, k: K, v: V) -> Node{ return Node::new_leaf(~[LeafElt::new(k, v)]); } } - +//Again, this might not be necessary in the future. impl Clone for Node{ + + ///Returns a new node based on whether or not it is a branch or a leaf. fn clone(&self) -> Node{ match *self{ LeafNode(ref leaf) => return Node::new_leaf(leaf.elts.clone()), BranchNode(ref branch) => return Node::new_branch(branch.elts.clone(), - branch.rightmost_child.clone()) + branch.rightmost_child.clone()) } } } +//The following impl is unfinished. Old iterations of code are left in for +//future reference when implementing this trait (commented-out). impl TotalOrd for Node{ + + ///Placeholder for an implementation of TotalOrd for Nodes. #[allow(unused_variable)] fn cmp(&self, other: &Node) -> Ordering{ //Requires a match statement--defer these procs to branch and leaf. /* if self.elts[0].less_than(other.elts[0]) { return Less} if self.elts[0].greater_than(other.elts[0]) {return Greater} - else {return Equal} - */ + else {return Equal} + */ return Equal; } } +//The following impl is unfinished. Old iterations of code are left in for +//future reference when implementing this trait (commented-out). impl TotalEq for Node{ - //Making sure Nodes have TotalEq + + ///Placeholder for an implementation of TotalEq for Nodes. #[allow(unused_variable)] fn equals(&self, other: &Node) -> bool{ - /* put in a match and defer this stuff to branch and leaf + /* put in a match and defer this stuff to branch and leaf let mut shorter = 0; if self.elts.len() <= other.elts.len(){ - shorter = self.elts.len(); - } - else{ - shorter = other.elts.len(); - } + shorter = self.elts.len(); + } + else{ + shorter = other.elts.len(); + } let mut i = 0; while i < shorter{ - if !self.elts[i].has_key(other.elts[i].key){ - return false; - } - i +=1; - } + if !self.elts[i].has_key(other.elts[i].key){ + return false; + } + i +=1; + } + return true; + */ return true; - */ - return true; } } impl ToStr for Node{ + ///Returns a string representation of a Node. + ///The Branch's to_str() is not implemented yet. fn to_str(&self) -> ~str{ - match *self{ - LeafNode(ref leaf) => leaf.to_str(), - BranchNode(*) => ~"" - } + match *self{ + LeafNode(ref leaf) => leaf.to_str(), + BranchNode(*) => ~"" + } } } -//Array with no children +//A leaf is a vector with elements that contain no children. A leaf also +//does not contain a rightmost child. struct Leaf{ elts: ~[LeafElt] } -//Array of values with children, plus a rightmost child (greater than all) +//Vector of values with children, plus a rightmost child (greater than all) struct Branch{ elts: ~[BranchElt], rightmost_child: ~Node @@ -193,17 +227,18 @@ struct Branch{ impl Leaf{ - //Constructor takes in a vector of leaves + + ///Creates a new Leaf from a vector of LeafElts. fn new(vec: ~[LeafElt]) -> Leaf{ Leaf{ elts: vec } } - + ///Returns the corresponding value to the supplied key. fn get(&self, k: K) -> Option{ for s in self.elts.iter(){ - let order=s.key.cmp(&k); + let order = s.key.cmp(&k); match order{ Equal => return Some(s.value.clone()), _ => {} @@ -212,7 +247,8 @@ impl Leaf{ return None; } - //Add method in progress + ///Placeholder for add method in progress. + ///Currently returns a new Leaf containing a single LeafElt. fn add(&self, k: K, v: V) -> Node{ return Node::new_leaf(~[LeafElt::new(k, v)]); } @@ -220,19 +256,22 @@ impl Leaf{ } impl ToStr for Leaf{ + + ///Returns a string representation of a Leaf. fn to_str(&self) -> ~str{ - let mut ret=~""; - for s in self.elts.iter(){ - ret = ret+" // "+ s.to_str(); - } - return ret; + let mut ret = ~""; + for s in self.elts.iter(){ + ret = ret + " // " + s.to_str(); + } + ret } } impl Branch{ - //constructor takes a branch vector and a rightmost child + + ///Creates a new Branch from a vector of BranchElts and a rightmost child (a node). fn new(vec: ~[BranchElt], right: ~Node) -> Branch{ Branch{ elts: vec, @@ -240,6 +279,8 @@ impl Branch{ } } + ///Returns the corresponding value to the supplied key. + ///If the key is not there, find the child that might hold it. fn get(&self, k: K) -> Option{ for s in self.elts.iter(){ let order = s.key.cmp(&k); @@ -250,22 +291,22 @@ impl Branch{ } } return self.rightmost_child.get(k); - } + } - //Add method in progress + ///Placeholder for add method in progress fn add(&self, k: K, v: V) -> Node{ return Node::new_leaf(~[LeafElt::new(k, v)]); } } -//No left child +//A LeafElt containts no left child, but a key-value pair. struct LeafElt{ key: K, value: V } -//Has a left child +//A BranchElt has a left child in addition to a key-value pair. struct BranchElt{ left: Node, key: K, @@ -273,6 +314,8 @@ struct BranchElt{ } impl LeafElt{ + + ///Creates a new LeafElt from a supplied key-value pair. fn new(k: K, v: V) -> LeafElt{ LeafElt{ key: k, @@ -280,6 +323,8 @@ impl LeafElt{ } } + ///Compares another LeafElt against itself and determines whether + ///the original LeafElt's key is less than the other one's key. fn less_than(&self, other: LeafElt) -> bool{ let order = self.key.cmp(&other.key); match order{ @@ -288,6 +333,8 @@ impl LeafElt{ } } + ///Compares another LeafElt against itself and determines whether + ///the original LeafElt's key is greater than the other one's key. fn greater_than(&self, other: LeafElt) -> bool{ let order = self.key.cmp(&other.key); match order{ @@ -296,7 +343,8 @@ impl LeafElt{ } } - + ///Takes a key and determines whether its own key and the supplied key + ///are the same. fn has_key(&self, other: K) -> bool{ let order = self.key.cmp(&other); match order{ @@ -307,20 +355,28 @@ impl LeafElt{ } +//This may be eliminated in the future to perserve efficiency by adjusting the way +//the BTree as a whole is stored in memory. impl Clone for LeafElt{ + + ///Returns a new LeafElt by cloning the key and value. fn clone(&self) -> LeafElt{ return LeafElt::new(self.key.clone(), self.value.clone()); } } impl ToStr for LeafElt{ + + ///Returns a string representation of a LeafElt. fn to_str(&self) -> ~str{ - return "Key: "+self.key.to_str()+", value: "+self.value.to_str()+"; "; + return "Key: " + self.key.to_str() + ", value: "+ self.value.to_str() + "; "; } } impl BranchElt{ + + ///Creates a new BranchElt from a supplied key, value, and left child. fn new(k: K, v: V, n: Node) -> BranchElt{ BranchElt{ left: n, @@ -329,13 +385,16 @@ impl BranchElt{ } } - //Add method in progress. Should it return a branch or a leaf elt? + ///Placeholder for add method in progress. + ///Overall implementation will determine the actual return value of this method. fn add(&self, k: K, v: V) -> LeafElt{ return LeafElt::new(k, v); } } impl Clone for BranchElt{ + + ///Returns a new BranchElt by cloning the key, value, and left child. fn clone(&self) -> BranchElt{ return BranchElt::new(self.key.clone(), self.value.clone(), self.left.clone()); } @@ -346,6 +405,7 @@ mod test_btree{ use super::*; + ///Tests the functionality of the add methods (which are unfinished). #[test] fn add_test(){ let b = BTree::new(1, ~"abc", 2); @@ -353,6 +413,7 @@ mod test_btree{ assert!(is_add); } + ///Tests the functionality of the get method. #[test] fn get_test(){ let b = BTree::new(1, ~"abc", 2); @@ -360,7 +421,7 @@ mod test_btree{ assert_eq!(val, Some(~"abc")); } - //Testing LeafElt functions (less_than, greater_than, and has_key) + ///Tests the LeafElt's less_than() method. #[test] fn leaf_lt(){ let l1 = LeafElt::new(1, ~"abc"); @@ -368,6 +429,8 @@ mod test_btree{ assert!(l1.less_than(l2)); } + + ///Tests the LeafElt's greater_than() method. #[test] fn leaf_gt(){ let l1 = LeafElt::new(1, ~"abc"); @@ -375,6 +438,7 @@ mod test_btree{ assert!(l2.greater_than(l1)); } + ///Tests the LeafElt's has_key() method. #[test] fn leaf_hk(){ let l1 = LeafElt::new(1, ~"abc"); diff --git a/src/libextra/lib.rs b/src/libextra/lib.rs index 2ac12373794..8bb99617274 100644 --- a/src/libextra/lib.rs +++ b/src/libextra/lib.rs @@ -67,6 +67,7 @@ pub mod sort; pub mod dlist; pub mod treemap; +pub mod btree; // And ... other stuff From 2f1b4335cbb2673996c5331b2a69b209e2e673cd Mon Sep 17 00:00:00 2001 From: niftynif Date: Fri, 8 Nov 2013 02:41:09 -0500 Subject: [PATCH 4/4] Added proper //! documentation to the beginning of btree.rs. --- src/libextra/btree.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libextra/btree.rs b/src/libextra/btree.rs index e3382cb6c19..d650769d70f 100644 --- a/src/libextra/btree.rs +++ b/src/libextra/btree.rs @@ -10,8 +10,9 @@ // // btree.rs // -// starting implementation of a btree for rust -// inspired by github user davidhalperin's gist + +//! Starting implementation of a btree for rust. +//! Structure inspired by github user davidhalperin's gist. use std::util::replace;