2013-11-05 18:44:21 -06:00
|
|
|
// 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.
|
2013-11-04 18:45:49 -06:00
|
|
|
//
|
|
|
|
// btree.rs
|
|
|
|
//
|
2013-11-08 01:41:09 -06:00
|
|
|
|
|
|
|
//! Starting implementation of a btree for rust.
|
|
|
|
//! Structure inspired by github user davidhalperin's gist.
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2013-12-08 01:55:28 -06:00
|
|
|
#[allow(dead_code)];
|
2014-01-06 20:19:36 -06:00
|
|
|
#[allow(unused_variable)];
|
2013-11-07 12:34:20 -06:00
|
|
|
|
|
|
|
///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)]
|
2013-12-08 01:55:28 -06:00
|
|
|
pub struct BTree<K, V> {
|
2014-01-25 20:25:02 -06:00
|
|
|
priv root: Node<K, V>,
|
|
|
|
priv len: uint,
|
|
|
|
priv lower_bound: uint,
|
|
|
|
priv upper_bound: uint
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
//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.
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V> BTree<K, V> {
|
2013-11-05 18:44:21 -06:00
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns new BTree with root node (leaf) and user-supplied lower bound
|
2013-12-08 01:55:28 -06:00
|
|
|
pub fn new(k: K, v: V, lb: uint) -> BTree<K, V> {
|
|
|
|
BTree {
|
2013-11-05 18:44:21 -06:00
|
|
|
root: Node::new_leaf(~[LeafElt::new(k, v)]),
|
|
|
|
len: 1,
|
|
|
|
lower_bound: lb,
|
|
|
|
upper_bound: 2 * lb
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Helper function for clone: returns new BTree with supplied root node,
|
|
|
|
///length, and lower bound. For use when the length is known already.
|
2014-01-25 20:25:02 -06:00
|
|
|
fn new_with_node_len(n: Node<K, V>,
|
|
|
|
length: uint,
|
|
|
|
lb: uint) -> BTree<K, V> {
|
2013-12-08 01:55:28 -06:00
|
|
|
BTree {
|
2013-11-05 18:44:21 -06:00
|
|
|
root: n,
|
|
|
|
len: length,
|
|
|
|
lower_bound: lb,
|
|
|
|
upper_bound: 2 * lb
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
|
|
|
|
///Stub for add method in progress.
|
|
|
|
pub fn add(self, k: K, v: V) -> BTree<K, V> {
|
|
|
|
//replace(&self.root,self.root.add(k, v));
|
|
|
|
return BTree::new(k, v, 2);
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
2014-01-06 20:19:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: Clone> BTree<K, V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns the value of a given key, which may not exist in the tree.
|
|
|
|
///Calls the root node's get method.
|
2013-12-08 01:55:28 -06:00
|
|
|
pub fn get(self, k: K) -> Option<V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
return self.root.get(k);
|
|
|
|
}
|
2014-01-06 20:19:36 -06:00
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: Clone + TotalOrd, V: Clone> Clone for BTree<K, V> {
|
|
|
|
///Implements the Clone trait for the BTree.
|
|
|
|
///Uses a helper function/constructor to produce a new BTree.
|
|
|
|
fn clone(&self) -> BTree<K, V> {
|
|
|
|
BTree::new_with_node_len(self.root.clone(), self.len, self.lower_bound)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalEq for BTree<K, V> {
|
|
|
|
///Testing equality on BTrees by comparing the root.
|
|
|
|
fn equals(&self, other: &BTree<K, V>) -> bool {
|
|
|
|
self.root.cmp(&other.root) == Equal
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalOrd for BTree<K, V> {
|
|
|
|
///Returns an ordering based on the root nodes of each BTree.
|
|
|
|
fn cmp(&self, other: &BTree<K, V>) -> Ordering {
|
|
|
|
self.root.cmp(&other.root)
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-08 01:55:28 -06:00
|
|
|
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for BTree<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns a string representation of the BTree
|
2013-12-08 01:55:28 -06:00
|
|
|
fn to_str(&self) -> ~str {
|
2013-11-07 12:34:20 -06:00
|
|
|
let ret = self.root.to_str();
|
|
|
|
ret
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Node types
|
2013-11-07 12:34:20 -06:00
|
|
|
//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.
|
2013-12-08 01:55:28 -06:00
|
|
|
enum Node<K, V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
LeafNode(Leaf<K, V>),
|
|
|
|
BranchNode(Branch<K, V>)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Node functions/methods
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V> Node<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
|
|
|
|
///Differentiates between leaf and branch nodes.
|
2014-01-06 20:19:36 -06:00
|
|
|
fn is_leaf(&self) -> bool {
|
2013-11-04 18:45:49 -06:00
|
|
|
match self{
|
2013-11-28 14:22:53 -06:00
|
|
|
&LeafNode(..) => true,
|
|
|
|
&BranchNode(..) => false
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
2013-11-05 18:44:21 -06:00
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Creates a new leaf node given a vector of elements.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn new_leaf(vec: ~[LeafElt<K, V>]) -> Node<K,V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
LeafNode(Leaf::new(vec))
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
2013-11-07 12:34:20 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Creates a new branch node given a vector of an elements and a pointer to a rightmost child.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn new_branch(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Node<K, V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
BranchNode(Branch::new(vec, right))
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
///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<K, V> {
|
|
|
|
return Node::new_leaf(~[LeafElt::new(k, v)]);
|
|
|
|
}
|
|
|
|
}
|
2013-11-07 12:34:20 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V: Clone> Node<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns the corresponding value to the provided key.
|
|
|
|
///get() is called in different ways on a branch or a leaf.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn get(&self, k: K) -> Option<V> {
|
|
|
|
match *self {
|
2013-11-05 18:44:21 -06:00
|
|
|
LeafNode(ref leaf) => return leaf.get(k),
|
|
|
|
BranchNode(ref branch) => return branch.get(k)
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-08 01:55:28 -06:00
|
|
|
impl<K: Clone + TotalOrd, V: Clone> Clone for Node<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns a new node based on whether or not it is a branch or a leaf.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn clone(&self) -> Node<K, V> {
|
|
|
|
match *self {
|
|
|
|
LeafNode(ref leaf) => {
|
2014-01-06 20:19:36 -06:00
|
|
|
Node::new_leaf(leaf.elts.clone())
|
2013-12-08 01:55:28 -06:00
|
|
|
}
|
|
|
|
BranchNode(ref branch) => {
|
2014-01-06 20:19:36 -06:00
|
|
|
Node::new_branch(branch.elts.clone(),
|
|
|
|
branch.rightmost_child.clone())
|
2013-12-08 01:55:28 -06:00
|
|
|
}
|
2013-11-05 18:44:21 -06:00
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalEq for Node<K, V> {
|
|
|
|
///Returns whether two nodes are equal
|
|
|
|
fn equals(&self, other: &Node<K, V>) -> bool{
|
|
|
|
match *self{
|
|
|
|
BranchNode(ref branch) => {
|
|
|
|
match *other{
|
|
|
|
BranchNode(ref branch2) => branch.cmp(branch2) == Equal,
|
|
|
|
LeafNode(ref leaf) => false
|
|
|
|
}
|
|
|
|
}
|
2013-11-07 12:34:20 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
LeafNode(ref leaf) => {
|
|
|
|
match *other{
|
|
|
|
LeafNode(ref leaf2) => leaf.cmp(leaf2) == Equal,
|
|
|
|
BranchNode(ref branch) => false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalOrd for Node<K, V> {
|
|
|
|
///Implementation of TotalOrd for Nodes.
|
|
|
|
fn cmp(&self, other: &Node<K, V>) -> 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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-08 01:55:28 -06:00
|
|
|
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for Node<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns a string representation of a Node.
|
|
|
|
///The Branch's to_str() is not implemented yet.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn to_str(&self) -> ~str {
|
|
|
|
match *self {
|
2013-11-07 12:34:20 -06:00
|
|
|
LeafNode(ref leaf) => leaf.to_str(),
|
2014-01-06 20:19:36 -06:00
|
|
|
BranchNode(ref branch) => branch.to_str()
|
2013-11-07 12:34:20 -06:00
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
//A leaf is a vector with elements that contain no children. A leaf also
|
|
|
|
//does not contain a rightmost child.
|
2013-12-08 01:55:28 -06:00
|
|
|
struct Leaf<K, V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
elts: ~[LeafElt<K, V>]
|
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
//Vector of values with children, plus a rightmost child (greater than all)
|
2013-12-08 01:55:28 -06:00
|
|
|
struct Branch<K, V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
elts: ~[BranchElt<K,V>],
|
|
|
|
rightmost_child: ~Node<K, V>
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V> Leaf<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Creates a new Leaf from a vector of LeafElts.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn new(vec: ~[LeafElt<K, V>]) -> Leaf<K, V> {
|
|
|
|
Leaf {
|
2013-11-04 18:45:49 -06:00
|
|
|
elts: vec
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
///Placeholder for add method in progress.
|
|
|
|
///Currently returns a new Leaf containing a single LeafElt.
|
|
|
|
fn add(&self, k: K, v: V) -> Node<K, V> {
|
|
|
|
return Node::new_leaf(~[LeafElt::new(k, v)]);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: Clone> Leaf<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns the corresponding value to the supplied key.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn get(&self, k: K) -> Option<V> {
|
|
|
|
for s in self.elts.iter() {
|
2013-11-07 12:34:20 -06:00
|
|
|
let order = s.key.cmp(&k);
|
2013-12-08 01:55:28 -06:00
|
|
|
match order {
|
2013-11-05 18:44:21 -06:00
|
|
|
Equal => return Some(s.value.clone()),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return None;
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
2014-01-06 20:19:36 -06:00
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: Clone + TotalOrd, V: Clone> Clone for Leaf<K, V> {
|
|
|
|
///Returns a new Leaf with the same elts.
|
|
|
|
fn clone(&self) -> Leaf<K, V> {
|
|
|
|
Leaf::new(self.elts.clone())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalEq for Leaf<K, V> {
|
|
|
|
///Implementation of equals function for leaves that compares LeafElts.
|
|
|
|
fn equals(&self, other: &Leaf<K, V>) -> bool {
|
|
|
|
self.elts.equals(&other.elts)
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
2014-01-06 20:19:36 -06:00
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalOrd for Leaf<K, V> {
|
|
|
|
///Returns an ordering based on the first element of each Leaf.
|
|
|
|
fn cmp(&self, other: &Leaf<K, V>) -> 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])
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for Leaf<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns a string representation of a Leaf.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn to_str(&self) -> ~str {
|
2014-01-06 20:19:36 -06:00
|
|
|
self.elts.iter().map(|s| s.to_str()).to_owned_vec().connect(" // ")
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V> Branch<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Creates a new Branch from a vector of BranchElts and a rightmost child (a node).
|
2013-12-08 01:55:28 -06:00
|
|
|
fn new(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Branch<K, V> {
|
|
|
|
Branch {
|
2013-11-05 18:44:21 -06:00
|
|
|
elts: vec,
|
|
|
|
rightmost_child: right
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
///Placeholder for add method in progress
|
|
|
|
fn add(&self, k: K, v: V) -> Node<K, V> {
|
|
|
|
return Node::new_leaf(~[LeafElt::new(k, v)]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: Clone> Branch<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns the corresponding value to the supplied key.
|
|
|
|
///If the key is not there, find the child that might hold it.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn get(&self, k: K) -> Option<V> {
|
|
|
|
for s in self.elts.iter() {
|
2013-11-05 18:44:21 -06:00
|
|
|
let order = s.key.cmp(&k);
|
2013-12-08 01:55:28 -06:00
|
|
|
match order {
|
2013-11-05 18:44:21 -06:00
|
|
|
Less => return s.left.get(k),
|
|
|
|
Equal => return Some(s.value.clone()),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
2014-01-06 20:19:36 -06:00
|
|
|
self.rightmost_child.get(k)
|
2013-11-07 12:34:20 -06:00
|
|
|
}
|
2014-01-06 20:19:36 -06:00
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: Clone + TotalOrd, V: Clone> Clone for Branch<K, V> {
|
|
|
|
///Returns a new branch using the clone methods of the Branch's internal variables.
|
|
|
|
fn clone(&self) -> Branch<K, V> {
|
|
|
|
Branch::new(self.elts.clone(), self.rightmost_child.clone())
|
|
|
|
}
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalEq for Branch<K, V> {
|
|
|
|
///Equals function for Branches--compares all the elements in each branch
|
|
|
|
fn equals(&self, other: &Branch<K, V>) -> bool {
|
|
|
|
self.elts.equals(&other.elts)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalOrd for Branch<K, V> {
|
|
|
|
///Compares the first elements of two branches to determine an ordering
|
|
|
|
fn cmp(&self, other: &Branch<K, V>) -> 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<K: ToStr + TotalOrd, V: ToStr> ToStr for Branch<K, V> {
|
|
|
|
///Returns a string representation of a Branch.
|
|
|
|
fn to_str(&self) -> ~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
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
//A LeafElt containts no left child, but a key-value pair.
|
2013-12-08 01:55:28 -06:00
|
|
|
struct LeafElt<K, V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
key: K,
|
|
|
|
value: V
|
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
//A BranchElt has a left child in addition to a key-value pair.
|
2013-12-08 01:55:28 -06:00
|
|
|
struct BranchElt<K, V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
left: Node<K, V>,
|
|
|
|
key: K,
|
|
|
|
value: V
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V> LeafElt<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Creates a new LeafElt from a supplied key-value pair.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn new(k: K, v: V) -> LeafElt<K, V> {
|
|
|
|
LeafElt {
|
2013-11-04 18:45:49 -06:00
|
|
|
key: k,
|
2013-11-05 18:44:21 -06:00
|
|
|
value: v
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Compares another LeafElt against itself and determines whether
|
|
|
|
///the original LeafElt's key is less than the other one's key.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn less_than(&self, other: LeafElt<K, V>) -> bool {
|
2013-11-04 18:45:49 -06:00
|
|
|
let order = self.key.cmp(&other.key);
|
2013-12-08 01:55:28 -06:00
|
|
|
match order {
|
2013-11-05 18:44:21 -06:00
|
|
|
Less => true,
|
|
|
|
_ => false
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Compares another LeafElt against itself and determines whether
|
|
|
|
///the original LeafElt's key is greater than the other one's key.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn greater_than(&self, other: LeafElt<K, V>) -> bool {
|
2013-11-04 18:45:49 -06:00
|
|
|
let order = self.key.cmp(&other.key);
|
2013-12-08 01:55:28 -06:00
|
|
|
match order {
|
2013-11-05 18:44:21 -06:00
|
|
|
Greater => true,
|
|
|
|
_ => false
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Takes a key and determines whether its own key and the supplied key
|
|
|
|
///are the same.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn has_key(&self, other: K) -> bool {
|
2013-11-04 18:45:49 -06:00
|
|
|
let order = self.key.cmp(&other);
|
2013-12-08 01:55:28 -06:00
|
|
|
match order {
|
2013-11-05 18:44:21 -06:00
|
|
|
Equal => true,
|
|
|
|
_ => false
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-08 01:55:28 -06:00
|
|
|
impl<K: Clone + TotalOrd, V: Clone> Clone for LeafElt<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns a new LeafElt by cloning the key and value.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn clone(&self) -> LeafElt<K, V> {
|
2014-01-06 20:19:36 -06:00
|
|
|
LeafElt::new(self.key.clone(), self.value.clone())
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalEq for LeafElt<K, V> {
|
|
|
|
///TotalEq for LeafElts
|
|
|
|
fn equals(&self, other: &LeafElt<K, V>) -> bool {
|
|
|
|
self.key.equals(&other.key) && self.value.equals(&other.value)
|
|
|
|
}
|
|
|
|
}
|
2013-11-07 12:34:20 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalOrd for LeafElt<K, V> {
|
|
|
|
///Returns an ordering based on the keys of the LeafElts.
|
|
|
|
fn cmp(&self, other: &LeafElt<K, V>) -> Ordering {
|
|
|
|
self.key.cmp(&other.key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for LeafElt<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns a string representation of a LeafElt.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn to_str(&self) -> ~str {
|
2014-01-06 20:19:36 -06:00
|
|
|
format!("Key: {}, value: {};",
|
|
|
|
self.key.to_str(), self.value.to_str())
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: TotalOrd, V> BranchElt<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Creates a new BranchElt from a supplied key, value, and left child.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn new(k: K, v: V, n: Node<K, V>) -> BranchElt<K, V> {
|
|
|
|
BranchElt {
|
2013-11-04 18:45:49 -06:00
|
|
|
left: n,
|
|
|
|
key: k,
|
|
|
|
value: v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
///Placeholder for add method in progress.
|
|
|
|
///Overall implementation will determine the actual return value of this method.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn add(&self, k: K, v: V) -> LeafElt<K, V> {
|
2013-11-04 18:45:49 -06:00
|
|
|
return LeafElt::new(k, v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
impl<K: Clone + TotalOrd, V: Clone> Clone for BranchElt<K, V> {
|
2013-11-07 12:34:20 -06:00
|
|
|
///Returns a new BranchElt by cloning the key, value, and left child.
|
2013-12-08 01:55:28 -06:00
|
|
|
fn clone(&self) -> BranchElt<K, V> {
|
2014-01-06 20:19:36 -06:00
|
|
|
BranchElt::new(self.key.clone(),
|
|
|
|
self.value.clone(),
|
|
|
|
self.left.clone())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalEq for BranchElt<K, V>{
|
|
|
|
///TotalEq for BranchElts
|
|
|
|
fn equals(&self, other: &BranchElt<K, V>) -> bool {
|
|
|
|
self.key.equals(&other.key)&&self.value.equals(&other.value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: TotalOrd, V: TotalEq> TotalOrd for BranchElt<K, V> {
|
|
|
|
///Fulfills TotalOrd for BranchElts
|
|
|
|
fn cmp(&self, other: &BranchElt<K, V>) -> Ordering {
|
|
|
|
self.key.cmp(&other.key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for BranchElt<K, V> {
|
|
|
|
///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())
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-05 18:44:21 -06:00
|
|
|
#[cfg(test)]
|
2014-01-06 20:19:36 -06:00
|
|
|
mod test_btree {
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2013-12-17 01:32:37 -06:00
|
|
|
use super::{BTree, LeafElt};
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
//Tests the functionality of the add methods (which are unfinished).
|
|
|
|
/*#[test]
|
2013-11-05 18:44:21 -06:00
|
|
|
fn add_test(){
|
|
|
|
let b = BTree::new(1, ~"abc", 2);
|
|
|
|
let is_add = b.add(2, ~"xyz");
|
|
|
|
assert!(is_add);
|
2014-01-06 20:19:36 -06:00
|
|
|
}*/
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
//Tests the functionality of the get method.
|
2013-11-05 18:44:21 -06:00
|
|
|
#[test]
|
2014-01-06 20:19:36 -06:00
|
|
|
fn get_test() {
|
2013-11-05 18:44:21 -06:00
|
|
|
let b = BTree::new(1, ~"abc", 2);
|
|
|
|
let val = b.get(1);
|
|
|
|
assert_eq!(val, Some(~"abc"));
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
//Tests the LeafElt's less_than() method.
|
2013-11-05 18:44:21 -06:00
|
|
|
#[test]
|
2014-01-06 20:19:36 -06:00
|
|
|
fn leaf_lt() {
|
2013-11-05 18:44:21 -06:00
|
|
|
let l1 = LeafElt::new(1, ~"abc");
|
|
|
|
let l2 = LeafElt::new(2, ~"xyz");
|
|
|
|
assert!(l1.less_than(l2));
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2013-11-07 12:34:20 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
//Tests the LeafElt's greater_than() method.
|
2013-11-05 18:44:21 -06:00
|
|
|
#[test]
|
2014-01-06 20:19:36 -06:00
|
|
|
fn leaf_gt() {
|
2013-11-05 18:44:21 -06:00
|
|
|
let l1 = LeafElt::new(1, ~"abc");
|
|
|
|
let l2 = LeafElt::new(2, ~"xyz");
|
|
|
|
assert!(l2.greater_than(l1));
|
|
|
|
}
|
2013-11-04 18:45:49 -06:00
|
|
|
|
2014-01-06 20:19:36 -06:00
|
|
|
//Tests the LeafElt's has_key() method.
|
2013-11-05 18:44:21 -06:00
|
|
|
#[test]
|
2014-01-06 20:19:36 -06:00
|
|
|
fn leaf_hk() {
|
2013-11-05 18:44:21 -06:00
|
|
|
let l1 = LeafElt::new(1, ~"abc");
|
|
|
|
assert!(l1.has_key(1));
|
|
|
|
}
|
2014-01-06 20:19:36 -06:00
|
|
|
|
|
|
|
//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;")
|
|
|
|
}
|
|
|
|
|
2013-11-04 18:45:49 -06:00
|
|
|
}
|