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();
}
};
}
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);
}
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);
}
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);
}
}
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;
}
Aggregations