use of org.apache.ignite.internal.pagememory.tree.IgniteTree.OperationType in project ignite-3 by apache.
the class ItBplusTreeSelfTest method doTestRandomPutRemoveMultithreaded.
private void doTestRandomPutRemoveMultithreaded(boolean canGetRow) throws Exception {
final TestTree tree = createTestTree(canGetRow);
final Map<Long, Long> map = new ConcurrentHashMap<>();
final int loops = reuseList == null ? 10_000 : 30_000;
final IgniteStripedLock lock = new IgniteStripedLock(256);
final String[] ops = { "put", "rmv", "inv_put", "inv_rmv" };
CompletableFuture<?> fut = runMultiThreadedAsync(() -> {
for (int i = 0; i < loops && !stop.get(); i++) {
final Long x = (long) DataStructure.randomInt(CNT);
final int op = DataStructure.randomInt(4);
if (i % 5_000 == 0) {
println(" --> " + ops[op] + "_" + i + " " + x);
}
Lock l = lock.getLock(x.longValue());
l.lock();
try {
if (op == 0) {
// Put.
assertEquals(map.put(x, x), tree.put(x));
assertNoLocks();
} else if (op == 1) {
// Remove.
if (map.remove(x) != null) {
assertEquals(x, tree.remove(x));
assertNoLocks();
}
assertNull(tree.remove(x));
assertNoLocks();
} else if (op == 2) {
tree.invoke(x, null, new InvokeClosure<>() {
OperationType opType;
@Override
public void call(@Nullable Long row) {
opType = PUT;
if (row != null) {
assertEquals(x, row);
}
}
@Override
public Long newRow() {
return x;
}
@Override
public OperationType operationType() {
return opType;
}
});
map.put(x, x);
} else if (op == 3) {
tree.invoke(x, null, new InvokeClosure<Long>() {
OperationType opType;
@Override
public void call(@Nullable Long row) {
if (row != null) {
assertEquals(x, row);
opType = REMOVE;
} else {
opType = NOOP;
}
}
@Override
public Long newRow() {
return null;
}
@Override
public OperationType operationType() {
return opType;
}
});
map.remove(x);
} else {
fail();
}
} finally {
l.unlock();
}
}
return null;
}, CPUS, "put-remove");
CompletableFuture<?> fut2 = runMultiThreadedAsync(() -> {
while (!stop.get()) {
Thread.sleep(1_000);
println(TestTree.printLocks());
}
return null;
}, 1, "printLocks");
CompletableFuture<?> fut3 = runMultiThreadedAsync(() -> {
while (!stop.get()) {
int low = DataStructure.randomInt(CNT);
int high = low + DataStructure.randomInt(CNT - low);
IgniteCursor<Long> c = tree.find((long) low, (long) high);
Long last = null;
while (c.next()) {
// Correct bounds.
assertTrue(c.get() >= low, low + " <= " + c.get() + " <= " + high);
assertTrue(c.get() <= high, low + " <= " + c.get() + " <= " + high);
if (last != null) {
// No duplicates.
assertTrue(c.get() > last, low + " <= " + last + " < " + c.get() + " <= " + high);
}
last = c.get();
}
TestTreeFindFirstClosure cl = new TestTreeFindFirstClosure();
tree.iterate((long) low, (long) high, cl);
last = cl.val;
if (last != null) {
assertTrue(last >= low, low + " <= " + last + " <= " + high);
assertTrue(last <= high, low + " <= " + last + " <= " + high);
}
}
return null;
}, 4, "find");
asyncRunFut = CompletableFuture.allOf(fut, fut2, fut3);
try {
fut.get(getTestTimeout(), MILLISECONDS);
} finally {
stop.set(true);
asyncRunFut.get(getTestTimeout(), MILLISECONDS);
}
IgniteCursor<Long> cursor = tree.find(null, null);
while (cursor.next()) {
Long x = cursor.get();
assert x != null;
assertEquals(map.get(x), x);
}
info("size: " + map.size());
assertEquals(map.size(), tree.size());
tree.validateTree();
assertNoLocks();
}
use of org.apache.ignite.internal.pagememory.tree.IgniteTree.OperationType in project ignite-3 by apache.
the class ItBplusTreeSelfTest method doTestRandomInvoke.
private void doTestRandomInvoke(boolean canGetRow) throws Exception {
TestTree tree = createTestTree(canGetRow);
Map<Long, Long> map = new HashMap<>();
int loops = reuseList == null ? 20_000 : 60_000;
for (int i = 0; i < loops; i++) {
final Long x = (long) BplusTree.randomInt(CNT);
final int rnd = BplusTree.randomInt(11);
if (i % 10_000 == 0) {
// println(tree.printTree());
println(" --> " + i + " ++> " + x);
}
// Update map.
if (!map.containsKey(x)) {
if (rnd % 2 == 0) {
map.put(x, x);
// println("put0: " + x);
} else {
// println("noop0: " + x);
}
} else {
if (rnd % 2 == 0) {
// println("put1: " + x);
} else if (rnd % 3 == 0) {
map.remove(x);
// println("rmv1: " + x);
} else {
// println("noop1: " + x);
}
}
// Consistently update tree.
tree.invoke(x, null, new IgniteTree.InvokeClosure<>() {
OperationType op;
Long newRow;
@Override
public void call(@Nullable Long row) {
if (row == null) {
if (rnd % 2 == 0) {
op = PUT;
newRow = x;
} else {
op = NOOP;
newRow = null;
}
} else {
assertEquals(x, row);
if (rnd % 2 == 0) {
op = PUT;
// We can not replace x with y here, because keys must be equal.
newRow = x;
} else if (rnd % 3 == 0) {
op = REMOVE;
newRow = null;
} else {
op = NOOP;
newRow = null;
}
}
}
@Override
public Long newRow() {
return newRow;
}
@Override
public OperationType operationType() {
return op;
}
});
assertNoLocks();
// println(tree.printTree());
tree.validateTree();
if (i % 100 == 0) {
assertEqualContents(tree, map);
}
}
}
Aggregations