redid the braces and added the findProperties function
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@352741 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
752ef86096
commit
64d1de512c
@ -57,6 +57,7 @@ package org.apache.poi.hdf.model.util;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import org.apache.poi.hdf.model.hdftypes.PropertyNode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A B-Tree like implementation of the java.util.Set inteface. This is a modifiable set
|
* A B-Tree like implementation of the java.util.Set inteface. This is a modifiable set
|
||||||
@ -73,7 +74,8 @@ import java.util.*;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class BTreeSet extends AbstractSet implements Set {
|
public class BTreeSet extends AbstractSet
|
||||||
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Instance Variables
|
* Instance Variables
|
||||||
@ -90,20 +92,24 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* at construction it defaults to 32.
|
* at construction it defaults to 32.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public BTreeSet() {
|
public BTreeSet()
|
||||||
|
{
|
||||||
this(6); // Default order for a BTreeSet is 32
|
this(6); // Default order for a BTreeSet is 32
|
||||||
}
|
}
|
||||||
|
|
||||||
public BTreeSet(Collection c) {
|
public BTreeSet(Collection c)
|
||||||
|
{
|
||||||
this(6); // Default order for a BTreeSet is 32
|
this(6); // Default order for a BTreeSet is 32
|
||||||
addAll(c);
|
addAll(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BTreeSet(int order) {
|
public BTreeSet(int order)
|
||||||
|
{
|
||||||
this(order, null);
|
this(order, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BTreeSet(int order, Comparator comparator) {
|
public BTreeSet(int order, Comparator comparator)
|
||||||
|
{
|
||||||
this.order = order;
|
this.order = order;
|
||||||
this.comparator = comparator;
|
this.comparator = comparator;
|
||||||
root = new BTreeNode(null);
|
root = new BTreeNode(null);
|
||||||
@ -113,38 +119,99 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
/*
|
/*
|
||||||
* Public Methods
|
* Public Methods
|
||||||
*/
|
*/
|
||||||
public boolean add(Object x) throws IllegalArgumentException {
|
public boolean add(Object x) throws IllegalArgumentException
|
||||||
|
{
|
||||||
if (x == null) throw new IllegalArgumentException();
|
if (x == null) throw new IllegalArgumentException();
|
||||||
return root.insert(x, -1);
|
return root.insert(x, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(Object x) {
|
public boolean contains(Object x)
|
||||||
|
{
|
||||||
return root.includes(x);
|
return root.includes(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean remove(Object x) {
|
public boolean remove(Object x)
|
||||||
|
{
|
||||||
if (x == null) return false;
|
if (x == null) return false;
|
||||||
return root.delete(x, -1);
|
return root.delete(x, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size()
|
||||||
|
{
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear()
|
||||||
|
{
|
||||||
root = new BTreeNode(null);
|
root = new BTreeNode(null);
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public java.util.Iterator iterator() {
|
public java.util.Iterator iterator()
|
||||||
|
{
|
||||||
return new Iterator();
|
return new Iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ArrayList findProperties(int start, int end, BTreeSet.BTreeNode root)
|
||||||
|
{
|
||||||
|
ArrayList results = new ArrayList();
|
||||||
|
BTreeSet.Entry[] entries = root.entries;
|
||||||
|
|
||||||
|
for(int x = 0; x < entries.length; x++)
|
||||||
|
{
|
||||||
|
if(entries[x] != null)
|
||||||
|
{
|
||||||
|
BTreeSet.BTreeNode child = entries[x].child;
|
||||||
|
PropertyNode xNode = (PropertyNode)entries[x].element;
|
||||||
|
if(xNode != null)
|
||||||
|
{
|
||||||
|
int xStart = xNode.getStart();
|
||||||
|
int xEnd = xNode.getEnd();
|
||||||
|
if(xStart < end)
|
||||||
|
{
|
||||||
|
if(xStart >= start)
|
||||||
|
{
|
||||||
|
if(child != null)
|
||||||
|
{
|
||||||
|
ArrayList beforeItems = findProperties(start, end, child);
|
||||||
|
results.addAll(beforeItems);
|
||||||
|
}
|
||||||
|
results.add(xNode);
|
||||||
|
}
|
||||||
|
else if(start < xEnd)
|
||||||
|
{
|
||||||
|
results.add(xNode);
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(child != null)
|
||||||
|
{
|
||||||
|
ArrayList beforeItems = findProperties(start, end, child);
|
||||||
|
results.addAll(beforeItems);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(child != null)
|
||||||
|
{
|
||||||
|
ArrayList afterItems = findProperties(start, end, child);
|
||||||
|
results.addAll(afterItems);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Private methods
|
* Private methods
|
||||||
*/
|
*/
|
||||||
private int compare(Object x, Object y) {
|
private int compare(Object x, Object y)
|
||||||
|
{
|
||||||
return (comparator == null ? ((Comparable)x).compareTo(y) : comparator.compare(x, y));
|
return (comparator == null ? ((Comparable)x).compareTo(y) : comparator.compare(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,23 +230,27 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* chance of receiving a NullPointerException. The Iterator.delete method is supported.
|
* chance of receiving a NullPointerException. The Iterator.delete method is supported.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private class Iterator implements java.util.Iterator {
|
private class Iterator implements java.util.Iterator
|
||||||
|
{
|
||||||
private int index = 0;
|
private int index = 0;
|
||||||
private Stack parentIndex = new Stack(); // Contains all parentIndicies for currentNode
|
private Stack parentIndex = new Stack(); // Contains all parentIndicies for currentNode
|
||||||
private Object lastReturned = null;
|
private Object lastReturned = null;
|
||||||
private Object next;
|
private Object next;
|
||||||
private BTreeNode currentNode;
|
private BTreeNode currentNode;
|
||||||
|
|
||||||
Iterator() {
|
Iterator()
|
||||||
|
{
|
||||||
currentNode = firstNode();
|
currentNode = firstNode();
|
||||||
next = nextElement();
|
next = nextElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext()
|
||||||
|
{
|
||||||
return next != null;
|
return next != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object next() {
|
public Object next()
|
||||||
|
{
|
||||||
if (next == null) throw new NoSuchElementException();
|
if (next == null) throw new NoSuchElementException();
|
||||||
|
|
||||||
lastReturned = next;
|
lastReturned = next;
|
||||||
@ -187,17 +258,20 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
return lastReturned;
|
return lastReturned;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove() {
|
public void remove()
|
||||||
|
{
|
||||||
if (lastReturned == null) throw new NoSuchElementException();
|
if (lastReturned == null) throw new NoSuchElementException();
|
||||||
|
|
||||||
BTreeSet.this.remove(lastReturned);
|
BTreeSet.this.remove(lastReturned);
|
||||||
lastReturned = null;
|
lastReturned = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BTreeNode firstNode() {
|
private BTreeNode firstNode()
|
||||||
|
{
|
||||||
BTreeNode temp = BTreeSet.this.root;
|
BTreeNode temp = BTreeSet.this.root;
|
||||||
|
|
||||||
while (temp.entries[0].child != null) {
|
while (temp.entries[0].child != null)
|
||||||
|
{
|
||||||
temp = temp.entries[0].child;
|
temp = temp.entries[0].child;
|
||||||
parentIndex.push(new Integer(0));
|
parentIndex.push(new Integer(0));
|
||||||
}
|
}
|
||||||
@ -205,15 +279,19 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object nextElement() {
|
private Object nextElement()
|
||||||
if (currentNode.isLeaf()) {
|
{
|
||||||
|
if (currentNode.isLeaf())
|
||||||
|
{
|
||||||
if (index < currentNode.nrElements) return currentNode.entries[index++].element;
|
if (index < currentNode.nrElements) return currentNode.entries[index++].element;
|
||||||
|
|
||||||
else if (!parentIndex.empty()) { //All elements have been returned, return successor of lastReturned if it exists
|
else if (!parentIndex.empty())
|
||||||
|
{ //All elements have been returned, return successor of lastReturned if it exists
|
||||||
currentNode = currentNode.parent;
|
currentNode = currentNode.parent;
|
||||||
index = ((Integer)parentIndex.pop()).intValue();
|
index = ((Integer)parentIndex.pop()).intValue();
|
||||||
|
|
||||||
while (index == currentNode.nrElements) {
|
while (index == currentNode.nrElements)
|
||||||
|
{
|
||||||
if (parentIndex.empty()) break;
|
if (parentIndex.empty()) break;
|
||||||
currentNode = currentNode.parent;
|
currentNode = currentNode.parent;
|
||||||
index = ((Integer)parentIndex.pop()).intValue();
|
index = ((Integer)parentIndex.pop()).intValue();
|
||||||
@ -223,17 +301,20 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
return currentNode.entries[index++].element;
|
return currentNode.entries[index++].element;
|
||||||
}
|
}
|
||||||
|
|
||||||
else { //Your a leaf and the root
|
else
|
||||||
|
{ //Your a leaf and the root
|
||||||
if (index == currentNode.nrElements) return null;
|
if (index == currentNode.nrElements) return null;
|
||||||
return currentNode.entries[index++].element;
|
return currentNode.entries[index++].element;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else { //Your not a leaf so simply find and return the successor of lastReturned
|
else
|
||||||
|
{ //Your not a leaf so simply find and return the successor of lastReturned
|
||||||
currentNode = currentNode.entries[index].child;
|
currentNode = currentNode.entries[index].child;
|
||||||
parentIndex.push(new Integer(index));
|
parentIndex.push(new Integer(index));
|
||||||
|
|
||||||
while (currentNode.entries[0].child != null) {
|
while (currentNode.entries[0].child != null)
|
||||||
|
{
|
||||||
currentNode = currentNode.entries[0].child;
|
currentNode = currentNode.entries[0].child;
|
||||||
parentIndex.push(new Integer(0));
|
parentIndex.push(new Integer(0));
|
||||||
}
|
}
|
||||||
@ -245,75 +326,89 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class Entry {
|
public static class Entry
|
||||||
|
{
|
||||||
|
|
||||||
public Object element;
|
public Object element;
|
||||||
public BTreeNode child;
|
public BTreeNode child;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class BTreeNode {
|
public class BTreeNode
|
||||||
|
{
|
||||||
|
|
||||||
public Entry[] entries;
|
public Entry[] entries;
|
||||||
public BTreeNode parent;
|
public BTreeNode parent;
|
||||||
private int nrElements = 0;
|
private int nrElements = 0;
|
||||||
private final int MIN = (BTreeSet.this.order - 1) / 2;
|
private final int MIN = (BTreeSet.this.order - 1) / 2;
|
||||||
|
|
||||||
BTreeNode(BTreeNode parent) {
|
BTreeNode(BTreeNode parent)
|
||||||
|
{
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
entries = new Entry[BTreeSet.this.order];
|
entries = new Entry[BTreeSet.this.order];
|
||||||
entries[0] = new Entry();
|
entries[0] = new Entry();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean insert(Object x, int parentIndex) {
|
boolean insert(Object x, int parentIndex)
|
||||||
if (isFull()) { // If full, you must split and promote splitNode before inserting
|
{
|
||||||
|
if (isFull())
|
||||||
|
{ // If full, you must split and promote splitNode before inserting
|
||||||
Object splitNode = entries[nrElements / 2].element;
|
Object splitNode = entries[nrElements / 2].element;
|
||||||
BTreeNode rightSibling = split();
|
BTreeNode rightSibling = split();
|
||||||
|
|
||||||
if (isRoot()) { // Grow a level
|
if (isRoot())
|
||||||
|
{ // Grow a level
|
||||||
splitRoot(splitNode, this, rightSibling);
|
splitRoot(splitNode, this, rightSibling);
|
||||||
// Determine where to insert
|
// Determine where to insert
|
||||||
if (BTreeSet.this.compare(x, BTreeSet.this.root.entries[0].element) < 0) insert(x, 0);
|
if (BTreeSet.this.compare(x, BTreeSet.this.root.entries[0].element) < 0) insert(x, 0);
|
||||||
else rightSibling.insert(x, 1);
|
else rightSibling.insert(x, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // Promote splitNode
|
else
|
||||||
|
{ // Promote splitNode
|
||||||
parent.insertSplitNode(splitNode, this, rightSibling, parentIndex);
|
parent.insertSplitNode(splitNode, this, rightSibling, parentIndex);
|
||||||
if (BTreeSet.this.compare(x, parent.entries[parentIndex].element) < 0) return insert(x, parentIndex);
|
if (BTreeSet.this.compare(x, parent.entries[parentIndex].element) < 0) return insert(x, parentIndex);
|
||||||
else return rightSibling.insert(x, parentIndex + 1);
|
else return rightSibling.insert(x, parentIndex + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isLeaf()) { // If leaf, simply insert the non-duplicate element
|
else if (isLeaf())
|
||||||
|
{ // If leaf, simply insert the non-duplicate element
|
||||||
int insertAt = childToInsertAt(x, true);
|
int insertAt = childToInsertAt(x, true);
|
||||||
if (insertAt == -1) return false; // Determine if the element already exists
|
if (insertAt == -1) return false; // Determine if the element already exists
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
insertNewElement(x, insertAt);
|
insertNewElement(x, insertAt);
|
||||||
BTreeSet.this.size++;
|
BTreeSet.this.size++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // If not full and not leaf recursively find correct node to insert at
|
else
|
||||||
|
{ // If not full and not leaf recursively find correct node to insert at
|
||||||
int insertAt = childToInsertAt(x, true);
|
int insertAt = childToInsertAt(x, true);
|
||||||
return (insertAt == -1 ? false : entries[insertAt].child.insert(x, insertAt));
|
return (insertAt == -1 ? false : entries[insertAt].child.insert(x, insertAt));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean includes(Object x) {
|
boolean includes(Object x)
|
||||||
|
{
|
||||||
int index = childToInsertAt(x, true);
|
int index = childToInsertAt(x, true);
|
||||||
if (index == -1) return true;
|
if (index == -1) return true;
|
||||||
if (entries[index] == null || entries[index].child == null) return false;
|
if (entries[index] == null || entries[index].child == null) return false;
|
||||||
return entries[index].child.includes(x);
|
return entries[index].child.includes(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean delete(Object x, int parentIndex) {
|
boolean delete(Object x, int parentIndex)
|
||||||
|
{
|
||||||
int i = childToInsertAt(x, true);
|
int i = childToInsertAt(x, true);
|
||||||
int priorParentIndex = parentIndex;
|
int priorParentIndex = parentIndex;
|
||||||
BTreeNode temp = this;
|
BTreeNode temp = this;
|
||||||
if (i != -1) {
|
if (i != -1)
|
||||||
do {
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
if (temp.entries[i] == null || temp.entries[i].child == null) return false;
|
if (temp.entries[i] == null || temp.entries[i].child == null) return false;
|
||||||
temp = temp.entries[i].child;
|
temp = temp.entries[i].child;
|
||||||
priorParentIndex = parentIndex;
|
priorParentIndex = parentIndex;
|
||||||
@ -322,14 +417,17 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
} while (i != -1);
|
} while (i != -1);
|
||||||
} // Now temp contains element to delete and temp's parentIndex is parentIndex
|
} // Now temp contains element to delete and temp's parentIndex is parentIndex
|
||||||
|
|
||||||
if (temp.isLeaf()) { // If leaf and have more than MIN elements, simply delete
|
if (temp.isLeaf())
|
||||||
if (temp.nrElements > MIN) {
|
{ // If leaf and have more than MIN elements, simply delete
|
||||||
|
if (temp.nrElements > MIN)
|
||||||
|
{
|
||||||
temp.deleteElement(x);
|
temp.deleteElement(x);
|
||||||
BTreeSet.this.size--;
|
BTreeSet.this.size--;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // If leaf and have less than MIN elements, than prepare the BTreeSet for deletion
|
else
|
||||||
|
{ // If leaf and have less than MIN elements, than prepare the BTreeSet for deletion
|
||||||
temp.prepareForDeletion(parentIndex);
|
temp.prepareForDeletion(parentIndex);
|
||||||
temp.deleteElement(x);
|
temp.deleteElement(x);
|
||||||
BTreeSet.this.size--;
|
BTreeSet.this.size--;
|
||||||
@ -338,7 +436,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // Only delete at leaf so first switch with successor than delete
|
else
|
||||||
|
{ // Only delete at leaf so first switch with successor than delete
|
||||||
temp.switchWithSuccessor(x);
|
temp.switchWithSuccessor(x);
|
||||||
parentIndex = temp.childToInsertAt(x, false) + 1;
|
parentIndex = temp.childToInsertAt(x, false) + 1;
|
||||||
return temp.entries[parentIndex].child.delete(x, parentIndex);
|
return temp.entries[parentIndex].child.delete(x, parentIndex);
|
||||||
@ -356,12 +455,14 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* Splits a BTreeNode into two BTreeNodes, removing the splitNode from the
|
* Splits a BTreeNode into two BTreeNodes, removing the splitNode from the
|
||||||
* calling BTreeNode.
|
* calling BTreeNode.
|
||||||
*/
|
*/
|
||||||
private BTreeNode split() {
|
private BTreeNode split()
|
||||||
|
{
|
||||||
BTreeNode rightSibling = new BTreeNode(parent);
|
BTreeNode rightSibling = new BTreeNode(parent);
|
||||||
int index = nrElements / 2;
|
int index = nrElements / 2;
|
||||||
entries[index++].element = null;
|
entries[index++].element = null;
|
||||||
|
|
||||||
for (int i = 0, nr = nrElements; index <= nr; i++, index++) {
|
for (int i = 0, nr = nrElements; index <= nr; i++, index++)
|
||||||
|
{
|
||||||
rightSibling.entries[i] = entries[index];
|
rightSibling.entries[i] = entries[index];
|
||||||
if (rightSibling.entries[i] != null && rightSibling.entries[i].child != null)
|
if (rightSibling.entries[i] != null && rightSibling.entries[i].child != null)
|
||||||
rightSibling.entries[i].child.parent = rightSibling;
|
rightSibling.entries[i].child.parent = rightSibling;
|
||||||
@ -378,7 +479,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* Creates a new BTreeSet.root which contains only the splitNode and pointers
|
* Creates a new BTreeSet.root which contains only the splitNode and pointers
|
||||||
* to it's left and right child.
|
* to it's left and right child.
|
||||||
*/
|
*/
|
||||||
private void splitRoot(Object splitNode, BTreeNode left, BTreeNode right) {
|
private void splitRoot(Object splitNode, BTreeNode left, BTreeNode right)
|
||||||
|
{
|
||||||
BTreeNode newRoot = new BTreeNode(null);
|
BTreeNode newRoot = new BTreeNode(null);
|
||||||
newRoot.entries[0].element = splitNode;
|
newRoot.entries[0].element = splitNode;
|
||||||
newRoot.entries[0].child = left;
|
newRoot.entries[0].child = left;
|
||||||
@ -389,7 +491,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
BTreeSet.this.root = newRoot;
|
BTreeSet.this.root = newRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertSplitNode(Object splitNode, BTreeNode left, BTreeNode right, int insertAt) {
|
private void insertSplitNode(Object splitNode, BTreeNode left, BTreeNode right, int insertAt)
|
||||||
|
{
|
||||||
for (int i = nrElements; i >= insertAt; i--) entries[i + 1] = entries[i];
|
for (int i = nrElements; i >= insertAt; i--) entries[i + 1] = entries[i];
|
||||||
|
|
||||||
entries[insertAt] = new Entry();
|
entries[insertAt] = new Entry();
|
||||||
@ -400,7 +503,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
nrElements++;
|
nrElements++;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insertNewElement(Object x, int insertAt) {
|
private void insertNewElement(Object x, int insertAt)
|
||||||
|
{
|
||||||
|
|
||||||
for (int i = nrElements; i > insertAt; i--) entries[i] = entries[i - 1];
|
for (int i = nrElements; i > insertAt; i--) entries[i] = entries[i - 1];
|
||||||
|
|
||||||
@ -419,18 +523,22 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* element is contained in the calling BTreeNode than the position of the element
|
* element is contained in the calling BTreeNode than the position of the element
|
||||||
* in entries[] is returned.
|
* in entries[] is returned.
|
||||||
*/
|
*/
|
||||||
private int childToInsertAt(Object x, boolean position) {
|
private int childToInsertAt(Object x, boolean position)
|
||||||
|
{
|
||||||
int index = nrElements / 2;
|
int index = nrElements / 2;
|
||||||
|
|
||||||
if (entries[index] == null || entries[index].element == null) return index;
|
if (entries[index] == null || entries[index].element == null) return index;
|
||||||
|
|
||||||
int lo = 0, hi = nrElements - 1;
|
int lo = 0, hi = nrElements - 1;
|
||||||
while (lo <= hi) {
|
while (lo <= hi)
|
||||||
if (BTreeSet.this.compare(x, entries[index].element) > 0) {
|
{
|
||||||
|
if (BTreeSet.this.compare(x, entries[index].element) > 0)
|
||||||
|
{
|
||||||
lo = index + 1;
|
lo = index + 1;
|
||||||
index = (hi + lo) / 2;
|
index = (hi + lo) / 2;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
hi = index - 1;
|
hi = index - 1;
|
||||||
index = (hi + lo) / 2;
|
index = (hi + lo) / 2;
|
||||||
}
|
}
|
||||||
@ -442,7 +550,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void deleteElement(Object x) {
|
private void deleteElement(Object x)
|
||||||
|
{
|
||||||
int index = childToInsertAt(x, false);
|
int index = childToInsertAt(x, false);
|
||||||
for (; index < (nrElements - 1); index++) entries[index] = entries[index + 1];
|
for (; index < (nrElements - 1); index++) entries[index] = entries[index + 1];
|
||||||
|
|
||||||
@ -452,17 +561,20 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
nrElements--;
|
nrElements--;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareForDeletion(int parentIndex) {
|
private void prepareForDeletion(int parentIndex)
|
||||||
|
{
|
||||||
if (isRoot()) return; // Don't attempt to steal or merge if your the root
|
if (isRoot()) return; // Don't attempt to steal or merge if your the root
|
||||||
|
|
||||||
// If not root then try to steal left
|
// If not root then try to steal left
|
||||||
else if (parentIndex != 0 && parent.entries[parentIndex - 1].child.nrElements > MIN) {
|
else if (parentIndex != 0 && parent.entries[parentIndex - 1].child.nrElements > MIN)
|
||||||
|
{
|
||||||
stealLeft(parentIndex);
|
stealLeft(parentIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not root and can't steal left try to steal right
|
// If not root and can't steal left try to steal right
|
||||||
else if (parentIndex < entries.length && parent.entries[parentIndex + 1] != null && parent.entries[parentIndex + 1].child != null && parent.entries[parentIndex + 1].child.nrElements > MIN) {
|
else if (parentIndex < entries.length && parent.entries[parentIndex + 1] != null && parent.entries[parentIndex + 1].child != null && parent.entries[parentIndex + 1].child.nrElements > MIN)
|
||||||
|
{
|
||||||
stealRight(parentIndex);
|
stealRight(parentIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -477,14 +589,17 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
else mergeRight(parentIndex);
|
else mergeRight(parentIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fixAfterDeletion(int parentIndex) {
|
private void fixAfterDeletion(int parentIndex)
|
||||||
|
{
|
||||||
if (isRoot() || parent.isRoot()) return; // No fixing needed
|
if (isRoot() || parent.isRoot()) return; // No fixing needed
|
||||||
|
|
||||||
if (parent.nrElements < MIN) { // If parent lost it's n/2 element repair it
|
if (parent.nrElements < MIN)
|
||||||
|
{ // If parent lost it's n/2 element repair it
|
||||||
BTreeNode temp = parent;
|
BTreeNode temp = parent;
|
||||||
temp.prepareForDeletion(parentIndex);
|
temp.prepareForDeletion(parentIndex);
|
||||||
if (temp.parent == null) return; // Root changed
|
if (temp.parent == null) return; // Root changed
|
||||||
if (!temp.parent.isRoot() && temp.parent.nrElements < MIN) { // If need be recurse
|
if (!temp.parent.isRoot() && temp.parent.nrElements < MIN)
|
||||||
|
{ // If need be recurse
|
||||||
BTreeNode x = temp.parent.parent;
|
BTreeNode x = temp.parent.parent;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
// Find parent's parentIndex
|
// Find parent's parentIndex
|
||||||
@ -494,7 +609,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void switchWithSuccessor(Object x) {
|
private void switchWithSuccessor(Object x)
|
||||||
|
{
|
||||||
int index = childToInsertAt(x, false);
|
int index = childToInsertAt(x, false);
|
||||||
BTreeNode temp = entries[index + 1].child;
|
BTreeNode temp = entries[index + 1].child;
|
||||||
while (temp.entries[0] != null && temp.entries[0].child != null) temp = temp.entries[0].child;
|
while (temp.entries[0] != null && temp.entries[0].child != null) temp = temp.entries[0].child;
|
||||||
@ -507,11 +623,13 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* This method is called only when the BTreeNode has the minimum number of elements,
|
* This method is called only when the BTreeNode has the minimum number of elements,
|
||||||
* has a leftSibling, and the leftSibling has more than the minimum number of elements.
|
* has a leftSibling, and the leftSibling has more than the minimum number of elements.
|
||||||
*/
|
*/
|
||||||
private void stealLeft(int parentIndex) {
|
private void stealLeft(int parentIndex)
|
||||||
|
{
|
||||||
BTreeNode p = parent;
|
BTreeNode p = parent;
|
||||||
BTreeNode ls = parent.entries[parentIndex - 1].child;
|
BTreeNode ls = parent.entries[parentIndex - 1].child;
|
||||||
|
|
||||||
if (isLeaf()) { // When stealing from leaf to leaf don't worry about children
|
if (isLeaf())
|
||||||
|
{ // When stealing from leaf to leaf don't worry about children
|
||||||
int add = childToInsertAt(p.entries[parentIndex - 1].element, true);
|
int add = childToInsertAt(p.entries[parentIndex - 1].element, true);
|
||||||
insertNewElement(p.entries[parentIndex - 1].element, add);
|
insertNewElement(p.entries[parentIndex - 1].element, add);
|
||||||
p.entries[parentIndex - 1].element = ls.entries[ls.nrElements - 1].element;
|
p.entries[parentIndex - 1].element = ls.entries[ls.nrElements - 1].element;
|
||||||
@ -519,7 +637,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
ls.nrElements--;
|
ls.nrElements--;
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // Was called recursively to fix an undermanned parent
|
else
|
||||||
|
{ // Was called recursively to fix an undermanned parent
|
||||||
entries[0].element = p.entries[parentIndex - 1].element;
|
entries[0].element = p.entries[parentIndex - 1].element;
|
||||||
p.entries[parentIndex - 1].element = ls.entries[ls.nrElements - 1].element;
|
p.entries[parentIndex - 1].element = ls.entries[ls.nrElements - 1].element;
|
||||||
entries[0].child = ls.entries[ls.nrElements].child;
|
entries[0].child = ls.entries[ls.nrElements].child;
|
||||||
@ -536,11 +655,13 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* has the minimum number of elements, has a rightSibling, and the rightSibling
|
* has the minimum number of elements, has a rightSibling, and the rightSibling
|
||||||
* has more than the minimum number of elements.
|
* has more than the minimum number of elements.
|
||||||
*/
|
*/
|
||||||
private void stealRight(int parentIndex) {
|
private void stealRight(int parentIndex)
|
||||||
|
{
|
||||||
BTreeNode p = parent;
|
BTreeNode p = parent;
|
||||||
BTreeNode rs = p.entries[parentIndex + 1].child;
|
BTreeNode rs = p.entries[parentIndex + 1].child;
|
||||||
|
|
||||||
if (isLeaf()) { // When stealing from leaf to leaf don't worry about children
|
if (isLeaf())
|
||||||
|
{ // When stealing from leaf to leaf don't worry about children
|
||||||
entries[nrElements] = new Entry();
|
entries[nrElements] = new Entry();
|
||||||
entries[nrElements].element = p.entries[parentIndex].element;
|
entries[nrElements].element = p.entries[parentIndex].element;
|
||||||
p.entries[parentIndex].element = rs.entries[0].element;
|
p.entries[parentIndex].element = rs.entries[0].element;
|
||||||
@ -550,7 +671,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
rs.nrElements--;
|
rs.nrElements--;
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // Was called recursively to fix an undermanned parent
|
else
|
||||||
|
{ // Was called recursively to fix an undermanned parent
|
||||||
for (int i = 0; i <= nrElements; i++) entries[i] = entries[i + 1];
|
for (int i = 0; i <= nrElements; i++) entries[i] = entries[i + 1];
|
||||||
entries[nrElements].element = p.entries[parentIndex].element;
|
entries[nrElements].element = p.entries[parentIndex].element;
|
||||||
p.entries[parentIndex].element = rs.entries[0].element;
|
p.entries[parentIndex].element = rs.entries[0].element;
|
||||||
@ -573,11 +695,13 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* mergeLeft, or mergeRight to fix the parent. All of the before-mentioned methods
|
* mergeLeft, or mergeRight to fix the parent. All of the before-mentioned methods
|
||||||
* expect the parent to be in such a condition.
|
* expect the parent to be in such a condition.
|
||||||
*/
|
*/
|
||||||
private void mergeLeft(int parentIndex) {
|
private void mergeLeft(int parentIndex)
|
||||||
|
{
|
||||||
BTreeNode p = parent;
|
BTreeNode p = parent;
|
||||||
BTreeNode ls = p.entries[parentIndex - 1].child;
|
BTreeNode ls = p.entries[parentIndex - 1].child;
|
||||||
|
|
||||||
if (isLeaf()) { // Don't worry about children
|
if (isLeaf())
|
||||||
|
{ // Don't worry about children
|
||||||
int add = childToInsertAt(p.entries[parentIndex - 1].element, true);
|
int add = childToInsertAt(p.entries[parentIndex - 1].element, true);
|
||||||
insertNewElement(p.entries[parentIndex - 1].element, add); // Could have been a successor switch
|
insertNewElement(p.entries[parentIndex - 1].element, add); // Could have been a successor switch
|
||||||
p.entries[parentIndex - 1].element = null;
|
p.entries[parentIndex - 1].element = null;
|
||||||
@ -585,12 +709,14 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
for (int i = nrElements - 1, nr = ls.nrElements; i >= 0; i--)
|
for (int i = nrElements - 1, nr = ls.nrElements; i >= 0; i--)
|
||||||
entries[i + nr] = entries[i];
|
entries[i + nr] = entries[i];
|
||||||
|
|
||||||
for (int i = ls.nrElements - 1; i >= 0; i--) {
|
for (int i = ls.nrElements - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
entries[i] = ls.entries[i];
|
entries[i] = ls.entries[i];
|
||||||
nrElements++;
|
nrElements++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.nrElements == MIN && p != BTreeSet.this.root) {
|
if (p.nrElements == MIN && p != BTreeSet.this.root)
|
||||||
|
{
|
||||||
|
|
||||||
for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x--, y--)
|
for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x--, y--)
|
||||||
p.entries[x] = p.entries[y];
|
p.entries[x] = p.entries[y];
|
||||||
@ -598,7 +724,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
p.entries[0].child = ls; //So p doesn't think it's a leaf this will be deleted in the next recursive call
|
p.entries[0].child = ls; //So p doesn't think it's a leaf this will be deleted in the next recursive call
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
|
|
||||||
for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
|
for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
|
||||||
p.entries[x] = p.entries[y];
|
p.entries[x] = p.entries[y];
|
||||||
@ -607,13 +734,15 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
|
|
||||||
p.nrElements--;
|
p.nrElements--;
|
||||||
|
|
||||||
if (p.isRoot() && p.nrElements == 0) { // It's the root and it's empty
|
if (p.isRoot() && p.nrElements == 0)
|
||||||
|
{ // It's the root and it's empty
|
||||||
BTreeSet.this.root = this;
|
BTreeSet.this.root = this;
|
||||||
parent = null;
|
parent = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // I'm not a leaf but fixing the tree structure
|
else
|
||||||
|
{ // I'm not a leaf but fixing the tree structure
|
||||||
entries[0].element = p.entries[parentIndex - 1].element;
|
entries[0].element = p.entries[parentIndex - 1].element;
|
||||||
entries[0].child = ls.entries[ls.nrElements].child;
|
entries[0].child = ls.entries[ls.nrElements].child;
|
||||||
nrElements++;
|
nrElements++;
|
||||||
@ -621,20 +750,25 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
for (int x = nrElements, nr = ls.nrElements; x >= 0; x--)
|
for (int x = nrElements, nr = ls.nrElements; x >= 0; x--)
|
||||||
entries[x + nr] = entries[x];
|
entries[x + nr] = entries[x];
|
||||||
|
|
||||||
for (int x = ls.nrElements - 1; x >= 0; x--) {
|
for (int x = ls.nrElements - 1; x >= 0; x--)
|
||||||
|
{
|
||||||
entries[x] = ls.entries[x];
|
entries[x] = ls.entries[x];
|
||||||
entries[x].child.parent = this;
|
entries[x].child.parent = this;
|
||||||
nrElements++;
|
nrElements++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p.nrElements == MIN && p != BTreeSet.this.root) { // Push everything to the right
|
if (p.nrElements == MIN && p != BTreeSet.this.root)
|
||||||
for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x++, y++){
|
{ // Push everything to the right
|
||||||
|
for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x++, y++)
|
||||||
|
{
|
||||||
System.out.println(x + " " + y);
|
System.out.println(x + " " + y);
|
||||||
p.entries[x] = p.entries[y];}
|
p.entries[x] = p.entries[y];
|
||||||
|
}
|
||||||
p.entries[0] = new Entry();
|
p.entries[0] = new Entry();
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // Either p.nrElements > MIN or p == BTreeSet.this.root so push everything to the left
|
else
|
||||||
|
{ // Either p.nrElements > MIN or p == BTreeSet.this.root so push everything to the left
|
||||||
for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
|
for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
|
||||||
p.entries[x] = p.entries[y];
|
p.entries[x] = p.entries[y];
|
||||||
p.entries[p.nrElements] = null;
|
p.entries[p.nrElements] = null;
|
||||||
@ -642,7 +776,8 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
|
|
||||||
p.nrElements--;
|
p.nrElements--;
|
||||||
|
|
||||||
if (p.isRoot() && p.nrElements == 0) { // p == BTreeSet.this.root and it's empty
|
if (p.isRoot() && p.nrElements == 0)
|
||||||
|
{ // p == BTreeSet.this.root and it's empty
|
||||||
BTreeSet.this.root = this;
|
BTreeSet.this.root = this;
|
||||||
parent = null;
|
parent = null;
|
||||||
}
|
}
|
||||||
@ -658,45 +793,53 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
* mergeLeft, or mergeRight to fix the parent. All of the before-mentioned methods
|
* mergeLeft, or mergeRight to fix the parent. All of the before-mentioned methods
|
||||||
* expect the parent to be in such a condition.
|
* expect the parent to be in such a condition.
|
||||||
*/
|
*/
|
||||||
private void mergeRight(int parentIndex) {
|
private void mergeRight(int parentIndex)
|
||||||
|
{
|
||||||
BTreeNode p = parent;
|
BTreeNode p = parent;
|
||||||
BTreeNode rs = p.entries[parentIndex + 1].child;
|
BTreeNode rs = p.entries[parentIndex + 1].child;
|
||||||
|
|
||||||
if (isLeaf()) { // Don't worry about children
|
if (isLeaf())
|
||||||
|
{ // Don't worry about children
|
||||||
entries[nrElements] = new Entry();
|
entries[nrElements] = new Entry();
|
||||||
entries[nrElements].element = p.entries[parentIndex].element;
|
entries[nrElements].element = p.entries[parentIndex].element;
|
||||||
nrElements++;
|
nrElements++;
|
||||||
for (int i = 0, nr = nrElements; i < rs.nrElements; i++, nr++) {
|
for (int i = 0, nr = nrElements; i < rs.nrElements; i++, nr++)
|
||||||
|
{
|
||||||
entries[nr] = rs.entries[i];
|
entries[nr] = rs.entries[i];
|
||||||
nrElements++;
|
nrElements++;
|
||||||
}
|
}
|
||||||
p.entries[parentIndex].element = p.entries[parentIndex + 1].element;
|
p.entries[parentIndex].element = p.entries[parentIndex + 1].element;
|
||||||
if (p.nrElements == MIN && p != BTreeSet.this.root) {
|
if (p.nrElements == MIN && p != BTreeSet.this.root)
|
||||||
|
{
|
||||||
for (int x = parentIndex + 1, y = parentIndex; y >= 0; x--, y--)
|
for (int x = parentIndex + 1, y = parentIndex; y >= 0; x--, y--)
|
||||||
p.entries[x] = p.entries[y];
|
p.entries[x] = p.entries[y];
|
||||||
p.entries[0] = new Entry();
|
p.entries[0] = new Entry();
|
||||||
p.entries[0].child = rs; // So it doesn't think it's a leaf, this child will be deleted in the next recursive call
|
p.entries[0].child = rs; // So it doesn't think it's a leaf, this child will be deleted in the next recursive call
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
for (int x = parentIndex + 1, y = parentIndex + 2; y <= p.nrElements; x++, y++)
|
for (int x = parentIndex + 1, y = parentIndex + 2; y <= p.nrElements; x++, y++)
|
||||||
p.entries[x] = p.entries[y];
|
p.entries[x] = p.entries[y];
|
||||||
p.entries[p.nrElements] = null;
|
p.entries[p.nrElements] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.nrElements--;
|
p.nrElements--;
|
||||||
if (p.isRoot() && p.nrElements == 0) { // It's the root and it's empty
|
if (p.isRoot() && p.nrElements == 0)
|
||||||
|
{ // It's the root and it's empty
|
||||||
BTreeSet.this.root = this;
|
BTreeSet.this.root = this;
|
||||||
parent = null;
|
parent = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // It's not a leaf
|
else
|
||||||
|
{ // It's not a leaf
|
||||||
|
|
||||||
entries[nrElements].element = p.entries[parentIndex].element;
|
entries[nrElements].element = p.entries[parentIndex].element;
|
||||||
nrElements++;
|
nrElements++;
|
||||||
|
|
||||||
for (int x = nrElements + 1, y = 0; y <= rs.nrElements; x++, y++) {
|
for (int x = nrElements + 1, y = 0; y <= rs.nrElements; x++, y++)
|
||||||
|
{
|
||||||
entries[x] = rs.entries[y];
|
entries[x] = rs.entries[y];
|
||||||
rs.entries[y].child.parent = this;
|
rs.entries[y].child.parent = this;
|
||||||
nrElements++;
|
nrElements++;
|
||||||
@ -705,13 +848,15 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
|
|
||||||
p.entries[++parentIndex].child = this;
|
p.entries[++parentIndex].child = this;
|
||||||
|
|
||||||
if (p.nrElements == MIN && p != BTreeSet.this.root) {
|
if (p.nrElements == MIN && p != BTreeSet.this.root)
|
||||||
|
{
|
||||||
for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x--, y--)
|
for (int x = parentIndex - 1, y = parentIndex - 2; y >= 0; x--, y--)
|
||||||
p.entries[x] = p.entries[y];
|
p.entries[x] = p.entries[y];
|
||||||
p.entries[0] = new Entry();
|
p.entries[0] = new Entry();
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
|
for (int x = parentIndex - 1, y = parentIndex; y <= p.nrElements; x++, y++)
|
||||||
p.entries[x] = p.entries[y];
|
p.entries[x] = p.entries[y];
|
||||||
p.entries[p.nrElements] = null;
|
p.entries[p.nrElements] = null;
|
||||||
@ -719,12 +864,14 @@ public class BTreeSet extends AbstractSet implements Set {
|
|||||||
|
|
||||||
p.nrElements--;
|
p.nrElements--;
|
||||||
|
|
||||||
if (p.isRoot() && p.nrElements == 0) { // It's the root and it's empty
|
if (p.isRoot() && p.nrElements == 0)
|
||||||
|
{ // It's the root and it's empty
|
||||||
BTreeSet.this.root = this;
|
BTreeSet.this.root = this;
|
||||||
parent = null;
|
parent = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user