Re-arranging some things in btree.rs to accommodate testing.
This commit is contained in:
parent
e6dde28c95
commit
058d785369
1 changed files with 123 additions and 111 deletions
|
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<K, V>{
|
|||
|
||||
|
||||
impl<K: Clone + TotalOrd, V: Clone> BTree<K, V>{
|
||||
|
||||
|
||||
//Returns new BTree with root node (leaf) and user-supplied lower bound
|
||||
fn new(k: K, v: V, lb: uint) -> BTree<K, V>{
|
||||
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<K, V>, length: uint, lb: uint) -> BTree<K, V>{
|
||||
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<K: Clone + TotalOrd, V: Clone> BTree<K, V>{
|
|||
|
||||
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<K: ToStr + TotalOrd, V: ToStr> ToStr for BTree<K, V>{
|
|||
//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<K: Clone + TotalOrd, V: Clone> Node<K, V>{
|
|||
//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<K, V>]) -> Node<K,V>{
|
||||
LeafNode(Leaf::new(vec))
|
||||
|
@ -98,8 +108,8 @@ impl<K: Clone + TotalOrd, V: Clone> Node<K, V>{
|
|||
|
||||
fn get(&self, k: K) -> Option<V>{
|
||||
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<K: Clone + TotalOrd, V: Clone> Node<K, V>{
|
|||
impl<K: Clone + TotalOrd, V: Clone> Clone for Node<K, V>{
|
||||
fn clone(&self) -> Node<K, V>{
|
||||
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<K: Clone + TotalOrd, V: Clone> TotalOrd for Node<K, V>{
|
|||
fn cmp(&self, other: &Node<K, V>) -> 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<K: Clone + TotalOrd, V: Clone> TotalEq for Node<K, V>{
|
|||
|
||||
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<K: ToStr + TotalOrd, V: ToStr> ToStr for Node<K, V>{
|
|||
fn to_str(&self) -> ~str{
|
||||
match *self{
|
||||
LeafNode(ref leaf) => leaf.to_str(),
|
||||
BranchNode(*) => ~""
|
||||
BranchNode(*) => ~""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -192,13 +203,13 @@ impl<K: Clone + TotalOrd, V: Clone> Leaf<K, V>{
|
|||
|
||||
fn get(&self, k: K) -> Option<V>{
|
||||
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<K: Clone + TotalOrd, V: Clone> Branch<K, V>{
|
|||
//constructor takes a branch vector and a rightmost child
|
||||
fn new(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Branch<K, V>{
|
||||
Branch{
|
||||
elts: vec,
|
||||
rightmost_child: right
|
||||
elts: vec,
|
||||
rightmost_child: right
|
||||
}
|
||||
}
|
||||
|
||||
fn get(&self, k: K) -> Option<V>{
|
||||
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<K: Clone + TotalOrd, V> LeafElt<K, V>{
|
|||
fn new(k: K, v: V) -> LeafElt<K, V>{
|
||||
LeafElt{
|
||||
key: k,
|
||||
value: v
|
||||
}
|
||||
value: v
|
||||
}
|
||||
}
|
||||
|
||||
fn less_than(&self, other: LeafElt<K, V>) -> bool{
|
||||
let order = self.key.cmp(&other.key);
|
||||
match order{
|
||||
Less => true,
|
||||
_ => false
|
||||
}
|
||||
match order{
|
||||
Less => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn greater_than(&self, other: LeafElt<K, V>) -> 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<K: Clone + TotalOrd, V: Clone> BranchElt<K, V>{
|
|||
}
|
||||
}
|
||||
|
||||
//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<K, V>{
|
||||
return LeafElt::new(k, v);
|
||||
}
|
||||
|
@ -330,43 +341,44 @@ impl<K: Clone + TotalOrd, V: Clone> Clone for BranchElt<K, V>{
|
|||
}
|
||||
}
|
||||
|
||||
#[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<K, V> 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<K, V> 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(){
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue