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