-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathNode.java
More file actions
140 lines (125 loc) · 3.66 KB
/
Node.java
File metadata and controls
140 lines (125 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
* Sequential B*-Tree implementation for the
* Concurrent Search Tree Project for
* Parallel Computing I
*
* Author: David C. Larsen <dcl9934@cs.rit.edu>
* Author: Benjamin David Mayes <bdm8233@rit.edu>
* Date: April. 12, 2011
*/
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* A B-Tree node.
*/
public abstract class Node<K extends Comparable,V>
{
public static int locks = 0;
public static int unlocks = 0;
protected static int numKeysPerNode = 6;
protected int numKeys;
protected K[] keys;
protected Node<K,V> parent = null;
protected Node<K,V> next = null;
protected Lock lock = null;
/**
* Creates a node with an intial value and the given parent.
*
* @param key The initial key in this node.
*/
@SuppressWarnings({"unchecked"})
public Node( K key )
{
// Like: keys = new K[numKeysPerNode], but working around Java's
// type-erasure approach to generics.
// This cast will always work because Array dynamically creates the
// generic array of the correct type. Still, we have to do an
// "unchecked" cast, and we don't want to be warned about it,
// because we've already guaranteed the type safety.
keys = (K[])(Array.newInstance( key.getClass(), numKeysPerNode + + 1 ));
keys[0] = key;
numKeys = 1;
lock = new ReentrantLock();
}
/**
* Creates a node with the given keys and parent.
*
* @param keys The keys in this node.
* @param parent The parent node.
*/
protected Node( K[] keys, int numKeys, Node<K,V> parent, Node<K,V> next ) {
this.keys = Utilities.copyOf( keys, numKeysPerNode + 1 );
this.numKeys = numKeys;
this.parent = parent;
this.next = next;
lock = new ReentrantLock();
}
/**
* Obtains the number of keys in this Node.
*
* @return The number of keys in this node.
*/
public int numKeys() {
return numKeys;
}
/**
* Obtains the next node on the same level as this node.
*
* @return The next node on the same level.
*/
public Node<K,V> getNext() {
return next;
}
/**
* Find the lowest number in the range of Keys in this Node.
*
* @return The lowerbound of the values in this node.
*/
public K lowerBound()
{
return keys[0];
}
/**
* Find the highest number in the range of Keys in this Node.
*
* @return The upperbound of the values in this node.
*/
public K upperUpper()
{
return keys[numKeys-1];
}
/**
* Returns a child node such that K is within its bounds.
*
* @param key The key of the desired child.
* @return The child to search for the key or the value corresponding to
* the key depending on the type of node.
*/
public abstract Union<Node<K,V>,V> getChild( K key );
/**
* Splits a node into two nodes, returning the second node.
*/
//public abstract Union<InternalNode<K,V>,LeafNode<K,V>> split( K key, V value );
public K[] getKeys() {
return Utilities.copyOfRange(keys,0,numKeys);
}
/**
* Obtains a lock on this node.
*/
public void lock() {
lock.lock();
System.out.println( "LOCKS: " + (++locks) );
}
/**
* Unlocks this node if called by the Thread owning the lock.
*/
public void unlock() {
lock.unlock();
System.out.println( "UNLOCKS: " + (++unlocks) );
}
public boolean isLocked() {
return ((ReentrantLock)lock).isLocked();
}
}