Skip to content

Commit e6dde28

Browse files
committed
Added skeleton implementation of a B-tree with a few bells and
whistles. No major functionality added yet (such as insertion and removal).
1 parent 658637b commit e6dde28

File tree

1 file changed

+372
-0
lines changed

1 file changed

+372
-0
lines changed

src/libextra/btree.rs

Lines changed: 372 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,372 @@
1+
//
2+
// btree.rs
3+
// Nif Ward
4+
// 10/24/13
5+
//
6+
// starting implementation of a btree for rust
7+
// inspired by github user davidhalperin's gist
8+
9+
10+
//What's in a BTree?
11+
pub struct BTree<K, V>{
12+
root: Node<K, V>,
13+
len: uint,
14+
lower_bound: uint,
15+
upper_bound: uint
16+
}
17+
18+
19+
impl<K: Clone + TotalOrd, V: Clone> BTree<K, V>{
20+
21+
//Returns new BTree with root node (leaf) and user-supplied lower bound
22+
fn new(k: K, v: V, lb: uint) -> BTree<K, V>{
23+
BTree{
24+
root: Node::new_leaf(~[LeafElt::new(k, v)]),
25+
len: 1,
26+
lower_bound: lb,
27+
upper_bound: 2 * lb
28+
}
29+
}
30+
31+
//Helper function for clone
32+
fn new_with_node_len(n: Node<K, V>, length: uint, lb: uint) -> BTree<K, V>{
33+
BTree{
34+
root: n,
35+
len: length,
36+
lower_bound: lb,
37+
upper_bound: 2 * lb
38+
}
39+
}
40+
41+
42+
fn clone(&self) -> BTree<K, V>{
43+
return BTree::new_with_node_len(self.root.clone(), self.len, self.lower_bound);
44+
}
45+
46+
fn get(self, k: K) -> Option<V>{
47+
return self.root.get(k);
48+
}
49+
50+
51+
fn add(self, k: K, v: V) -> bool{
52+
let is_get = &self.clone().get(k.clone());
53+
if is_get.is_some(){ return false; }
54+
else{
55+
std::util::replace(&mut self.root.clone(),self.root.add(k.clone(), v));
56+
return true;
57+
}
58+
59+
}
60+
61+
62+
63+
}
64+
65+
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for BTree<K, V>{
66+
//Returns a string representation of the BTree
67+
fn to_str(&self) -> ~str{
68+
let ret=self.root.to_str();
69+
return ret;
70+
}
71+
}
72+
73+
74+
//Node types
75+
enum Node<K, V>{
76+
LeafNode(Leaf<K, V>),
77+
BranchNode(Branch<K, V>)
78+
}
79+
80+
81+
//Node functions/methods
82+
impl<K: Clone + TotalOrd, V: Clone> Node<K, V>{
83+
//differentiates between leaf and branch nodes
84+
fn is_leaf(&self) -> bool{
85+
match self{
86+
&LeafNode(*) => true,
87+
&BranchNode(*) => false
88+
}
89+
}
90+
91+
//Creates a new leaf or branch node
92+
fn new_leaf(vec: ~[LeafElt<K, V>]) -> Node<K,V>{
93+
LeafNode(Leaf::new(vec))
94+
}
95+
fn new_branch(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Node<K, V>{
96+
BranchNode(Branch::new(vec, right))
97+
}
98+
99+
fn get(&self, k: K) -> Option<V>{
100+
match *self{
101+
LeafNode(ref leaf) => return leaf.get(k),
102+
BranchNode(ref branch) => return branch.get(k)
103+
}
104+
}
105+
106+
//A placeholder for add
107+
//Currently returns a leaf node with a single value (the added one)
108+
fn add(self, k: K, v: V) -> Node<K, V>{
109+
return Node::new_leaf(~[LeafElt::new(k, v)]);
110+
}
111+
}
112+
113+
114+
impl<K: Clone + TotalOrd, V: Clone> Clone for Node<K, V>{
115+
fn clone(&self) -> Node<K, V>{
116+
match *self{
117+
LeafNode(ref leaf) => return Node::new_leaf(leaf.elts.clone()),
118+
BranchNode(ref branch) => return Node::new_branch(branch.elts.clone(), branch.rightmost_child.clone())
119+
}
120+
}
121+
}
122+
123+
impl<K: Clone + TotalOrd, V: Clone> TotalOrd for Node<K, V>{
124+
#[allow(unused_variable)]
125+
fn cmp(&self, other: &Node<K, V>) -> Ordering{
126+
//Requires a match statement--defer these procs to branch and leaf.
127+
/* if self.elts[0].less_than(other.elts[0]) { return Less}
128+
if self.elts[0].greater_than(other.elts[0]) {return Greater}
129+
else {return Equal}
130+
*/
131+
return Equal;
132+
}
133+
}
134+
135+
impl<K: Clone + TotalOrd, V: Clone> TotalEq for Node<K, V>{
136+
//Making sure Nodes have TotalEq
137+
#[allow(unused_variable)]
138+
fn equals(&self, other: &Node<K, V>) -> bool{
139+
/* put in a match and defer this stuff to branch and leaf
140+
141+
let mut shorter = 0;
142+
if self.elts.len() <= other.elts.len(){
143+
shorter = self.elts.len();
144+
}
145+
else{
146+
shorter = other.elts.len();
147+
}
148+
let mut i = 0;
149+
while i < shorter{
150+
if !self.elts[i].has_key(other.elts[i].key){
151+
return false;
152+
}
153+
i +=1;
154+
}
155+
return true;
156+
*/
157+
return true;
158+
}
159+
}
160+
161+
162+
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for Node<K, V>{
163+
fn to_str(&self) -> ~str{
164+
match *self{
165+
LeafNode(ref leaf) => leaf.to_str(),
166+
BranchNode(*) => ~""
167+
}
168+
}
169+
}
170+
171+
172+
//Array with no children
173+
struct Leaf<K, V>{
174+
elts: ~[LeafElt<K, V>]
175+
}
176+
177+
//Array of values with children, plus a rightmost child (greater than all)
178+
struct Branch<K, V>{
179+
elts: ~[BranchElt<K,V>],
180+
rightmost_child: ~Node<K, V>
181+
}
182+
183+
184+
impl<K: Clone + TotalOrd, V: Clone> Leaf<K, V>{
185+
//Constructor takes in a vector of leaves
186+
fn new(vec: ~[LeafElt<K, V>]) -> Leaf<K, V>{
187+
Leaf{
188+
elts: vec
189+
}
190+
}
191+
192+
193+
fn get(&self, k: K) -> Option<V>{
194+
for s in self.elts.iter(){
195+
let order=s.key.cmp(&k);
196+
match order{
197+
Equal => return Some(s.value.clone()),
198+
_ => {}
199+
}
200+
}
201+
return None;
202+
}
203+
204+
//Add method in progress
205+
fn add(&self, k: K, v: V) -> Node<K, V>{
206+
return Node::new_leaf(~[LeafElt::new(k, v)]);
207+
}
208+
209+
}
210+
211+
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for Leaf<K, V>{
212+
fn to_str(&self) -> ~str{
213+
let mut ret=~"";
214+
for s in self.elts.iter(){
215+
ret = ret+" // "+ s.to_str();
216+
}
217+
return ret;
218+
}
219+
220+
}
221+
222+
223+
impl<K: Clone + TotalOrd, V: Clone> Branch<K, V>{
224+
//constructor takes a branch vector and a rightmost child
225+
fn new(vec: ~[BranchElt<K, V>], right: ~Node<K, V>) -> Branch<K, V>{
226+
Branch{
227+
elts: vec,
228+
rightmost_child: right
229+
}
230+
}
231+
232+
fn get(&self, k: K) -> Option<V>{
233+
for s in self.elts.iter(){
234+
let order = s.key.cmp(&k);
235+
match order{
236+
Less => return s.left.get(k),
237+
Equal => return Some(s.value.clone()),
238+
_ => {}
239+
}
240+
}
241+
return self.rightmost_child.get(k);
242+
}
243+
244+
245+
//Add method in progress
246+
fn add(&self, k: K, v: V) -> Node<K, V>{
247+
return Node::new_leaf(~[LeafElt::new(k, v)]);
248+
}
249+
}
250+
251+
//No left child
252+
struct LeafElt<K, V>{
253+
key: K,
254+
value: V
255+
}
256+
257+
//Has a left child
258+
struct BranchElt<K, V>{
259+
left: Node<K, V>,
260+
key: K,
261+
value: V
262+
}
263+
264+
impl<K: Clone + TotalOrd, V> LeafElt<K, V>{
265+
fn new(k: K, v: V) -> LeafElt<K, V>{
266+
LeafElt{
267+
key: k,
268+
value: v
269+
}
270+
}
271+
272+
fn less_than(&self, other: LeafElt<K, V>) -> bool{
273+
let order = self.key.cmp(&other.key);
274+
match order{
275+
Less => true,
276+
_ => false
277+
}
278+
}
279+
280+
fn greater_than(&self, other: LeafElt<K, V>) -> bool{
281+
let order = self.key.cmp(&other.key);
282+
match order{
283+
Greater => true,
284+
_ => false
285+
}
286+
}
287+
288+
289+
fn has_key(&self, other: K) -> bool{
290+
let order = self.key.cmp(&other);
291+
match order{
292+
Equal => true,
293+
_ => false
294+
}
295+
}
296+
297+
}
298+
299+
impl<K: Clone + TotalOrd, V: Clone> Clone for LeafElt<K, V>{
300+
fn clone(&self) -> LeafElt<K, V>{
301+
return LeafElt::new(self.key.clone(), self.value.clone());
302+
}
303+
}
304+
305+
impl<K: ToStr + TotalOrd, V: ToStr> ToStr for LeafElt<K, V>{
306+
fn to_str(&self) -> ~str{
307+
return "Key: "+self.key.to_str()+", value: "+self.value.to_str()+"; ";
308+
}
309+
310+
}
311+
312+
impl<K: Clone + TotalOrd, V: Clone> BranchElt<K, V>{
313+
fn new(k: K, v: V, n: Node<K, V>) -> BranchElt<K, V>{
314+
BranchElt{
315+
left: n,
316+
key: k,
317+
value: v
318+
}
319+
}
320+
321+
//Add method in progress. Should it return a branch or a leaf elt? It will depend on implementation.
322+
fn add(&self, k: K, v: V) -> LeafElt<K, V>{
323+
return LeafElt::new(k, v);
324+
}
325+
}
326+
327+
impl<K: Clone + TotalOrd, V: Clone> Clone for BranchElt<K, V>{
328+
fn clone(&self) -> BranchElt<K, V>{
329+
return BranchElt::new(self.key.clone(), self.value.clone(), self.left.clone());
330+
}
331+
}
332+
333+
#[test]
334+
fn add_test(){
335+
let b = BTree::new(1, ~"abc", 2);
336+
let is_add = b.add(2, ~"xyz");
337+
assert!(is_add);
338+
339+
}
340+
341+
#[test]
342+
fn get_test(){
343+
let b = BTree::new(1, ~"abc", 2);
344+
let val = b.get(1);
345+
assert_eq!(val, Some(~"abc"));
346+
}
347+
348+
//Testing LeafElt<K, V> functions (less_than, greater_than, and has_key)
349+
#[test]
350+
fn leaf_lt(){
351+
let l1 = LeafElt::new(1, ~"abc");
352+
let l2 = LeafElt::new(2, ~"xyz");
353+
assert!(l1.less_than(l2));
354+
}
355+
356+
#[test]
357+
fn leaf_gt(){
358+
let l1 = LeafElt::new(1, ~"abc");
359+
let l2 = LeafElt::new(2, ~"xyz");
360+
assert!(l2.greater_than(l1));
361+
}
362+
363+
#[test]
364+
fn leaf_hk(){
365+
let l1 = LeafElt::new(1, ~"abc");
366+
assert!(l1.has_key(1));
367+
}
368+
369+
fn main(){
370+
371+
372+
}

0 commit comments

Comments
 (0)