Search in sources :

Example 11 with PrimitiveRecord

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

the class Loaders method propertyLoader.

public static Loader<Long, PropertyRecord, PrimitiveRecord> propertyLoader(final PropertyStore store) {
    return new Loader<Long, PropertyRecord, PrimitiveRecord>() {

        @Override
        public PropertyRecord newUnused(Long key, PrimitiveRecord additionalData) {
            PropertyRecord record = new PropertyRecord(key);
            setOwner(record, additionalData);
            return andMarkAsCreated(record);
        }

        private void setOwner(PropertyRecord record, PrimitiveRecord owner) {
            if (owner != null) {
                owner.setIdTo(record);
            }
        }

        @Override
        public PropertyRecord load(Long key, PrimitiveRecord additionalData) {
            PropertyRecord record = store.getRecord(key, store.newRecord(), NORMAL);
            setOwner(record, additionalData);
            return record;
        }

        @Override
        public void ensureHeavy(PropertyRecord record) {
            for (PropertyBlock block : record) {
                store.ensureHeavy(block);
            }
        }

        @Override
        public PropertyRecord clone(PropertyRecord propertyRecord) {
            return propertyRecord.clone();
        }
    };
}
Also used : PropertyRecord(org.neo4j.kernel.impl.store.record.PropertyRecord) PropertyBlock(org.neo4j.kernel.impl.store.record.PropertyBlock) Loader(org.neo4j.kernel.impl.transaction.state.RecordAccess.Loader) PrimitiveRecord(org.neo4j.kernel.impl.store.record.PrimitiveRecord)

Example 12 with PrimitiveRecord

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

the class PropertyCreator method primitiveSetProperty.

public <P extends PrimitiveRecord> void primitiveSetProperty(RecordProxy<Long, P, Void> primitiveRecordChange, int propertyKey, Object value, RecordAccess<Long, PropertyRecord, PrimitiveRecord> propertyRecords) {
    PropertyBlock block = encodePropertyValue(propertyKey, value);
    P primitive = primitiveRecordChange.forReadingLinkage();
    assert traverser.assertPropertyChain(primitive, propertyRecords);
    int newBlockSizeInBytes = block.getSize();
    // Traverse the existing property chain. Tracking two things along the way:
    // - (a) Free space for this block (candidateHost)
    // - (b) Existence of a block with the property key
    // Chain traversal can be aborted only if:
    // - (1) (b) occurs and new property block fits where the current is
    // - (2) (a) occurs and (b) has occurred, but new property block didn't fit
    // - (3) (b) occurs and (a) has occurred
    // - (4) Chain ends
    RecordProxy<Long, PropertyRecord, PrimitiveRecord> freeHostProxy = null;
    RecordProxy<Long, PropertyRecord, PrimitiveRecord> existingHostProxy = null;
    long prop = primitive.getNextProp();
    while (// <-- (4)
    prop != Record.NO_NEXT_PROPERTY.intValue()) {
        RecordProxy<Long, PropertyRecord, PrimitiveRecord> proxy = propertyRecords.getOrLoad(prop, primitive);
        PropertyRecord propRecord = proxy.forReadingLinkage();
        assert propRecord.inUse() : propRecord;
        // (a) search for free space
        if (propertyFitsInside(newBlockSizeInBytes, propRecord)) {
            freeHostProxy = proxy;
            if (existingHostProxy != null) {
                // (2)
                PropertyRecord freeHost = proxy.forChangingData();
                freeHost.addPropertyBlock(block);
                freeHost.setChanged(primitive);
                assert traverser.assertPropertyChain(primitive, propertyRecords);
                return;
            }
        }
        // (b) search for existence of property key
        PropertyBlock existingBlock = propRecord.getPropertyBlock(propertyKey);
        if (existingBlock != null) {
            // We found an existing property and whatever happens we have to remove the existing
            // block so that we can add the new one, where ever we decide to place it
            existingHostProxy = proxy;
            PropertyRecord existingHost = existingHostProxy.forChangingData();
            removeProperty(primitive, existingHost, existingBlock);
            // Now see if we at this point can add the new block
            if (// cheap check
            newBlockSizeInBytes <= existingBlock.getSize() || // fallback check
            propertyFitsInside(newBlockSizeInBytes, existingHost)) {
                // (1) yes we could add it right into the host of the existing block
                existingHost.addPropertyBlock(block);
                assert traverser.assertPropertyChain(primitive, propertyRecords);
                return;
            } else if (freeHostProxy != null) {
                // (3) yes we could add it to a previously found host with sufficiently free space in it
                PropertyRecord freeHost = freeHostProxy.forChangingData();
                freeHost.addPropertyBlock(block);
                freeHost.setChanged(primitive);
                assert traverser.assertPropertyChain(primitive, propertyRecords);
                return;
            }
        // else we can't add it at this point
        }
        // Continue down the chain
        prop = propRecord.getNextProp();
    }
    // At this point we haven't added the property block, although we may have found room for it
    // along the way. If we didn't then just create a new record, it's fine
    PropertyRecord freeHost = null;
    if (freeHostProxy == null) {
        // We couldn't find free space along the way, so create a new host record
        freeHost = propertyRecords.create(propertyRecordIdGenerator.nextId(), primitive).forChangingData();
        freeHost.setInUse(true);
        if (primitive.getNextProp() != Record.NO_NEXT_PROPERTY.intValue()) {
            // This isn't the first property record for the entity, re-shuffle the first one so that
            // the new one becomes the first
            PropertyRecord prevProp = propertyRecords.getOrLoad(primitive.getNextProp(), primitive).forChangingLinkage();
            assert prevProp.getPrevProp() == Record.NO_PREVIOUS_PROPERTY.intValue();
            prevProp.setPrevProp(freeHost.getId());
            freeHost.setNextProp(prevProp.getId());
            prevProp.setChanged(primitive);
        }
        // By the way, this is the only condition where the primitive record also needs to change
        primitiveRecordChange.forChangingLinkage().setNextProp(freeHost.getId());
    } else {
        freeHost = freeHostProxy.forChangingData();
    }
    // At this point we know that we have a host record with sufficient space in it for the block
    // to add, so simply add it
    freeHost.addPropertyBlock(block);
    assert traverser.assertPropertyChain(primitive, propertyRecords);
}
Also used : 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 13 with PrimitiveRecord

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

the class PropertyCreator method primitiveSetProperty.

public <P extends PrimitiveRecord> void primitiveSetProperty(RecordProxy<P, ?> primitiveRecordChange, int propertyKey, Value value, RecordAccess<PropertyRecord, PrimitiveRecord> propertyRecords) {
    PropertyBlock block = encodePropertyValue(propertyKey, value);
    P primitive = primitiveRecordChange.forReadingLinkage();
    assert traverser.assertPropertyChain(primitive, propertyRecords);
    // Traverse the existing property chain. Tracking two things along the way:
    // - (a) Free space for this block (candidateHost)
    // - (b) Existence of a block with the property key
    // Chain traversal can be aborted only if:
    // - (1) (b) occurs and new property block fits where the current is
    // - (2) (a) occurs and (b) has occurred, but new property block didn't fit
    // - (3) (b) occurs and (a) has occurred
    // - (4) Chain ends
    RecordProxy<PropertyRecord, PrimitiveRecord> freeHostProxy = null;
    RecordProxy<PropertyRecord, PrimitiveRecord> existingHostProxy = null;
    long prop = primitive.getNextProp();
    while (// <-- (4)
    prop != Record.NO_NEXT_PROPERTY.intValue()) {
        RecordProxy<PropertyRecord, PrimitiveRecord> proxy = propertyRecords.getOrLoad(prop, primitive, cursorContext);
        PropertyRecord propRecord = proxy.forReadingLinkage();
        assert propRecord.inUse() : propRecord;
        // (a) search for free space
        if (propRecord.hasSpaceFor(block)) {
            freeHostProxy = proxy;
            if (existingHostProxy != null) {
                // (2)
                PropertyRecord freeHost = proxy.forChangingData();
                freeHost.addPropertyBlock(block);
                freeHost.setChanged(primitive);
                assert traverser.assertPropertyChain(primitive, propertyRecords);
                return;
            }
        }
        // (b) search for existence of property key
        PropertyBlock existingBlock = propRecord.getPropertyBlock(propertyKey);
        if (existingBlock != null) {
            // We found an existing property and whatever happens we have to remove the existing
            // block so that we can add the new one, where ever we decide to place it
            existingHostProxy = proxy;
            PropertyRecord existingHost = existingHostProxy.forChangingData();
            removeProperty(primitive, existingHost, existingBlock);
            // Now see if we at this point can add the new block
            if (// cheap check
            block.getSize() <= existingBlock.getSize() || // fallback check
            existingHost.hasSpaceFor(block)) {
                // (1) yes we could add it right into the host of the existing block
                existingHost.addPropertyBlock(block);
                assert traverser.assertPropertyChain(primitive, propertyRecords);
                return;
            } else if (freeHostProxy != null) {
                // (3) yes we could add it to a previously found host with sufficiently free space in it
                PropertyRecord freeHost = freeHostProxy.forChangingData();
                freeHost.addPropertyBlock(block);
                freeHost.setChanged(primitive);
                assert traverser.assertPropertyChain(primitive, propertyRecords);
                return;
            }
        // else we can't add it at this point
        }
        // Continue down the chain
        prop = propRecord.getNextProp();
    }
    // At this point we haven't added the property block, although we may have found room for it
    // along the way. If we didn't then just create a new record, it's fine
    PropertyRecord freeHost;
    if (freeHostProxy == null) {
        // We couldn't find free space along the way, so create a new host record
        freeHost = propertyRecords.create(propertyRecordIdGenerator.nextId(cursorContext), primitive, cursorContext).forChangingData();
        freeHost.setInUse(true);
        if (primitive.getNextProp() != Record.NO_NEXT_PROPERTY.intValue()) {
            // This isn't the first property record for the entity, re-shuffle the first one so that
            // the new one becomes the first
            PropertyRecord prevProp = propertyRecords.getOrLoad(primitive.getNextProp(), primitive, cursorContext).forChangingLinkage();
            assert prevProp.getPrevProp() == Record.NO_PREVIOUS_PROPERTY.intValue();
            prevProp.setPrevProp(freeHost.getId());
            freeHost.setNextProp(prevProp.getId());
            prevProp.setChanged(primitive);
        }
        // By the way, this is the only condition where the primitive record also needs to change
        primitiveRecordChange.forChangingLinkage().setNextProp(freeHost.getId());
    } else {
        freeHost = freeHostProxy.forChangingData();
    }
    // At this point we know that we have a host record with sufficient space in it for the block
    // to add, so simply add it
    freeHost.addPropertyBlock(block);
    assert traverser.assertPropertyChain(primitive, propertyRecords);
}
Also used : 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 14 with PrimitiveRecord

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

the class PropertyDeleter method removeProperty.

private <P extends PrimitiveRecord> void removeProperty(RecordProxy<P, Void> primitiveProxy, int propertyKey, RecordAccess<PropertyRecord, PrimitiveRecord> propertyRecords, PrimitiveRecord primitive, long propertyId) {
    RecordProxy<PropertyRecord, PrimitiveRecord> recordChange = propertyRecords.getOrLoad(propertyId, primitive, cursorContext);
    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 15 with PrimitiveRecord

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

the class PropertyDeleter method removePropertyIfExists.

/**
 * Removes property with given {@code propertyKey} from property chain owner by the primitive found in
 * {@code primitiveProxy} if it exists.
 *
 * @param primitiveProxy access to the primitive record pointing to the start of the property chain.
 * @param propertyKey the property key token id to look for and remove.
 * @param propertyRecords access to records.
 * @return {@code true} if the property was found and removed, otherwise {@code false}.
 */
public <P extends PrimitiveRecord> boolean removePropertyIfExists(RecordProxy<P, Void> primitiveProxy, int propertyKey, RecordAccess<PropertyRecord, PrimitiveRecord> propertyRecords) {
    PrimitiveRecord primitive = primitiveProxy.forReadingData();
    // propertyData.getId();
    long propertyId = traverser.findPropertyRecordContaining(primitive, propertyKey, propertyRecords, false);
    if (!Record.NO_NEXT_PROPERTY.is(propertyId)) {
        removeProperty(primitiveProxy, propertyKey, propertyRecords, primitive, propertyId);
        return true;
    }
    return false;
}
Also used : 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