提交 d20f5855 authored 作者: Thomas Mueller's avatar Thomas Mueller

A concurrent linked list, to replace the array list of old roots (work in progress)

上级 836d37e3
......@@ -41,24 +41,31 @@ public class ConcurrentLinkedList<K> {
public void removeFirst(K obj) {
Entry<K> x = head;
if (x == null || tail == x) {
throw DataUtils.newUnsupportedOperationException(
"Must contain at least two entries");
if (x == null) {
return;
}
if (x.obj.equals(obj)) {
if (head == tail) {
tail = x.next;
}
head = x.next;
}
}
public void removeLast(K obj) {
Entry<K> x = head;
Entry<K> prev = x;
if (x == null) {
return;
}
Entry<K> prev = null;
while (x.next != null) {
prev = x;
x = x.next;
}
if (x.obj.equals(obj)) {
prev.next = null;
if (prev != null) {
prev.next = null;
}
if (head == tail) {
head = prev;
}
......
......@@ -996,12 +996,8 @@ public class MVMap<K, V> extends AbstractMap<K, V>
return;
}
Page last = oldRootsList.peekLast();
if (oldRootsList.peekFirst() == last) {
// do nothing if there is no or only one entry
return;
}
;
// TODO why is this?
;
oldest--;
while (true) {
Page p = oldRootsList.peekFirst();
......
......@@ -13,6 +13,9 @@ import org.h2.mvstore.ConcurrentLinkedList;
import org.h2.test.TestBase;
import org.h2.util.Task;
/**
* Test the concurrent linked list.
*/
public class TestConcurrentLinkedList extends TestBase {
/**
......@@ -21,19 +24,24 @@ public class TestConcurrentLinkedList extends TestBase {
* @param a ignored
*/
public static void main(String... a) throws Exception {
TestBase.createCaller().init().test();
TestConcurrentLinkedList test = (TestConcurrentLinkedList) TestBase.createCaller().init();
test.test();
test.testPerformance();
}
@Override
public void test() throws Exception {
testConcurrent();
testRandomized();
}
private void testPerformance() {
testPerformance(true);
testPerformance(false);
testPerformance(true);
testPerformance(false);
testPerformance(true);
testPerformance(false);
testConcurrent();
testRandomized();
}
private void testPerformance(final boolean stock) {
......@@ -100,64 +108,49 @@ public class TestConcurrentLinkedList extends TestBase {
LinkedList<Integer> x = new LinkedList<Integer>();
StringBuilder buff = new StringBuilder();
for (int j = 0; j < 10000; j++) {
int opType = r.nextInt(10);
buff.append("[" + j + "] ");
int opType = r.nextInt(3);
switch (opType) {
case 0: {
int value = r.nextInt(100);
buff.append(" add " + value);
buff.append("add " + value + "\n");
test.add(value);
x.add(value);
break;
}
case 1: {
Integer value = x.peek();
buff.append(" peek");
if (value == null) {
assertNull(test.peekFirst());
if (value != null && r.nextBoolean()) {
buff.append("removeFirst\n");
x.removeFirst();
test.removeFirst(value);
} else {
assertEquals(value.intValue(), test.peekFirst().intValue());
buff.append("removeFirst -1\n");
test.removeFirst(-1);
}
break;
}
case 2: {
Integer value = x.peekLast();
buff.append(" peeLast");
if (value == null) {
assertNull(test.peekLast());
if (value != null && r.nextBoolean()) {
buff.append("removeLast\n");
x.removeLast();
test.removeLast(value);
} else {
assertEquals(value.intValue(), test.peekLast()
.intValue());
}
break;
}
case 3: {
if (x.size() >= 2) {
Integer value = x.peek();
if (value != null && r.nextBoolean()) {
buff.append(" removeFirst");
x.removeFirst();
test.removeFirst(value);
} else {
test.removeFirst(-1);
}
}
break;
}
case 4: {
if (x.size() >= 2) {
Integer value = x.peekLast();
if (value != null && r.nextBoolean()) {
buff.append(" removeLast");
x.removeLast();
test.removeLast(value);
} else {
test.removeLast(-1);
}
buff.append("removeLast -1\n");
test.removeLast(-1);
}
break;
}
}
assertEquals(toString(x.iterator()), toString(test.iterator()));
if (x.isEmpty()) {
assertNull(test.peekFirst());
assertNull(test.peekLast());
} else {
assertEquals(x.peekFirst().intValue(), test.peekFirst().intValue());
assertEquals(x.peekLast().intValue(), test.peekLast().intValue());
}
}
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论