use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class BatchInserterImpl method getPropertyChain.
private Map<String, Object> getPropertyChain(long nextProp) {
PropertyStore propStore = getPropertyStore();
Map<String, Object> properties = new HashMap<String, Object>();
while (nextProp != Record.NO_NEXT_PROPERTY.intValue()) {
PropertyRecord propRecord = propStore.getRecord(nextProp);
for (PropertyBlock propBlock : propRecord.getPropertyBlocks()) {
String key = indexHolder.getStringKey(propBlock.getKeyIndexId());
PropertyData propertyData = propBlock.newPropertyData(propRecord);
Object value = propertyData.getValue() != null ? propertyData.getValue() : propBlock.getType().getValue(propBlock, getPropertyStore());
properties.put(key, value);
}
nextProp = propRecord.getNextProp();
}
return properties;
}
use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class PropertyWriter method writeProperties.
/**
* Transforms a mapping of key index ids to values into a property chain.
* Mostly copied-pasted from BatchTransactionImpl.
*
* @param properties The mapping, as a list of Pairs of keys and values
* @return a long value valid for a property record id that is the id of the
* head of the chain, suitable for a nextProp() value on a
* primitive.
*/
public long writeProperties(List<Pair<Integer, Object>> properties) {
if (properties == null || properties.isEmpty()) {
return Record.NO_NEXT_PROPERTY.intValue();
}
// To hold the records, we will write them out in reverse order
List<PropertyRecord> propRecords = new ArrayList<PropertyRecord>();
// There is at least one property, so we will create at least one record.
PropertyRecord currentRecord = new PropertyRecord(propertyStore.nextId());
currentRecord.setInUse(true);
currentRecord.setCreated();
propRecords.add(currentRecord);
for (Pair<Integer, Object> propertyDatum : properties) {
PropertyBlock block = new PropertyBlock();
propertyStore.encodeValue(block, propertyDatum.first(), propertyDatum.other());
if (currentRecord.size() + block.getSize() > PropertyType.getPayloadSize()) {
// Here it means the current block is done for
PropertyRecord prevRecord = currentRecord;
// Create new record
long propertyId = propertyStore.nextId();
currentRecord = new PropertyRecord(propertyId);
currentRecord.setInUse(true);
currentRecord.setCreated();
// Set up links
prevRecord.setNextProp(propertyId);
currentRecord.setPrevProp(prevRecord.getId());
propRecords.add(currentRecord);
// Now current is ready to start picking up blocks
}
currentRecord.addPropertyBlock(block);
}
/*
* Add the property records in reverse order, which means largest
* id first. That is to make sure we expand the property store file
* only once.
*/
for (int i = propRecords.size() - 1; i >= 0; i--) {
propertyStore.updateRecord(propRecords.get(i));
}
/*
* 0 will always exist, if the map was empty we wouldn't be here
* and even one property will create at least one record.
*/
return propRecords.get(0).getId();
}
use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class WriteTransaction method primitiveChangeProperty.
private PropertyData primitiveChangeProperty(PrimitiveRecord primitive, PropertyData propertyData, Object value, boolean isNode) {
assert assertPropertyChain(primitive);
long propertyId = propertyData.getId();
PropertyRecord propertyRecord = getPropertyRecord(propertyId, true, true);
if (!propertyRecord.inUse()) {
throw new IllegalStateException("Unable to change property[" + propertyId + "] since it has been deleted.");
}
if (isNode) {
propertyRecord.setNodeId(primitive.getId());
} else {
propertyRecord.setRelId(primitive.getId());
}
PropertyBlock block = propertyRecord.getPropertyBlock(propertyData.getIndex());
if (block == null) {
throw new IllegalStateException("Property with index[" + propertyData.getIndex() + "] is not present in property[" + propertyId + "]");
}
if (block.isLight()) {
getPropertyStore().makeHeavy(block);
}
propertyRecord.setChanged();
for (DynamicRecord record : block.getValueRecords()) {
assert record.inUse();
record.setInUse(false, block.getType().intValue());
propertyRecord.addDeletedRecord(record);
}
getPropertyStore().encodeValue(block, propertyData.getIndex(), value);
if (propertyRecord.size() > PropertyType.getPayloadSize()) {
propertyRecord.removePropertyBlock(propertyData.getIndex());
/*
* The record should never, ever be above max size. Less obviously, it should
* never remain empty. If removing a property because it won't fit when changing
* it leaves the record empty it means that this block was the last one which
* means that it doesn't fit in an empty record. Where i come from, we call this
* weird.
*
assert propertyRecord.size() <= PropertyType.getPayloadSize() : propertyRecord;
assert propertyRecord.size() > 0 : propertyRecord;
*/
propertyRecord = addPropertyBlockToPrimitive(block, primitive, isNode);
}
assert assertPropertyChain(primitive);
return block.newPropertyData(propertyRecord, value);
}
use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class WriteTransaction method relRemoveProperty.
@Override
public void relRemoveProperty(long relId, PropertyData propertyData) {
long propertyId = propertyData.getId();
RelationshipRecord relRecord = getRelationshipRecord(relId);
if (relRecord == null) {
relRecord = getRelationshipStore().getRecord(relId);
}
if (!relRecord.inUse()) {
throw new IllegalStateException("Property remove on relationship[" + relId + "] illegal since it has been deleted.");
}
assert assertPropertyChain(relRecord);
PropertyRecord propRecord = getPropertyRecord(propertyId, false, true);
if (!propRecord.inUse()) {
throw new IllegalStateException("Unable to delete property[" + propertyId + "] since it is already deleted.");
}
propRecord.setRelId(relId);
PropertyBlock block = propRecord.removePropertyBlock(propertyData.getIndex());
if (block == null) {
throw new IllegalStateException("Property with index[" + propertyData.getIndex() + "] is not present in property[" + propertyId + "]");
}
if (block.isLight()) {
getPropertyStore().makeHeavy(block);
}
// TODO: update count on property index record
for (DynamicRecord valueRecord : block.getValueRecords()) {
assert valueRecord.inUse();
valueRecord.setInUse(false, block.getType().intValue());
propRecord.addDeletedRecord(valueRecord);
}
if (propRecord.size() > 0) {
propRecord.setChanged();
assert assertPropertyChain(relRecord);
return;
} else {
if (unlinkPropertyRecord(propRecord, relRecord)) {
addRelationshipRecord(relRecord);
}
}
}
use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class WriteTransaction method relAddProperty.
@Override
public PropertyData relAddProperty(long relId, PropertyIndex index, Object value) {
RelationshipRecord relRecord = getRelationshipRecord(relId);
if (relRecord == null) {
relRecord = getRelationshipStore().getRecord(relId);
addRelationshipRecord(relRecord);
}
if (!relRecord.inUse()) {
throw new IllegalStateException("Property add on relationship[" + relId + "] illegal since it has been deleted.");
}
assert assertPropertyChain(relRecord);
PropertyBlock block = new PropertyBlock();
block.setCreated();
getPropertyStore().encodeValue(block, index.getKeyId(), value);
PropertyRecord host = addPropertyBlockToPrimitive(block, relRecord, /*isNode*/
false);
assert assertPropertyChain(relRecord);
return block.newPropertyData(host, value);
}
Aggregations