use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class BatchInserterImpl method createPropertyChain.
private long createPropertyChain(Map<String, Object> properties) {
if (properties == null || properties.isEmpty()) {
return Record.NO_NEXT_PROPERTY.intValue();
}
PropertyStore propStore = getPropertyStore();
List<PropertyRecord> propRecords = new ArrayList<PropertyRecord>();
PropertyRecord currentRecord = new PropertyRecord(propStore.nextId());
currentRecord.setInUse(true);
currentRecord.setCreated();
propRecords.add(currentRecord);
for (Entry<String, Object> entry : properties.entrySet()) {
int keyId = indexHolder.getKeyId(entry.getKey());
if (keyId == -1) {
keyId = createNewPropertyIndex(entry.getKey());
}
PropertyBlock block = new PropertyBlock();
propStore.encodeValue(block, keyId, entry.getValue());
if (currentRecord.size() + block.getSize() > PropertyType.getPayloadSize()) {
// Here it means the current block is done for
PropertyRecord prevRecord = currentRecord;
// Create new record
long propertyId = propStore.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--) {
propStore.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 loadPropertyValue.
@Override
public Object loadPropertyValue(PropertyData propertyData) {
PropertyRecord propertyRecord = propertyRecords.get(propertyData.getId());
if (propertyRecord == null) {
propertyRecord = getPropertyStore().getRecord(propertyData.getId());
}
PropertyBlock block = propertyRecord.getPropertyBlock(propertyData.getIndex());
if (block == null) {
throw new IllegalStateException("Property with index[" + propertyData.getIndex() + "] is not present in property[" + propertyData.getId() + "]");
}
if (block.isLight()) {
getPropertyStore().makeHeavy(block);
}
return block.getType().getValue(block, getPropertyStore());
}
use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class WriteTransaction method nodeAddProperty.
@Override
public PropertyData nodeAddProperty(long nodeId, PropertyIndex index, Object value) {
NodeRecord nodeRecord = getNodeRecord(nodeId);
if (nodeRecord == null) {
nodeRecord = getNodeStore().getRecord(nodeId);
addNodeRecord(nodeRecord);
}
if (!nodeRecord.inUse()) {
throw new IllegalStateException("Property add on node[" + nodeId + "] illegal since it has been deleted.");
}
assert assertPropertyChain(nodeRecord);
PropertyBlock block = new PropertyBlock();
block.setCreated();
/*
* Encoding has to be set here before anything is changed,
* since an exception could be thrown in encodeValue now and tx not marked
* rollback only.
*/
getPropertyStore().encodeValue(block, index.getKeyId(), value);
PropertyRecord host = addPropertyBlockToPrimitive(block, nodeRecord, /*isNode*/
true);
assert assertPropertyChain(nodeRecord);
return block.newPropertyData(host, value);
}
use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class Command method readPropertyBlock.
static PropertyBlock readPropertyBlock(ReadableByteChannel byteChannel, ByteBuffer buffer) throws IOException {
PropertyBlock toReturn = new PropertyBlock();
buffer.clear();
buffer.limit(1);
if (byteChannel.read(buffer) != buffer.limit()) {
return null;
}
buffer.flip();
// the size is stored in bytes // 1
byte blockSize = buffer.get();
assert blockSize > 0 && blockSize % 8 == 0 : blockSize + " is not a valid block size value";
// Read in blocks
buffer.clear();
/*
* We add 4 to avoid another limit()/read() for the DynamicRecord size
* field later on
*/
buffer.limit(blockSize + 4);
if (byteChannel.read(buffer) != buffer.limit()) {
return null;
}
buffer.flip();
long[] blocks = readLongs(buffer, blockSize / 8);
assert blocks.length == blockSize / 8 : blocks.length + " longs were read in while i asked for what corresponds to " + blockSize;
assert PropertyType.getPropertyType(blocks[0], false).calculateNumberOfBlocksUsed(blocks[0]) == blocks.length : blocks.length + " is not a valid number of blocks for type " + PropertyType.getPropertyType(blocks[0], false);
/*
* Ok, now we may be ready to return, if there are no DynamicRecords. So
* we start building the Object
*/
toReturn.setValueBlocks(blocks);
/*
* Read in existence of DynamicRecords. Remember, this has already been
* read in the buffer with the blocks, above.
*/
int noOfDynRecs = buffer.getInt();
assert noOfDynRecs >= 0 : noOfDynRecs + " is not a valid value for the number of dynamic records in a property block";
if (noOfDynRecs != 0) {
for (int i = 0; i < noOfDynRecs; i++) {
DynamicRecord dr = readDynamicRecord(byteChannel, buffer);
if (dr == null) {
return null;
}
// writePropertyBlock always writes only newly
dr.setCreated();
// created chains
toReturn.addValueRecord(dr);
}
assert toReturn.getValueRecords().size() == noOfDynRecs : "read in " + toReturn.getValueRecords().size() + " instead of the proper " + noOfDynRecs;
}
return toReturn;
}
use of org.neo4j.kernel.impl.nioneo.store.PropertyBlock in project neo4j-mobile-android by neo4j-contrib.
the class BatchInserterImpl method deletePropertyChain.
private void deletePropertyChain(long nextProp) {
PropertyStore propStore = getPropertyStore();
while (nextProp != Record.NO_NEXT_PROPERTY.intValue()) {
PropertyRecord propRecord = propStore.getRecord(nextProp);
for (PropertyBlock propBlock : propRecord.getPropertyBlocks()) {
propStore.makeHeavy(propBlock);
for (DynamicRecord rec : propBlock.getValueRecords()) {
rec.setInUse(false);
propRecord.addDeletedRecord(rec);
}
}
propRecord.setInUse(false);
nextProp = propRecord.getNextProp();
propStore.updateRecord(propRecord);
}
}
Aggregations