use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.
the class GenericAccessorPointsTest method shouldNotGetFalsePositivesForRangesSpanningMultipleTiles.
/**
* Given how the spatial index works, if a point is on a tile that intersect with the search area,
* but the point itself is outside the search area, it is a candidate for a false positive.
* The reason is that such a point is returned from the index itself,
* because a space index compares (and generally works with) only values of a space-filling curve
* and not the points themselves.
* Therefore {@link IndexReader} implementation must post-process raw index results and filter out such false positives.
*/
@Test
void shouldNotGetFalsePositivesForRangesSpanningMultipleTiles() throws IndexNotApplicableKernelException, IndexEntryConflictException {
PointValue origin = Values.pointValue(WGS84, 0.0, 0.0);
long derivedValueForCenterPoint = curve.derivedValueFor(origin.coordinate());
double[] searchStart = curve.centerPointFor(derivedValueForCenterPoint);
double xTileWidth = curve.getTileWidth(0, curve.getMaxLevel());
// to make it easier to imagine this, the search start is a center point of one tile and the limit is a center point of the next tile on the x-axis
PointValue limitPoint = Values.pointValue(WGS84, searchStart[0] + xTileWidth, searchStart[1]);
int nbrOfValues = 10_000;
List<PointValue> pointsInside = new ArrayList<>();
List<IndexEntryUpdate<?>> updates = new ArrayList<>();
for (int i = 0; i < nbrOfValues; i++) {
double distanceMultiplier = random.nextDouble() * 2;
PointValue point = Values.pointValue(WGS84, searchStart[0] + distanceMultiplier * xTileWidth, searchStart[1]);
updates.add(IndexEntryUpdate.add(0, descriptor, point));
if (distanceMultiplier <= 1) {
pointsInside.add(point);
}
}
processAll(updates);
try (var indexReader = accessor.newValueReader()) {
SimpleEntityValueClient client = new SimpleEntityValueClient();
var range = PropertyIndexQuery.range(descriptor.schema().getPropertyId(), Values.pointValue(WGS84, searchStart), true, limitPoint, true);
indexReader.query(QueryContext.NULL_CONTEXT, client, unorderedValues(), range);
List<Value> queryResult = new ArrayList<>();
while (client.next()) {
queryResult.add(client.values[0]);
}
assertThat(queryResult).containsExactlyInAnyOrderElementsOf(pointsInside);
}
}
use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.
the class NativeUniqueIndexPopulatorTest method updaterShouldThrowOnDuplicateValues.
@Test
void updaterShouldThrowOnDuplicateValues() throws Exception {
// given
populator.create();
IndexEntryUpdate<IndexDescriptor>[] updates = valueCreatorUtil.someUpdatesWithDuplicateValues(random);
IndexUpdater updater = populator.newPopulatingUpdater(null_property_accessor, NULL);
// when
for (IndexEntryUpdate<IndexDescriptor> update : updates) {
updater.process(update);
}
var e = assertThrows(Exception.class, () -> {
updater.close();
populator.scanCompleted(nullInstance, populationWorkScheduler, NULL);
});
assertTrue(hasCause(e, IndexEntryConflictException.class), e.getMessage());
populator.close(true, NULL);
}
use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.
the class NativeUniqueIndexPopulatorTest method shouldSampleUpdates.
@Test
void shouldSampleUpdates() throws Exception {
// GIVEN
populator.create();
IndexEntryUpdate<IndexDescriptor>[] updates = valueCreatorUtil.someUpdates(random);
// WHEN
populator.add(asList(updates), NULL);
for (IndexEntryUpdate<IndexDescriptor> update : updates) {
populator.includeSample(update);
}
populator.scanCompleted(nullInstance, populationWorkScheduler, NULL);
IndexSample sample = populator.sample(NULL);
// THEN
assertEquals(updates.length, sample.sampleSize());
assertEquals(updates.length, sample.uniqueValues());
assertEquals(updates.length, sample.indexSize());
populator.close(true, NULL);
}
use of org.neo4j.storageengine.api.IndexEntryUpdate in project neo4j by neo4j.
the class OnlineIndexUpdatesTest method shouldContainFedNodeUpdate.
@Test
void shouldContainFedNodeUpdate() {
OnlineIndexUpdates onlineIndexUpdates = new OnlineIndexUpdates(nodeStore, schemaCache, propertyPhysicalToLogicalConverter, new RecordStorageReader(neoStores), CursorContext.NULL, INSTANCE);
int nodeId = 0;
NodeRecord inUse = getNode(nodeId, true);
Value propertyValue = Values.of("hej");
long propertyId = createNodeProperty(inUse, propertyValue, 1);
NodeRecord notInUse = getNode(nodeId, false);
nodeStore.updateRecord(inUse, CursorContext.NULL);
NodeCommand nodeCommand = new NodeCommand(inUse, notInUse);
PropertyRecord propertyBlocks = new PropertyRecord(propertyId);
propertyBlocks.setNodeId(nodeId);
PropertyCommand propertyCommand = new PropertyCommand(recordAccess.getIfLoaded(propertyId).forReadingData(), propertyBlocks);
IndexDescriptor indexDescriptor = IndexPrototype.forSchema(fulltext(NODE, ENTITY_TOKENS, new int[] { 1, 4, 6 })).withName("index").materialise(0);
createIndexes(indexDescriptor);
onlineIndexUpdates.feed(nodeGroup(nodeCommand, propertyCommand), relationshipGroup(null), -1);
assertTrue(onlineIndexUpdates.hasUpdates());
Iterator<IndexEntryUpdate<IndexDescriptor>> iterator = onlineIndexUpdates.iterator();
assertEquals(iterator.next(), IndexEntryUpdate.remove(nodeId, indexDescriptor, propertyValue, null, null));
assertFalse(iterator.hasNext());
}
Aggregations