use of org.neo4j.storageengine.api.EntityUpdates in project neo4j by neo4j.
the class OnlineIndexUpdates method gatherUpdatesFor.
private void gatherUpdatesFor(long nodeId, NodeCommand nodeCommand, EntityCommandGrouper<NodeCommand>.Cursor propertyCommands, long txId) {
EntityUpdates nodeUpdates = gatherUpdatesFromCommandsForNode(nodeId, nodeCommand, propertyCommands);
eagerlyGatherValueIndexUpdates(nodeUpdates, EntityType.NODE);
eagerlyGatherTokenIndexUpdates(nodeUpdates, EntityType.NODE, txId);
}
use of org.neo4j.storageengine.api.EntityUpdates in project neo4j by neo4j.
the class OnlineIndexUpdates method gatherUpdatesFromCommandsForNode.
private EntityUpdates gatherUpdatesFromCommandsForNode(long nodeId, NodeCommand nodeChanges, EntityCommandGrouper<NodeCommand>.Cursor propertyCommandsForNode) {
long[] nodeLabelsBefore;
long[] nodeLabelsAfter;
if (nodeChanges != null) {
// Special case since the node may not be heavy, i.e. further loading may be required
nodeLabelsBefore = parseLabelsField(nodeChanges.getBefore()).get(nodeStore, cursorContext);
nodeLabelsAfter = parseLabelsField(nodeChanges.getAfter()).get(nodeStore, cursorContext);
} else {
/* If the node doesn't exist here then we've most likely encountered this scenario:
* - TX1: Node N exists and has property record P
* - rotate log
* - TX2: P gets changed
* - TX3: N gets deleted (also P, but that's irrelevant for this scenario)
* - N is persisted to disk for some reason
* - crash
* - recover
* - TX2: P has changed and updates to indexes are gathered. As part of that it tries to read
* the labels of N (which does not exist a.t.m.).
*
* We can actually (if we disregard any potential inconsistencies) just assume that
* if this happens and we're in recovery mode that the node in question will be deleted
* in an upcoming transaction, so just skip this update.
*/
StorageNodeCursor nodeCursor = loadNode(nodeId);
nodeLabelsBefore = nodeLabelsAfter = nodeCursor.labels();
}
// First get possible Label changes
boolean complete = providesCompleteListOfProperties(nodeChanges);
EntityUpdates.Builder nodePropertyUpdates = EntityUpdates.forEntity(nodeId, complete).withTokens(nodeLabelsBefore).withTokensAfter(nodeLabelsAfter);
// Then look for property changes
converter.convertPropertyRecord(propertyCommandsForNode, nodePropertyUpdates);
return nodePropertyUpdates.build();
}
use of org.neo4j.storageengine.api.EntityUpdates in project neo4j by neo4j.
the class OnlineIndexUpdates method gatherUpdatesFor.
private void gatherUpdatesFor(long relationshipId, RelationshipCommand relationshipCommand, EntityCommandGrouper<RelationshipCommand>.Cursor propertyCommands, long txId) {
EntityUpdates relationshipUpdates = gatherUpdatesFromCommandsForRelationship(relationshipId, relationshipCommand, propertyCommands);
eagerlyGatherValueIndexUpdates(relationshipUpdates, EntityType.RELATIONSHIP);
eagerlyGatherTokenIndexUpdates(relationshipUpdates, EntityType.RELATIONSHIP, txId);
}
use of org.neo4j.storageengine.api.EntityUpdates in project neo4j by neo4j.
the class MultiIndexPopulationConcurrentUpdatesIT method applyConcurrentDeletesToPopulatedIndex.
@ParameterizedTest
@MethodSource("parameters")
void applyConcurrentDeletesToPopulatedIndex(GraphDatabaseSettings.SchemaIndex schemaIndex) throws Throwable {
List<EntityUpdates> updates = new ArrayList<>(2);
updates.add(EntityUpdates.forEntity(country1.getId(), false).withTokens(id(COUNTRY_LABEL)).removed(propertyId, Values.of("Sweden")).build());
updates.add(EntityUpdates.forEntity(color2.getId(), false).withTokens(id(COLOR_LABEL)).removed(propertyId, Values.of("green")).build());
launchCustomIndexPopulation(schemaIndex, labelsNameIdMap, propertyId, new UpdateGenerator(updates));
waitAndActivateIndexes(labelsNameIdMap, propertyId);
try (Transaction tx = db.beginTx()) {
Integer countryLabelId = labelsNameIdMap.get(COUNTRY_LABEL);
Integer colorLabelId = labelsNameIdMap.get(COLOR_LABEL);
try (var indexReader = getIndexReader(propertyId, countryLabelId)) {
assertThat(indexReader.countIndexedEntities(0, NULL, new int[] { propertyId }, Values.of("Sweden"))).as("Should be removed by concurrent remove.").isEqualTo(0);
}
try (var indexReader = getIndexReader(propertyId, colorLabelId)) {
assertThat(indexReader.countIndexedEntities(3, NULL, new int[] { propertyId }, Values.of("green"))).as("Should be removed by concurrent remove.").isEqualTo(0);
}
}
}
use of org.neo4j.storageengine.api.EntityUpdates in project neo4j by neo4j.
the class GraphStoreFixture method nodeAsUpdates.
public EntityUpdates nodeAsUpdates(long nodeId) {
try (StorageReader storeReader = storageEngine.newReader();
StorageNodeCursor nodeCursor = storeReader.allocateNodeCursor(NULL);
StoragePropertyCursor propertyCursor = storeReader.allocatePropertyCursor(NULL, INSTANCE)) {
nodeCursor.single(nodeId);
long[] labels;
if (!nodeCursor.next() || !nodeCursor.hasProperties() || (labels = nodeCursor.labels()).length == 0) {
return null;
}
nodeCursor.properties(propertyCursor);
EntityUpdates.Builder update = EntityUpdates.forEntity(nodeId, true).withTokens(labels);
while (propertyCursor.next()) {
update.added(propertyCursor.propertyKey(), propertyCursor.propertyValue());
}
return update.build();
}
}
Aggregations