From 55a10cf853e6eca1de68a895782fd43fe508a839 Mon Sep 17 00:00:00 2001 From: Nif Ward Date: Mon, 16 Dec 2013 13:23:09 -0500 Subject: [PATCH 1/2] Committing standard compare/to_str/clone features, but no tests yet. Wrote some tests for the compare/clone/to_str methods. Took out doc comments around tests. Don't allow impls to force public types This code in resolve accidentally forced all types with an impl to become public. This fixes it by default inheriting the privacy of what was previously there and then becoming `true` if nothing else exits. Closes #10545 Committing to show work in progress. Everything is still messy, but I want to take this opportunity to get feedback from relevant parties if I can. Recommitting after a bad commit that unnecessarily changed files. --- src/libextra/btree.rs | 374 +++++++++++++++++++++++++++++++++--------- 1 file changed, 296 insertions(+), 78 deletions(-) diff --git a/src/libextra/btree.rs b/src/libextra/btree.rs index 0f9eba2e9dcd4..eb71185a0d719 100644 --- a/src/libextra/btree.rs +++ b/src/libextra/btree.rs @@ -14,8 +14,10 @@ //! Starting implementation of a btree for rust. //! Structure inspired by github user davidhalperin's gist. + +#[allow(attribute_usage)]; +#[feature(globs)]; #[allow(dead_code)]; -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 @@ -33,7 +35,7 @@ pub struct BTree { //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 { +impl BTree { ///Returns new BTree with root node (leaf) and user-supplied lower bound pub fn new(k: K, v: V, lb: uint) -> BTree { @@ -58,27 +60,43 @@ impl BTree { } } - ///Implements the Clone trait for the BTree. - ///Uses a helper function/constructor to produce a new BTree. - pub fn clone(&self) -> BTree { - return BTree::new_with_node_len(self.root.clone(), self.len, self.lower_bound); + + ///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. + pub fn add(self, k: K, v: V) -> BTree { + //replace(&self.root,self.root.add(k, v)); + return BTree::new(k, v, 2); } +} +impl BTree { ///Returns the value of a given key, which may not exist in the tree. ///Calls the root node's get method. pub 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. - pub fn add(self, k: K, v: V) -> bool { - let is_get = &self.clone().get(k.clone()); - if is_get.is_some(){ return false; } - else { - replace(&mut self.root.clone(),self.root.add(k.clone(), v)); - return true; - } +impl Clone for BTree{ + ///Implements the Clone trait for the BTree. + ///Uses a helper function/constructor to produce a new BTree. + fn clone(&self) -> BTree { + BTree::new_with_node_len(self.root.clone(), self.len, self.lower_bound) + } +} + +impl TotalOrd for BTree { + ///Returns an ordering based on the root nodes of each BTree. + fn cmp(&self, other: &BTree) -> Ordering { + self.root.cmp(&other.root) + } +} + +impl TotalEq for BTree { + + ///Testing equality on BTrees by comparing the root. + fn equals(&self, other: &BTree) -> bool { + self.root.cmp(&other.root) == Equal } } @@ -96,6 +114,7 @@ impl ToStr for BTree { //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. +//#[deriving(Eq, TotalEq)] enum Node { LeafNode(Leaf), BranchNode(Branch) @@ -103,7 +122,7 @@ enum Node { //Node functions/methods -impl Node { +impl Node { ///Differentiates between leaf and branch nodes. fn is_leaf(&self) -> bool{ @@ -118,11 +137,20 @@ impl Node { 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)) } + ///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 Node{ ///Returns the corresponding value to the provided key. ///get() is called in different ways on a branch or a leaf. @@ -132,15 +160,8 @@ impl Node { 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)]); - } } -//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. @@ -157,49 +178,61 @@ impl Clone for Node { } } -//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 { +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} - */ - return Equal; + match *self{ + LeafNode(ref leaf) => { + match *other{ + LeafNode(ref leaf2) => { + return leaf.cmp(leaf2); + } + BranchNode(ref branch) => { + return Less; + } + } + } + + BranchNode(ref branch) => { + match *other{ + BranchNode(ref branch2) => { + return branch.cmp(branch2); + } + LeafNode(ref leaf) => { + return Greater; + } + } + } + } } -} -//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 { +} - ///Placeholder for an implementation of TotalEq for Nodes. +impl TotalEq for Node{ + ///Returns whether two nodes are equal #[allow(unused_variable)] - fn equals(&self, other: &Node) -> bool { - /* put in a match and defer this stuff to branch and leaf + fn equals(&self, other: &Node) -> bool{ + match *self{ + BranchNode(ref branch) => { + match *other{ + BranchNode(ref branch2) => branch.cmp(branch2) == Equal, + LeafNode(ref leaf) => false + } + } + + LeafNode(ref leaf) => { + match *other{ + LeafNode(ref leaf2) => leaf.cmp(leaf2) == Equal, + BranchNode(ref branch) => false + } + } + + } - 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; } + } @@ -209,7 +242,7 @@ impl ToStr for Node { fn to_str(&self) -> ~str { match *self { LeafNode(ref leaf) => leaf.to_str(), - BranchNode(..) => ~"" + BranchNode(ref branch) => branch.to_str() } } } @@ -217,18 +250,20 @@ impl ToStr for Node { //A leaf is a vector with elements that contain no children. A leaf also //does not contain a rightmost child. +//#[deriving(Eq, TotalEq)] struct Leaf { elts: ~[LeafElt] } //Vector of values with children, plus a rightmost child (greater than all) +//#[deriving(Eq, TotalEq)] struct Branch { elts: ~[BranchElt], rightmost_child: ~Node } -impl Leaf { +impl Leaf { ///Creates a new Leaf from a vector of LeafElts. fn new(vec: ~[LeafElt]) -> Leaf { @@ -237,6 +272,17 @@ impl Leaf { } } + + + ///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)]); + } + +} + +impl Leaf { ///Returns the corresponding value to the supplied key. fn get(&self, k: K) -> Option { for s in self.elts.iter() { @@ -248,13 +294,21 @@ impl Leaf { } return None; } +} - ///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)]); +impl TotalOrd for Leaf{ + ///Returns an ordering based on the first element of each Leaf. + fn cmp(&self, other: &Leaf) -> Ordering{ + self.elts[0].cmp(&other.elts[0]) } +} + +impl Clone for Leaf{ + ///Returns a new Leaf with the same elts. + fn clone(&self) -> Leaf{ + Leaf::new(self.elts.clone()) + } } impl ToStr for Leaf { @@ -267,11 +321,22 @@ impl ToStr for Leaf { } ret } +} +impl TotalEq for Leaf { + + ///Implementation of equals function for leaves, uses LeafElts' traits. + ///Placeholder implementation. + fn equals(&self, other: &Leaf) -> bool { + if self.elts[0].equals(&other.elts[0]) { + return true; + } + return false; + } } -impl Branch { +impl Branch { ///Creates a new Branch from a vector of BranchElts and a rightmost child (a node). fn new(vec: ~[BranchElt], right: ~Node) -> Branch { @@ -281,6 +346,14 @@ impl Branch { } } + + ///Placeholder for add method in progress + fn add(&self, k: K, v: V) -> Node { + return Node::new_leaf(~[LeafElt::new(k, v)]); + } +} + +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 { @@ -294,28 +367,64 @@ impl Branch { } return self.rightmost_child.get(k); } +} +impl TotalOrd for Branch{ + ///Compares the first elements of two branches to determine an ordering + fn cmp(&self, other: &Branch) -> Ordering{ + self.elts[0].cmp(&other.elts[0]) + } +} - ///Placeholder for add method in progress - fn add(&self, k: K, v: V) -> Node { - return Node::new_leaf(~[LeafElt::new(k, v)]); +impl Clone for Branch{ + + ///Returns a new branch using the clone methods of the Branch's internal variables. + fn clone(&self) -> Branch{ + Branch::new(self.elts.clone(), self.rightmost_child.clone()) } } +impl TotalEq for Branch{ + + ///Equals function for Branches--compares first elt (Placeholder) + fn equals(&self, other: &Branch) -> bool { + if self.elts[0].equals(&other.elts[0]){ + return true; + } + return false; + } +} + +impl ToStr for Branch { + + ///Returns a string representation of a Branch. + fn to_str(&self) -> ~str { + let mut ret = ~""; + for s in self.elts.iter() { + ret = ret + " // " + s.to_str(); + } + ret = ret + " // " + self.rightmost_child.to_str(); + ret + } + +} + //A LeafElt containts no left child, but a key-value pair. +//#[deriving(Eq)] struct LeafElt { key: K, value: V } //A BranchElt has a left child in addition to a key-value pair. +//#[deriving(Eq, TotalEq)] struct BranchElt { left: Node, key: K, value: V } -impl LeafElt { +impl LeafElt { ///Creates a new LeafElt from a supplied key-value pair. fn new(k: K, v: V) -> LeafElt { @@ -356,8 +465,16 @@ 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 TotalOrd for LeafElt { + + ///Returns an ordering based on the keys of the LeafElts. + ///Can be used as an alternative to less_than, etc. methods. + fn cmp(&self, other: &LeafElt) -> Ordering{ + self.key.cmp(&other.key) + } +} + impl Clone for LeafElt { ///Returns a new LeafElt by cloning the key and value. @@ -366,6 +483,18 @@ impl Clone for LeafElt { } } +impl TotalEq for LeafElt{ + ///TotalEq for LeafElts + fn equals(&self, other: &LeafElt) -> bool { + if self.key.equals(&other.key) { + if self.value.equals(&other.value) { + return true; + } + } + return false; + } +} + impl ToStr for LeafElt { ///Returns a string representation of a LeafElt. @@ -376,7 +505,7 @@ impl ToStr for LeafElt { } -impl BranchElt { +impl BranchElt { ///Creates a new BranchElt from a supplied key, value, and left child. fn new(k: K, v: V, n: Node) -> BranchElt { @@ -387,6 +516,7 @@ impl BranchElt { } } + ///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 { @@ -394,6 +524,17 @@ impl BranchElt { } } +impl ToStr for BranchElt { + + ///Returns string containing key, value, and child (which should recur to a leaf) + ///Consider changing in future to be more readable. + fn to_str(&self) -> ~str{ + return "Key: "+self.key.to_str()+", value: "+self.value.to_str()+" + , child: "+self.left.to_str()+";"; + + } +} + impl Clone for BranchElt { ///Returns a new BranchElt by cloning the key, value, and left child. @@ -404,20 +545,55 @@ impl Clone for BranchElt { } } + +impl TotalEq for BranchElt{ + + ///TotalEq for BranchElts + fn equals(&self, other: &BranchElt) -> bool { + if self.key.equals(&other.key) { + if self.value.equals(&other.value) { + return true; + } + } + return false; + } +} + +impl TotalOrd for BranchElt { + + ///Fulfills TotalOrd for BranchElts + fn cmp(&self, other: &BranchElt) -> Ordering { + self.key.cmp(&other.key) + } +} + + #[cfg(test)] mod test_btree{ +<<<<<<< HEAD +<<<<<<< HEAD use super::{BTree, LeafElt}; - - ///Tests the functionality of the add methods (which are unfinished). - #[test] +<<<<<<< HEAD +======= + +======= + +>>>>>>> Wrote some tests for the compare/clone/to_str methods. + use super::*; +>>>>>>> Committing standard compare/to_str/clone features, but no tests yet. +======= +>>>>>>> Don't allow impls to force public types + + //Tests the functionality of the add methods (which are unfinished). + /*#[test] fn add_test(){ let b = BTree::new(1, ~"abc", 2); let is_add = b.add(2, ~"xyz"); assert!(is_add); - } + }*/ - ///Tests the functionality of the get method. + //Tests the functionality of the get method. #[test] fn get_test(){ let b = BTree::new(1, ~"abc", 2); @@ -425,7 +601,7 @@ mod test_btree{ assert_eq!(val, Some(~"abc")); } - ///Tests the LeafElt's less_than() method. + //Tests the LeafElt's less_than() method. #[test] fn leaf_lt(){ let l1 = LeafElt::new(1, ~"abc"); @@ -434,7 +610,7 @@ mod test_btree{ } - ///Tests the LeafElt's greater_than() method. + //Tests the LeafElt's greater_than() method. #[test] fn leaf_gt(){ let l1 = LeafElt::new(1, ~"abc"); @@ -442,11 +618,53 @@ mod test_btree{ assert!(l2.greater_than(l1)); } - ///Tests the LeafElt's has_key() method. + //Tests the LeafElt's has_key() method. #[test] fn leaf_hk(){ let l1 = LeafElt::new(1, ~"abc"); assert!(l1.has_key(1)); } + + //New tests from week of 12/16/13 + + //Tests the BTree's clone() method. + #[test] + fn btree_clone_test(){ + let b = BTree::new(1, ~"abc", 2); + let b2 = b.clone(); + assert!(b.root.equals(&b2.root)) + } + + //Tests the BTree's cmp() method when one node is "less than" another. + #[test] + fn btree_cmp_test_less(){ + let b = BTree::new(1, ~"abc", 2); + let b2 = BTree::new(2, ~"bcd", 2); + assert!(&b.cmp(&b2) == &Less) + } + + //Tests the BTree's cmp() method when two nodes are equal. + #[test] + fn btree_cmp_test_eq(){ + let b = BTree::new(1, ~"abc", 2); + let b2 = BTree::new(1, ~"bcd", 2); + assert!(&b.cmp(&b2) == &Equal) + } + + //Tests the BTree's cmp() method when one node is "greater than" another. + #[test] + fn btree_cmp_test_greater(){ + let b = BTree::new(1, ~"abc", 2); + let b2 = BTree::new(2, ~"bcd", 2); + assert!(&b2.cmp(&b) == &Greater) + } + + //Tests the BTree's to_str() method. + #[test] + fn btree_tostr_test(){ + let b = BTree::new(1, ~"abc", 2); + assert_eq!(b.to_str(), ~" // Key: 1, value: abc; ") + } + } From 377f1508b2319cf67ef7db20e07d9d67bd7e62be Mon Sep 17 00:00:00 2001 From: Nif Ward Date: Mon, 30 Dec 2013 16:05:25 -0500 Subject: [PATCH 2/2] Added more robust compare and equals for Branch and Leaf, as well as some style changes. --- src/libextra/btree.rs | 315 +++++++++++++++++++----------------------- 1 file changed, 140 insertions(+), 175 deletions(-) diff --git a/src/libextra/btree.rs b/src/libextra/btree.rs index eb71185a0d719..6a3c7853c8ec7 100644 --- a/src/libextra/btree.rs +++ b/src/libextra/btree.rs @@ -61,8 +61,7 @@ impl BTree { } - ///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. + ///Stub for add method in progress. pub fn add(self, k: K, v: V) -> BTree { //replace(&self.root,self.root.add(k, v)); return BTree::new(k, v, 2); @@ -70,6 +69,7 @@ impl BTree { } impl BTree { + ///Returns the value of a given key, which may not exist in the tree. ///Calls the root node's get method. pub fn get(self, k: K) -> Option { @@ -77,7 +77,7 @@ impl BTree { } } -impl Clone for BTree{ +impl Clone for BTree { ///Implements the Clone trait for the BTree. ///Uses a helper function/constructor to produce a new BTree. fn clone(&self) -> BTree { @@ -85,12 +85,6 @@ impl Clone for BTree{ } } -impl TotalOrd for BTree { - ///Returns an ordering based on the root nodes of each BTree. - fn cmp(&self, other: &BTree) -> Ordering { - self.root.cmp(&other.root) - } -} impl TotalEq for BTree { @@ -100,6 +94,13 @@ impl TotalEq for BTree { } } +impl TotalOrd for BTree { + ///Returns an ordering based on the root nodes of each BTree. + fn cmp(&self, other: &BTree) -> Ordering { + self.root.cmp(&other.root) + } +} + impl ToStr for BTree { ///Returns a string representation of the BTree fn to_str(&self) -> ~str { @@ -125,7 +126,7 @@ enum Node { impl Node { ///Differentiates between leaf and branch nodes. - fn is_leaf(&self) -> bool{ + fn is_leaf(&self) -> bool { match self{ &LeafNode(..) => true, &BranchNode(..) => false @@ -143,15 +144,14 @@ impl Node { BranchNode(Branch::new(vec, right)) } - ///A placeholder for add + ///A placeholder/stub 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 Node{ - +impl Node { ///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 { @@ -163,54 +163,21 @@ impl Node{ } 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()); - } - } - } -} - -impl TotalOrd for Node { - - ///Placeholder for an implementation of TotalOrd for Nodes. - #[allow(unused_variable)] - fn cmp(&self, other: &Node) -> Ordering { - match *self{ - LeafNode(ref leaf) => { - match *other{ - LeafNode(ref leaf2) => { - return leaf.cmp(leaf2); - } - BranchNode(ref branch) => { - return Less; - } - } + Node::new_leaf(leaf.elts.clone()) } - BranchNode(ref branch) => { - match *other{ - BranchNode(ref branch2) => { - return branch.cmp(branch2); - } - LeafNode(ref leaf) => { - return Greater; - } - } + Node::new_branch(branch.elts.clone(), + branch.rightmost_child.clone()) } } } - } -impl TotalEq for Node{ +impl TotalEq for Node { ///Returns whether two nodes are equal #[allow(unused_variable)] fn equals(&self, other: &Node) -> bool{ @@ -228,13 +195,29 @@ impl TotalEq for Node{ BranchNode(ref branch) => false } } - } - } - } +impl TotalOrd for Node { + ///Implementation of TotalOrd for Nodes. + fn cmp(&self, other: &Node) -> Ordering { + match *self { + LeafNode(ref leaf) => { + match *other { + LeafNode(ref leaf2) => leaf.cmp(leaf2), + BranchNode(_) => Less + } + } + BranchNode(ref branch) => { + match *other { + BranchNode(ref branch2) => branch.cmp(branch2), + LeafNode(_) => Greater + } + } + } + } +} impl ToStr for Node { ///Returns a string representation of a Node. @@ -283,6 +266,7 @@ impl Leaf { } impl Leaf { + ///Returns the corresponding value to the supplied key. fn get(&self, k: K) -> Option { for s in self.elts.iter() { @@ -296,42 +280,50 @@ impl Leaf { } } -impl TotalOrd for Leaf{ - ///Returns an ordering based on the first element of each Leaf. - fn cmp(&self, other: &Leaf) -> Ordering{ - self.elts[0].cmp(&other.elts[0]) - } -} - -impl Clone for Leaf{ +impl Clone for Leaf { ///Returns a new Leaf with the same elts. - fn clone(&self) -> Leaf{ + fn clone(&self) -> Leaf { Leaf::new(self.elts.clone()) } } -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(); +impl TotalEq for Leaf { + + ///Implementation of equals function for leaves that compares LeafElts. + fn equals(&self, other: &Leaf) -> bool { + if self.elts.len() == other.elts.len() && self.elts.len() != 0 { + let mut i = 0; + while i < self.elts.len() { + if !self.elts[i].equals(&other.elts[i]) { + return false; + } + i = i + 1; + } + return true; } - ret + false } } -impl TotalEq for Leaf { - - ///Implementation of equals function for leaves, uses LeafElts' traits. - ///Placeholder implementation. - fn equals(&self, other: &Leaf) -> bool { - if self.elts[0].equals(&other.elts[0]) { - return true; +impl TotalOrd for Leaf { + ///Returns an ordering based on the first element of each Leaf. + fn cmp(&self, other: &Leaf) -> Ordering { + if self.elts.len() > other.elts.len() { + return Greater; } - return false; + if self.elts.len() < other.elts.len() { + return Less; + } + self.elts[0].cmp(&other.elts[0]) + } +} + + +impl ToStr for Leaf { + ///Returns a string representation of a Leaf. + fn to_str(&self) -> ~str { + self.elts.iter().map(|s| s.to_str()).to_owned_vec().connect(" // ") } } @@ -346,7 +338,6 @@ impl Branch { } } - ///Placeholder for add method in progress fn add(&self, k: K, v: V) -> Node { return Node::new_leaf(~[LeafElt::new(k, v)]); @@ -365,48 +356,57 @@ impl Branch { _ => {} } } - return self.rightmost_child.get(k); + self.rightmost_child.get(k) } } -impl TotalOrd for Branch{ - ///Compares the first elements of two branches to determine an ordering - fn cmp(&self, other: &Branch) -> Ordering{ - self.elts[0].cmp(&other.elts[0]) - } -} - -impl Clone for Branch{ - +impl Clone for Branch { ///Returns a new branch using the clone methods of the Branch's internal variables. - fn clone(&self) -> Branch{ + fn clone(&self) -> Branch { Branch::new(self.elts.clone(), self.rightmost_child.clone()) } } -impl TotalEq for Branch{ - - ///Equals function for Branches--compares first elt (Placeholder) +impl TotalEq for Branch { + ///Equals function for Branches--compares all the elements in each branch fn equals(&self, other: &Branch) -> bool { - if self.elts[0].equals(&other.elts[0]){ - return true; + if self.elts.len() == other.elts.len() && self.elts.len() != 0 { + let mut i = 0; + while i < self.elts.len() { + if !self.elts[i].equals(&other.elts[i]) { + return false; + } + i = i + 1; + } + if self.rightmost_child.equals(&other.rightmost_child) { + return true; + } } - return false; + false } } -impl ToStr for Branch { +impl TotalOrd for Branch { + ///Compares the first elements of two branches to determine an ordering + fn cmp(&self, other: &Branch) -> Ordering { + if self.elts.len() > other.elts.len() { + return Greater; + } + if self.elts.len() < other.elts.len() { + return Less; + } + self.elts[0].cmp(&other.elts[0]) + } +} +impl ToStr for Branch { ///Returns a string representation of a Branch. fn to_str(&self) -> ~str { - let mut ret = ~""; - for s in self.elts.iter() { - ret = ret + " // " + s.to_str(); - } - ret = ret + " // " + self.rightmost_child.to_str(); + let mut ret = self.elts.iter().map(|s| s.to_str()).to_owned_vec().connect(" // "); + ret.push_str(" // "); + ret.push_str(self.rightmost_child.to_str()); ret } - } //A LeafElt containts no left child, but a key-value pair. @@ -465,48 +465,37 @@ impl LeafElt { } } - -impl TotalOrd for LeafElt { - - ///Returns an ordering based on the keys of the LeafElts. - ///Can be used as an alternative to less_than, etc. methods. - fn cmp(&self, other: &LeafElt) -> Ordering{ - self.key.cmp(&other.key) - } -} - 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()); + LeafElt::new(self.key.clone(), self.value.clone()) } } -impl TotalEq for LeafElt{ +impl TotalEq for LeafElt { ///TotalEq for LeafElts fn equals(&self, other: &LeafElt) -> bool { - if self.key.equals(&other.key) { - if self.value.equals(&other.value) { - return true; - } - } - return false; + self.key.equals(&other.key) && self.value.equals(&other.value) } } -impl ToStr for LeafElt { +impl TotalOrd for LeafElt { + ///Returns an ordering based on the keys of the LeafElts. + fn cmp(&self, other: &LeafElt) -> Ordering { + self.key.cmp(&other.key) + } +} +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() + "; "; + format!("Key: {}, value: {};", + self.key.to_str(), 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 { @@ -516,7 +505,6 @@ impl BranchElt { } } - ///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 { @@ -524,66 +512,45 @@ impl BranchElt { } } -impl ToStr for BranchElt { - - ///Returns string containing key, value, and child (which should recur to a leaf) - ///Consider changing in future to be more readable. - fn to_str(&self) -> ~str{ - return "Key: "+self.key.to_str()+", value: "+self.value.to_str()+" - , child: "+self.left.to_str()+";"; - - } -} 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()); + BranchElt::new(self.key.clone(), + self.value.clone(), + self.left.clone()) } } - impl TotalEq for BranchElt{ - ///TotalEq for BranchElts fn equals(&self, other: &BranchElt) -> bool { - if self.key.equals(&other.key) { - if self.value.equals(&other.value) { - return true; - } - } - return false; + self.key.equals(&other.key)&&self.value.equals(&other.value) } } impl TotalOrd for BranchElt { - ///Fulfills TotalOrd for BranchElts fn cmp(&self, other: &BranchElt) -> Ordering { self.key.cmp(&other.key) } } +impl ToStr for BranchElt { + + ///Returns string containing key, value, and child (which should recur to a leaf) + ///Consider changing in future to be more readable. + fn to_str(&self) -> ~str { + format!("Key: {}, value: {}, child: {};", + self.key.to_str(), self.value.to_str(), self.left.to_str()) + } +} + #[cfg(test)] -mod test_btree{ -<<<<<<< HEAD -<<<<<<< HEAD +mod test_btree { use super::{BTree, LeafElt}; -<<<<<<< HEAD -======= - -======= - ->>>>>>> Wrote some tests for the compare/clone/to_str methods. - use super::*; ->>>>>>> Committing standard compare/to_str/clone features, but no tests yet. -======= ->>>>>>> Don't allow impls to force public types //Tests the functionality of the add methods (which are unfinished). /*#[test] @@ -595,7 +562,7 @@ mod test_btree{ //Tests the functionality of the get method. #[test] - fn get_test(){ + fn get_test() { let b = BTree::new(1, ~"abc", 2); let val = b.get(1); assert_eq!(val, Some(~"abc")); @@ -603,7 +570,7 @@ mod test_btree{ //Tests the LeafElt's less_than() method. #[test] - fn leaf_lt(){ + fn leaf_lt() { let l1 = LeafElt::new(1, ~"abc"); let l2 = LeafElt::new(2, ~"xyz"); assert!(l1.less_than(l2)); @@ -612,7 +579,7 @@ mod test_btree{ //Tests the LeafElt's greater_than() method. #[test] - fn leaf_gt(){ + fn leaf_gt() { let l1 = LeafElt::new(1, ~"abc"); let l2 = LeafElt::new(2, ~"xyz"); assert!(l2.greater_than(l1)); @@ -620,16 +587,14 @@ mod test_btree{ //Tests the LeafElt's has_key() method. #[test] - fn leaf_hk(){ + fn leaf_hk() { let l1 = LeafElt::new(1, ~"abc"); assert!(l1.has_key(1)); } - //New tests from week of 12/16/13 - //Tests the BTree's clone() method. #[test] - fn btree_clone_test(){ + fn btree_clone_test() { let b = BTree::new(1, ~"abc", 2); let b2 = b.clone(); assert!(b.root.equals(&b2.root)) @@ -637,7 +602,7 @@ mod test_btree{ //Tests the BTree's cmp() method when one node is "less than" another. #[test] - fn btree_cmp_test_less(){ + fn btree_cmp_test_less() { let b = BTree::new(1, ~"abc", 2); let b2 = BTree::new(2, ~"bcd", 2); assert!(&b.cmp(&b2) == &Less) @@ -645,7 +610,7 @@ mod test_btree{ //Tests the BTree's cmp() method when two nodes are equal. #[test] - fn btree_cmp_test_eq(){ + fn btree_cmp_test_eq() { let b = BTree::new(1, ~"abc", 2); let b2 = BTree::new(1, ~"bcd", 2); assert!(&b.cmp(&b2) == &Equal) @@ -653,7 +618,7 @@ mod test_btree{ //Tests the BTree's cmp() method when one node is "greater than" another. #[test] - fn btree_cmp_test_greater(){ + fn btree_cmp_test_greater() { let b = BTree::new(1, ~"abc", 2); let b2 = BTree::new(2, ~"bcd", 2); assert!(&b2.cmp(&b) == &Greater) @@ -661,9 +626,9 @@ mod test_btree{ //Tests the BTree's to_str() method. #[test] - fn btree_tostr_test(){ + fn btree_tostr_test() { let b = BTree::new(1, ~"abc", 2); - assert_eq!(b.to_str(), ~" // Key: 1, value: abc; ") + assert_eq!(b.to_str(), ~"Key: 1, value: abc;") } }