Search in sources :

Example 6 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 7 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 8 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)

Aggregations

PrimitiveRecord (org.neo4j.kernel.impl.store.record.PrimitiveRecord)8 PropertyRecord (org.neo4j.kernel.impl.store.record.PropertyRecord)7 PropertyBlock (org.neo4j.kernel.impl.store.record.PropertyBlock)4 NodeRecord (org.neo4j.kernel.impl.store.record.NodeRecord)3 RelationshipRecord (org.neo4j.kernel.impl.store.record.RelationshipRecord)3 NeoStores (org.neo4j.kernel.impl.store.NeoStores)2 NodeStore (org.neo4j.kernel.impl.store.NodeStore)2 RelationshipStore (org.neo4j.kernel.impl.store.RelationshipStore)2 DynamicRecord (org.neo4j.kernel.impl.store.record.DynamicRecord)2 LabelTokenRecord (org.neo4j.kernel.impl.store.record.LabelTokenRecord)2 PropertyKeyTokenRecord (org.neo4j.kernel.impl.store.record.PropertyKeyTokenRecord)2 RelationshipGroupRecord (org.neo4j.kernel.impl.store.record.RelationshipGroupRecord)2 RelationshipTypeTokenRecord (org.neo4j.kernel.impl.store.record.RelationshipTypeTokenRecord)2 SchemaRecord (org.neo4j.kernel.impl.store.record.SchemaRecord)2 SchemaRule (org.neo4j.storageengine.api.schema.SchemaRule)2 BufferedOutputStream (java.io.BufferedOutputStream)1 BufferedReader (java.io.BufferedReader)1 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1