Search in sources :

Example 1 with PrimitiveRecord

use of org.neo4j.kernel.impl.store.record.PrimitiveRecord in project neo4j by neo4j.

the class TransactionRecordState method extractCommands.

@Override
public void extractCommands(Collection<StorageCommand> commands) throws TransactionFailureException {
    assert !prepared : "Transaction has already been prepared";
    integrityValidator.validateTransactionStartKnowledge(lastCommittedTxWhenTransactionStarted);
    int noOfCommands = recordChangeSet.changeSize() + (neoStoreRecord != null ? neoStoreRecord.changeSize() : 0);
    for (RecordProxy<Integer, LabelTokenRecord, Void> record : recordChangeSet.getLabelTokenChanges().changes()) {
        commands.add(new Command.LabelTokenCommand(record.getBefore(), record.forReadingLinkage()));
    }
    for (RecordProxy<Integer, RelationshipTypeTokenRecord, Void> record : recordChangeSet.getRelationshipTypeTokenChanges().changes()) {
        commands.add(new Command.RelationshipTypeTokenCommand(record.getBefore(), record.forReadingLinkage()));
    }
    for (RecordProxy<Integer, PropertyKeyTokenRecord, Void> record : recordChangeSet.getPropertyKeyTokenChanges().changes()) {
        commands.add(new Command.PropertyKeyTokenCommand(record.getBefore(), record.forReadingLinkage()));
    }
    // Collect nodes, relationships, properties
    Command[] nodeCommands = EMPTY_COMMANDS;
    int skippedCommands = 0;
    if (recordChangeSet.getNodeRecords().changeSize() > 0) {
        nodeCommands = new Command[recordChangeSet.getNodeRecords().changeSize()];
        int i = 0;
        for (RecordProxy<Long, NodeRecord, Void> change : recordChangeSet.getNodeRecords().changes()) {
            NodeRecord record = prepared(change, nodeStore);
            integrityValidator.validateNodeRecord(record);
            nodeCommands[i++] = new Command.NodeCommand(change.getBefore(), record);
        }
        Arrays.sort(nodeCommands, COMMAND_SORTER);
    }
    Command[] relCommands = EMPTY_COMMANDS;
    if (recordChangeSet.getRelRecords().changeSize() > 0) {
        relCommands = new Command[recordChangeSet.getRelRecords().changeSize()];
        int i = 0;
        for (RecordProxy<Long, RelationshipRecord, Void> change : recordChangeSet.getRelRecords().changes()) {
            relCommands[i++] = new Command.RelationshipCommand(change.getBefore(), prepared(change, relationshipStore));
        }
        Arrays.sort(relCommands, COMMAND_SORTER);
    }
    Command[] propCommands = EMPTY_COMMANDS;
    if (recordChangeSet.getPropertyRecords().changeSize() > 0) {
        propCommands = new Command[recordChangeSet.getPropertyRecords().changeSize()];
        int i = 0;
        for (RecordProxy<Long, PropertyRecord, PrimitiveRecord> change : recordChangeSet.getPropertyRecords().changes()) {
            propCommands[i++] = new Command.PropertyCommand(change.getBefore(), prepared(change, propertyStore));
        }
        Arrays.sort(propCommands, COMMAND_SORTER);
    }
    Command[] relGroupCommands = EMPTY_COMMANDS;
    if (recordChangeSet.getRelGroupRecords().changeSize() > 0) {
        relGroupCommands = new Command[recordChangeSet.getRelGroupRecords().changeSize()];
        int i = 0;
        for (RecordProxy<Long, RelationshipGroupRecord, Integer> change : recordChangeSet.getRelGroupRecords().changes()) {
            if (change.isCreated() && !change.forReadingLinkage().inUse()) {
                /*
                     * This is an edge case that may come up and which we must handle properly. Relationship groups are
                     * not managed by the tx state, since they are created as side effects rather than through
                     * direct calls. However, they differ from say, dynamic records, in that their management can happen
                     * through separate code paths. What we are interested in here is the following scenario.
                     * 0. A node has one less relationship that is required to transition to dense node. The relationships
                     *    it has belong to at least two different types
                     * 1. In the same tx, a relationship is added making the node dense and all the relationships of a type
                     *    are removed from that node. Regardless of the order these operations happen, the creation of the
                     *    relationship (and the transition of the node to dense) will happen first.
                     * 2. A relationship group will be created because of the transition to dense and then deleted because
                     *    all the relationships it would hold are no longer there. This results in a relationship group
                     *    command that appears in the tx as not in use. Depending on the final order of operations, this
                     *    can end up using an id that is higher than the highest id seen so far. This may not be a problem
                     *    for a single instance, but it can result in errors in cases where transactions are applied
                     *    externally, such as backup or HA.
                     *
                     * The way we deal with this issue here is by not issuing a command for that offending record. This is
                     * safe, since the record is not in use and never was, so the high id is not necessary to change and
                     * the store remains consistent.
                     */
                skippedCommands++;
                continue;
            }
            relGroupCommands[i++] = new Command.RelationshipGroupCommand(change.getBefore(), prepared(change, relationshipGroupStore));
        }
        relGroupCommands = i < relGroupCommands.length ? Arrays.copyOf(relGroupCommands, i) : relGroupCommands;
        Arrays.sort(relGroupCommands, COMMAND_SORTER);
    }
    addFiltered(commands, Mode.CREATE, propCommands, relCommands, relGroupCommands, nodeCommands);
    addFiltered(commands, Mode.UPDATE, propCommands, relCommands, relGroupCommands, nodeCommands);
    addFiltered(commands, Mode.DELETE, propCommands, relCommands, relGroupCommands, nodeCommands);
    if (neoStoreRecord != null) {
        for (RecordProxy<Long, NeoStoreRecord, Void> change : neoStoreRecord.changes()) {
            commands.add(new Command.NeoStoreCommand(change.getBefore(), change.forReadingData()));
        }
    }
    for (RecordProxy<Long, SchemaRecord, SchemaRule> change : recordChangeSet.getSchemaRuleChanges().changes()) {
        integrityValidator.validateSchemaRule(change.getAdditionalData());
        commands.add(new Command.SchemaRuleCommand(change.getBefore(), change.forChangingData(), change.getAdditionalData()));
    }
    assert commands.size() == noOfCommands - skippedCommands : format("Expected %d final commands, got %d " + "instead, with %d skipped", noOfCommands, commands.size(), skippedCommands);
    prepared = true;
}
Also used : RelationshipTypeTokenRecord(org.neo4j.kernel.impl.store.record.RelationshipTypeTokenRecord) RelationshipRecord(org.neo4j.kernel.impl.store.record.RelationshipRecord) SchemaRule(org.neo4j.storageengine.api.schema.SchemaRule) PropertyKeyTokenRecord(org.neo4j.kernel.impl.store.record.PropertyKeyTokenRecord) NodeRecord(org.neo4j.kernel.impl.store.record.NodeRecord) NeoStoreRecord(org.neo4j.kernel.impl.store.record.NeoStoreRecord) PropertyRecord(org.neo4j.kernel.impl.store.record.PropertyRecord) SchemaRecord(org.neo4j.kernel.impl.store.record.SchemaRecord) LabelTokenRecord(org.neo4j.kernel.impl.store.record.LabelTokenRecord) PrimitiveRecord(org.neo4j.kernel.impl.store.record.PrimitiveRecord) RelationshipGroupRecord(org.neo4j.kernel.impl.store.record.RelationshipGroupRecord) StorageCommand(org.neo4j.storageengine.api.StorageCommand) Command(org.neo4j.kernel.impl.transaction.command.Command)

Example 2 with PrimitiveRecord

use of org.neo4j.kernel.impl.store.record.PrimitiveRecord in project neo4j by neo4j.

the class PropertyDeleter method removeProperty.

public <P extends PrimitiveRecord> void removeProperty(RecordProxy<Long, P, Void> primitiveProxy, int propertyKey, RecordAccess<Long, PropertyRecord, PrimitiveRecord> propertyRecords) {
    PrimitiveRecord primitive = primitiveProxy.forReadingData();
    // propertyData.getId();
    long propertyId = traverser.findPropertyRecordContaining(primitive, propertyKey, propertyRecords, true);
    RecordProxy<Long, PropertyRecord, PrimitiveRecord> recordChange = propertyRecords.getOrLoad(propertyId, primitive);
    PropertyRecord propRecord = recordChange.forChangingData();
    if (!propRecord.inUse()) {
        throw new IllegalStateException("Unable to delete property[" + propertyId + "] since it is already deleted.");
    }
    PropertyBlock block = propRecord.removePropertyBlock(propertyKey);
    if (block == null) {
        throw new IllegalStateException("Property with index[" + propertyKey + "] is not present in property[" + propertyId + "]");
    }
    for (DynamicRecord valueRecord : block.getValueRecords()) {
        assert valueRecord.inUse();
        valueRecord.setInUse(false, block.getType().intValue());
        propRecord.addDeletedRecord(valueRecord);
    }
    if (propRecord.size() > 0) {
        /*
             * There are remaining blocks in the record. We do not unlink yet.
             */
        propRecord.setChanged(primitive);
        assert traverser.assertPropertyChain(primitive, propertyRecords);
    } else {
        unlinkPropertyRecord(propRecord, propertyRecords, primitiveProxy);
    }
}
Also used : DynamicRecord(org.neo4j.kernel.impl.store.record.DynamicRecord) PropertyRecord(org.neo4j.kernel.impl.store.record.PropertyRecord) PropertyBlock(org.neo4j.kernel.impl.store.record.PropertyBlock) PrimitiveRecord(org.neo4j.kernel.impl.store.record.PrimitiveRecord)

Example 3 with PrimitiveRecord

use of org.neo4j.kernel.impl.store.record.PrimitiveRecord in project neo4j by neo4j.

the class PropertyDeleter method deletePropertyChain.

public void deletePropertyChain(PrimitiveRecord primitive, RecordAccess<Long, PropertyRecord, PrimitiveRecord> propertyRecords) {
    long nextProp = primitive.getNextProp();
    while (nextProp != Record.NO_NEXT_PROPERTY.intValue()) {
        RecordProxy<Long, PropertyRecord, PrimitiveRecord> propertyChange = propertyRecords.getOrLoad(nextProp, primitive);
        // TODO forChanging/forReading piggy-backing
        PropertyRecord propRecord = propertyChange.forChangingData();
        for (PropertyBlock block : propRecord) {
            for (DynamicRecord valueRecord : block.getValueRecords()) {
                assert valueRecord.inUse();
                valueRecord.setInUse(false);
                propRecord.addDeletedRecord(valueRecord);
            }
        }
        nextProp = propRecord.getNextProp();
        propRecord.setInUse(false);
        propRecord.setChanged(primitive);
        // We do not remove them individually, but all together here
        propRecord.clearPropertyBlocks();
    }
    primitive.setNextProp(Record.NO_NEXT_PROPERTY.intValue());
}
Also used : DynamicRecord(org.neo4j.kernel.impl.store.record.DynamicRecord) PropertyRecord(org.neo4j.kernel.impl.store.record.PropertyRecord) PropertyBlock(org.neo4j.kernel.impl.store.record.PropertyBlock) PrimitiveRecord(org.neo4j.kernel.impl.store.record.PrimitiveRecord)

Example 4 with PrimitiveRecord

use of org.neo4j.kernel.impl.store.record.PrimitiveRecord in project neo4j by neo4j.

the class StoreMigrator method propertyDecorator.

private <ENTITY extends InputEntity, RECORD extends PrimitiveRecord> BiConsumer<ENTITY, RECORD> propertyDecorator(boolean requiresPropertyMigration, RecordCursors cursors) {
    if (!requiresPropertyMigration) {
        return (a, b) -> {
        };
    }
    final StorePropertyCursor cursor = new StorePropertyCursor(cursors, ignored -> {
    });
    final List<Object> scratch = new ArrayList<>();
    return (ENTITY entity, RECORD record) -> {
        cursor.init(record.getNextProp(), LockService.NO_LOCK);
        scratch.clear();
        while (cursor.next()) {
            // add key as int here as to have the importer use the token id
            scratch.add(cursor.propertyKeyId());
            scratch.add(cursor.value());
        }
        entity.setProperties(scratch.isEmpty() ? InputEntity.NO_PROPERTIES : scratch.toArray());
        cursor.close();
    };
}
Also used : PropertyDeduplicator(org.neo4j.kernel.impl.storemigration.legacystore.v21.propertydeduplication.PropertyDeduplicator) Arrays(java.util.Arrays) PageCursor(org.neo4j.io.pagecache.PageCursor) NullLogProvider(org.neo4j.logging.NullLogProvider) StringUtils(org.apache.commons.lang3.StringUtils) UNKNOWN_TX_COMMIT_TIMESTAMP(org.neo4j.kernel.impl.transaction.log.TransactionIdStore.UNKNOWN_TX_COMMIT_TIMESTAMP) COPY(org.neo4j.kernel.impl.storemigration.FileOperation.COPY) SchemaIndexProvider(org.neo4j.kernel.api.index.SchemaIndexProvider) CountsComputer(org.neo4j.kernel.impl.store.CountsComputer) Arrays.asList(java.util.Arrays.asList) BASE_TX_COMMIT_TIMESTAMP(org.neo4j.kernel.impl.transaction.log.TransactionIdStore.BASE_TX_COMMIT_TIMESTAMP) Position(org.neo4j.kernel.impl.store.MetaDataStore.Position) Lifespan(org.neo4j.kernel.lifecycle.Lifespan) RecordCursors(org.neo4j.kernel.impl.store.RecordCursors) SilentMigrationProgressMonitor(org.neo4j.kernel.impl.storemigration.monitoring.SilentMigrationProgressMonitor) StandardCharsets(java.nio.charset.StandardCharsets) MetaDataRecordFormat(org.neo4j.kernel.impl.store.format.standard.MetaDataRecordFormat) DELETE(org.neo4j.kernel.impl.storemigration.FileOperation.DELETE) Stream(java.util.stream.Stream) ExecutionSupervisors.withDynamicProcessorAssignment(org.neo4j.unsafe.impl.batchimport.staging.ExecutionSupervisors.withDynamicProcessorAssignment) StoreType(org.neo4j.kernel.impl.store.StoreType) BatchImporter(org.neo4j.unsafe.impl.batchimport.BatchImporter) NodeStore(org.neo4j.kernel.impl.store.NodeStore) StoreFactory(org.neo4j.kernel.impl.store.StoreFactory) Collectors(org.neo4j.unsafe.impl.batchimport.input.Collectors) PagedFile(org.neo4j.io.pagecache.PagedFile) VERSION_TRAILERS(org.neo4j.kernel.impl.store.format.Capability.VERSION_TRAILERS) FormatFamily(org.neo4j.kernel.impl.store.format.FormatFamily) Supplier(java.util.function.Supplier) UNKNOWN_TX_CHECKSUM(org.neo4j.kernel.impl.transaction.log.TransactionIdStore.UNKNOWN_TX_CHECKSUM) BufferedOutputStream(java.io.BufferedOutputStream) StandardCopyOption(java.nio.file.StandardCopyOption) ArrayList(java.util.ArrayList) TransactionId(org.neo4j.kernel.impl.store.TransactionId) StandardV2_2(org.neo4j.kernel.impl.store.format.standard.StandardV2_2) LogPosition(org.neo4j.kernel.impl.transaction.log.LogPosition) StandardV2_1(org.neo4j.kernel.impl.store.format.standard.StandardV2_1) RelationshipStore(org.neo4j.kernel.impl.store.RelationshipStore) StandardV2_0(org.neo4j.kernel.impl.store.format.standard.StandardV2_0) IdMappers(org.neo4j.unsafe.impl.batchimport.cache.idmapping.IdMappers) BiConsumer(java.util.function.BiConsumer) IdGenerators(org.neo4j.unsafe.impl.batchimport.cache.idmapping.IdGenerators) StreamSupport(java.util.stream.StreamSupport) DirectRecordStoreMigrator(org.neo4j.kernel.impl.storemigration.DirectRecordStoreMigrator) CoarseBoundedProgressExecutionMonitor(org.neo4j.unsafe.impl.batchimport.staging.CoarseBoundedProgressExecutionMonitor) StoreFile(org.neo4j.kernel.impl.storemigration.StoreFile) FileOutputStream(java.io.FileOutputStream) RecordFormatSelector.selectForVersion(org.neo4j.kernel.impl.store.format.RecordFormatSelector.selectForVersion) IOException(java.io.IOException) NodeRecordFormat(org.neo4j.kernel.impl.store.format.standard.NodeRecordFormat) LegacyLogs(org.neo4j.kernel.impl.storemigration.legacylogs.LegacyLogs) File(java.io.File) Iterables(org.neo4j.helpers.collection.Iterables) ParallelBatchImporter(org.neo4j.unsafe.impl.batchimport.ParallelBatchImporter) NodeRecord(org.neo4j.kernel.impl.store.record.NodeRecord) Configuration(org.neo4j.unsafe.impl.batchimport.Configuration) BufferedReader(java.io.BufferedReader) MigrationProgressMonitor(org.neo4j.kernel.impl.storemigration.monitoring.MigrationProgressMonitor) RelationshipRecord(org.neo4j.kernel.impl.store.record.RelationshipRecord) StoreUpgrader(org.neo4j.kernel.impl.storemigration.StoreUpgrader) NoSuchFileException(java.nio.file.NoSuchFileException) BASE_TX_LOG_VERSION(org.neo4j.kernel.impl.transaction.log.TransactionIdStore.BASE_TX_LOG_VERSION) BASE_TX_CHECKSUM(org.neo4j.kernel.impl.transaction.log.TransactionIdStore.BASE_TX_CHECKSUM) PageCache(org.neo4j.io.pagecache.PageCache) InputNode(org.neo4j.unsafe.impl.batchimport.input.InputNode) Predicate(java.util.function.Predicate) Collection(java.util.Collection) StandardOpenOption(java.nio.file.StandardOpenOption) MOVE(org.neo4j.kernel.impl.storemigration.FileOperation.MOVE) LogService(org.neo4j.kernel.impl.logging.LogService) List(java.util.List) StoreFileType(org.neo4j.kernel.impl.storemigration.StoreFileType) MetaDataStore(org.neo4j.kernel.impl.store.MetaDataStore) Writer(java.io.Writer) Optional(java.util.Optional) Inputs(org.neo4j.unsafe.impl.batchimport.input.Inputs) InputIterable(org.neo4j.unsafe.impl.batchimport.InputIterable) InputRelationship(org.neo4j.unsafe.impl.batchimport.input.InputRelationship) TransactionIdStore(org.neo4j.kernel.impl.transaction.log.TransactionIdStore) InputEntity(org.neo4j.unsafe.impl.batchimport.input.InputEntity) DEFAULT_NAME(org.neo4j.kernel.impl.store.MetaDataStore.DEFAULT_NAME) RecordFormats(org.neo4j.kernel.impl.store.format.RecordFormats) CustomIOConfigValidator(org.neo4j.kernel.impl.util.CustomIOConfigValidator) AdditionalInitialIds(org.neo4j.unsafe.impl.batchimport.AdditionalInitialIds) NeoStores(org.neo4j.kernel.impl.store.NeoStores) StorePropertyCursor(org.neo4j.kernel.impl.api.store.StorePropertyCursor) CountsTracker(org.neo4j.kernel.impl.store.counts.CountsTracker) ExistingTargetStrategy(org.neo4j.kernel.impl.storemigration.ExistingTargetStrategy) PhysicalLogFiles(org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles) RelationshipRecordFormat(org.neo4j.kernel.impl.store.format.standard.RelationshipRecordFormat) OutputStream(java.io.OutputStream) Config(org.neo4j.kernel.configuration.Config) ReadOnlyIdGeneratorFactory(org.neo4j.kernel.impl.store.id.ReadOnlyIdGeneratorFactory) LockService(org.neo4j.kernel.impl.locking.LockService) FileHandle(org.neo4j.io.pagecache.FileHandle) CapabilityType(org.neo4j.kernel.impl.store.format.CapabilityType) PrimitiveRecord(org.neo4j.kernel.impl.store.record.PrimitiveRecord) FIELD_NOT_PRESENT(org.neo4j.kernel.impl.store.format.standard.MetaDataRecordFormat.FIELD_NOT_PRESENT) StoreMigratorCheckPointer(org.neo4j.kernel.impl.storemigration.StoreMigratorCheckPointer) ExecutionMonitor(org.neo4j.unsafe.impl.batchimport.staging.ExecutionMonitor) BASE_TX_LOG_BYTE_OFFSET(org.neo4j.kernel.impl.transaction.log.TransactionIdStore.BASE_TX_LOG_BYTE_OFFSET) FileSystemAbstraction(org.neo4j.io.fs.FileSystemAbstraction) StorePropertyCursor(org.neo4j.kernel.impl.api.store.StorePropertyCursor) ArrayList(java.util.ArrayList)

Example 5 with PrimitiveRecord

use of org.neo4j.kernel.impl.store.record.PrimitiveRecord in project neo4j by neo4j.

the class BatchInserterImpl method setPrimitiveProperty.

private void setPrimitiveProperty(RecordProxy<Long, ? extends PrimitiveRecord, Void> primitiveRecord, String propertyName, Object propertyValue) {
    int propertyKey = getOrCreatePropertyKeyId(propertyName);
    RecordAccess<Long, PropertyRecord, PrimitiveRecord> propertyRecords = recordAccess.getPropertyRecords();
    propertyCreator.primitiveSetProperty(primitiveRecord, propertyKey, propertyValue, propertyRecords);
}
Also used : PropertyRecord(org.neo4j.kernel.impl.store.record.PropertyRecord) UniquenessConstraint(org.neo4j.kernel.api.constraints.UniquenessConstraint) PrimitiveRecord(org.neo4j.kernel.impl.store.record.PrimitiveRecord)

Aggregations

PrimitiveRecord (org.neo4j.kernel.impl.store.record.PrimitiveRecord)17 PropertyRecord (org.neo4j.kernel.impl.store.record.PropertyRecord)14 PropertyBlock (org.neo4j.kernel.impl.store.record.PropertyBlock)7 NodeRecord (org.neo4j.kernel.impl.store.record.NodeRecord)5 RelationshipRecord (org.neo4j.kernel.impl.store.record.RelationshipRecord)5 NeoStores (org.neo4j.kernel.impl.store.NeoStores)4 DynamicRecord (org.neo4j.kernel.impl.store.record.DynamicRecord)4 LabelTokenRecord (org.neo4j.kernel.impl.store.record.LabelTokenRecord)4 PropertyKeyTokenRecord (org.neo4j.kernel.impl.store.record.PropertyKeyTokenRecord)4 RelationshipGroupRecord (org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)4 RelationshipTypeTokenRecord (org.neo4j.kernel.impl.store.record.RelationshipTypeTokenRecord)4 SchemaRecord (org.neo4j.kernel.impl.store.record.SchemaRecord)4 ArrayList (java.util.ArrayList)3 List (java.util.List)3 NodeStore (org.neo4j.kernel.impl.store.NodeStore)3 RelationshipStore (org.neo4j.kernel.impl.store.RelationshipStore)3 LinkedList (java.util.LinkedList)2 MutableLongSet (org.eclipse.collections.api.set.primitive.MutableLongSet)2 SchemaRule (org.neo4j.internal.schema.SchemaRule)2 CursorContext (org.neo4j.io.pagecache.context.CursorContext)2