use of org.neo4j.internal.kernel.api.NodeValueIndexCursor in project neo4j by neo4j.
the class NodeGetUniqueFromIndexSeekIT method shouldCompositeFindMatchingNode.
@Test
void shouldCompositeFindMatchingNode() throws Exception {
// given
IndexDescriptor index = createUniquenessConstraint(labelId, propertyId1, propertyId2);
Value value1 = Values.of("value1");
Value value2 = Values.of("value2");
long nodeId = createNodeWithValues(value1, value2);
// when looking for it
KernelTransaction transaction = newTransaction();
try (NodeValueIndexCursor cursor = transaction.cursors().allocateNodeValueIndexCursor(transaction.cursorContext(), transaction.memoryTracker())) {
long foundId = transaction.dataRead().lockingNodeUniqueIndexSeek(index, cursor, exact(propertyId1, value1), exact(propertyId2, value2));
// then
assertEquals(nodeId, foundId, "Created node was not found");
}
commit();
}
use of org.neo4j.internal.kernel.api.NodeValueIndexCursor in project neo4j by neo4j.
the class NodeGetUniqueFromIndexSeekIT method shouldBlockUniqueIndexSeekFromCompetingTransaction.
// ( timeout = 10_000 )
@Test
void shouldBlockUniqueIndexSeekFromCompetingTransaction() throws Exception {
// This is the interleaving that we are trying to verify works correctly:
// ----------------------------------------------------------------------
// Thread1 (main) : Thread2
// create unique node :
// lookup(node) :
// open start latch ----->
// | : lookup(node)
// wait for T2 to block : |
// : *block*
// commit ---------------> *unblock*
// wait for T2 end latch : |
// : finish transaction
// : open end latch
// *unblock* <-------------‘
// assert that we complete before timeout
final DoubleLatch latch = new DoubleLatch();
IndexDescriptor index = createUniquenessConstraint(labelId, propertyId1);
Value value = Values.of("value");
Write write = dataWriteInNewTransaction();
long nodeId = write.nodeCreate();
write.nodeAddLabel(nodeId, labelId);
// This adds the node to the unique index and should take an index write lock
write.nodeSetProperty(nodeId, propertyId1, value);
Runnable runnableForThread2 = () -> {
latch.waitForAllToStart();
try (KernelTransaction tx = kernel.beginTransaction(KernelTransaction.Type.IMPLICIT, LoginContext.AUTH_DISABLED)) {
try (NodeValueIndexCursor cursor = tx.cursors().allocateNodeValueIndexCursor(tx.cursorContext(), tx.memoryTracker())) {
tx.dataRead().lockingNodeUniqueIndexSeek(index, cursor, exact(propertyId1, value));
}
tx.commit();
} catch (KernelException e) {
throw new RuntimeException(e);
} finally {
latch.finish();
}
};
Thread thread2 = new Thread(runnableForThread2, "Transaction Thread 2");
thread2.start();
latch.startAndWaitForAllToStart();
while ((thread2.getState() != Thread.State.TIMED_WAITING) && (thread2.getState() != Thread.State.WAITING)) {
Thread.yield();
}
commit();
latch.waitForAllToFinish();
}
use of org.neo4j.internal.kernel.api.NodeValueIndexCursor in project neo4j by neo4j.
the class NodeGetUniqueFromIndexSeekIT method shouldFindMatchingNode.
// nodeGetUniqueWithLabelAndProperty(statement, :Person, foo=val)
//
// Given we have a unique constraint on :Person(foo)
// (If not, throw)
//
// If there is a node n with n:Person and n.foo == val, return it
// If there is no such node, return ?
//
// Ensure that if that method is called again with the same argument from some other transaction,
// that transaction blocks until this transaction has finished
//
// [X] must return node from the unique index with the given property
// [X] must return NO_SUCH_NODE if it is not in the index for the given property
//
// must block other transactions that try to call it with the same arguments
@Test
void shouldFindMatchingNode() throws Exception {
// given
IndexDescriptor index = createUniquenessConstraint(labelId, propertyId1);
Value value = Values.of("value");
long nodeId = createNodeWithValue(value);
// when looking for it
KernelTransaction transaction = newTransaction();
Read read = transaction.dataRead();
int propertyId = index.schema().getPropertyIds()[0];
try (NodeValueIndexCursor cursor = transaction.cursors().allocateNodeValueIndexCursor(transaction.cursorContext(), transaction.memoryTracker())) {
long foundId = read.lockingNodeUniqueIndexSeek(index, cursor, exact(propertyId, value));
// then
assertEquals(nodeId, foundId, "Created node was not found");
}
commit();
}
use of org.neo4j.internal.kernel.api.NodeValueIndexCursor in project neo4j by neo4j.
the class NodeGetUniqueFromIndexSeekIT method shouldNotFindNonMatchingNode.
@Test
void shouldNotFindNonMatchingNode() throws Exception {
// given
IndexDescriptor index = createUniquenessConstraint(labelId, propertyId1);
Value value = Values.of("value");
createNodeWithValue(Values.of("other_" + value));
// when looking for it
KernelTransaction transaction = newTransaction();
try (NodeValueIndexCursor cursor = transaction.cursors().allocateNodeValueIndexCursor(transaction.cursorContext(), transaction.memoryTracker())) {
long foundId = transaction.dataRead().lockingNodeUniqueIndexSeek(index, cursor, exact(propertyId1, value));
// then
assertTrue(isNoSuchNode(foundId), "Non-matching created node was found");
}
commit();
}
use of org.neo4j.internal.kernel.api.NodeValueIndexCursor in project neo4j by neo4j.
the class NodeIndexTransactionStateTest method assertEntityAndValueForScan.
@Override
void assertEntityAndValueForScan(Set<Pair<Long, Value>> expected, KernelTransaction tx, IndexDescriptor index, boolean needsValues, Object anotherValueFoundByQuery) throws Exception {
IndexReadSession indexSession = tx.dataRead().indexReadSession(index);
try (NodeValueIndexCursor nodes = tx.cursors().allocateNodeValueIndexCursor(tx.cursorContext(), tx.memoryTracker())) {
tx.dataRead().nodeIndexScan(indexSession, nodes, unordered(needsValues));
assertEntityAndValue(expected, tx, needsValues, anotherValueFoundByQuery, new NodeCursorAdapter(nodes));
}
}
Aggregations