package org.ObjectLayout.examples;/*
* Written by Gil Tene, Martin Thompson and Michael Barker, and released
* to the public domain, as explained at:
* http://creativecommons.org/publicdomain/zero/1.0/
*/
import static java.util.Arrays.sort;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Random;
import java.util.TreeMap;
import org.ObjectLayout.examples.BPlusTree;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;
public class BPlusTreeTest {
private final BPlusTree<Integer, Integer> tree = new BPlusTree<Integer, Integer>(
8);
@Test
public void test() {
int[] values = new int[] { 10, 20, 30, 40, 50, 60, 70, 80 };
for (int value : values) {
tree.put(value, value);
}
tree.put(21, 21);
Assert.assertThat(tree.get(49), CoreMatchers.is(CoreMatchers.nullValue()));
Assert.assertThat(tree.get(50), CoreMatchers.is((Object) 50));
Assert.assertThat(tree.get(51), CoreMatchers.is(CoreMatchers.nullValue()));
Assert.assertThat(tree.get(21), CoreMatchers.is((Object) 21));
}
@Test
public void insertsAndGetsAndRemovesRandomValues() throws Exception {
int[] values = nextInts(new Random(5), Integer.MAX_VALUE,
new int[10000]);
putAll(tree, values);
assertGet(tree, values);
TreeMap<Integer, Integer> treeMap = new TreeMap<Integer, Integer>();
putAll(treeMap, values);
Assert.assertThat(tree.size(), CoreMatchers.is(treeMap.size()));
Assert.assertThat(count(tree), CoreMatchers.is(treeMap.size()));
int count = 0;
for (int value : values) {
Assert.assertThat("{" + count + "}", tree.get(value),
CoreMatchers.is(treeMap.get(value)));
Integer removed = tree.remove(value);
Integer mapRemoved = treeMap.remove(value);
Assert.assertThat("{" + count + "}", removed, CoreMatchers.is(mapRemoved));
Assert.assertThat("{" + count + "}", tree.size(), CoreMatchers.is(treeMap.size()));
Assert.assertThat("{" + count + "}", count(tree), CoreMatchers.is(treeMap.size()));
Assert.assertThat("{" + count + "}", tree.get(value), CoreMatchers.is(CoreMatchers.nullValue()));
count++;
}
}
private int count(BPlusTree<Integer, Integer> tree) {
Iterator<Entry<Integer, Integer>> iterator = tree.iterator();
int i = 0;
while (iterator.hasNext()) {
iterator.next();
i++;
}
return i;
}
@Test
public void putsAndDeletesWithoutBranching() {
int[] values = new int[] { 10, 20, 30, 40, 50, 60, 70, 80 };
putAll(tree, values);
int size = tree.size();
for (int value : values) {
int removed = tree.remove(value);
Assert.assertThat(removed, CoreMatchers.is(value));
Assert.assertThat(tree.size(), CoreMatchers.is(--size));
}
}
@Test
public void putsAndDeletesFromLeftWithBranching() {
int[] values = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 90 };
putAll(tree, values);
int size = tree.size();
for (int value : values) {
int removed = tree.remove(value);
Assert.assertThat(removed, CoreMatchers.is(value));
Assert.assertThat(tree.size(), CoreMatchers.is(--size));
}
}
@Test
public void putsAndDeletesFromRightWithBranching() {
int[] values = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 45 };
putAll(tree, values);
int size = tree.size();
sort(values);
for (int value : reverse(values)) {
int removed = tree.remove(value);
Assert.assertThat(removed, CoreMatchers.is(value));
Assert.assertThat(tree.size(), CoreMatchers.is(--size));
}
}
private int[] reverse(int[] values) {
int[] reversed = new int[values.length];
int index = reversed.length;
for (int value : values) {
reversed[--index] = value;
}
return reversed;
}
@Test
public void splitsLeavesTwiceToRight() throws Exception {
int[] values = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 51, 52, 53,
54, 55 };
assertPutAndGet(values);
}
@Test
public void splitsLeavesTwiceToLeft() throws Exception {
int[] values = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 1, 2, 3, 4,
5 };
assertPutAndGet(values);
}
@Test
public void splitsLeavesTwiceBothWays() throws Exception {
int[] values = new int[] { 10, 20, 30, 40, 50, 60, 70, 80, 41, 42, 43,
44, 45 };
assertPutAndGet(values);
}
private void assertPutAndGet(int[] values) {
for (int value : values) {
tree.put(value, value);
}
for (int value : values) {
Assert.assertThat(tree.get(value), CoreMatchers.is((Object) value));
}
}
private static void putAll(BPlusTree<Integer, Integer> node, int... values) {
int counter = 0;
for (int value : values) {
try {
node.put(value, value);
counter++;
} catch (Exception e) {
throw new RuntimeException("" + counter, e);
}
}
}
private static void assertGet(BPlusTree<Integer, Integer> tree, int[] values) {
for (int value : values) {
Assert.assertThat(tree.get(value), CoreMatchers.is((Object) value));
}
}
private static void putAll(TreeMap<Integer, Integer> treeMap, int[] values) {
for (int value : values) {
treeMap.put(value, value);
}
}
private int[] nextInts(Random r, int maxValue, int[] values) {
for (int i = 0; i < values.length; i++) {
values[i] = r.nextInt(maxValue);
}
return values;
}
}