use of org.neo4j.kernel.impl.store.PropertyType in project neo4j by neo4j.
the class RecordPropertyCursor method next.
@Override
public boolean next() {
while (true) {
// Figure out number of blocks of record
int numberOfBlocks = getNumberOfBlocks();
while (block < numberOfBlocks) {
// We have just read a record, so we are at the beginning
if (block == INITIAL_POSITION) {
block = 0;
} else {
// Figure out the type and how many blocks that are used
long current = currentBlock();
PropertyType type = PropertyType.getPropertyTypeOrNull(current);
if (type == null) {
break;
}
block += type.calculateNumberOfBlocksUsed(current);
}
// nothing left, need to read a new record
if (block >= numberOfBlocks || type() == null) {
break;
}
return true;
}
if (next == NO_ID) {
return false;
}
property(this, next, page);
next = getNextProp();
block = INITIAL_POSITION;
if (++numSeenPropertyRecords >= CYCLE_DETECTION_THRESHOLD) {
if (cycleDetection == null) {
cycleDetection = LongSets.mutable.empty();
}
if (!cycleDetection.add(next)) {
throw new InconsistentDataReadException("Aborting property reading due to detected chain cycle, starting at property record id:%d from owner %s:%d", first, ownerEntityType, ownerReference);
}
}
}
}
use of org.neo4j.kernel.impl.store.PropertyType in project neo4j by neo4j.
the class SafePropertyChainReader method read.
<PRIMITIVE extends PrimitiveRecord> boolean read(MutableIntObjectMap<Value> intoValues, PRIMITIVE entity, Function<PRIMITIVE, ConsistencyReport.PrimitiveConsistencyReport> primitiveReporter, CursorContext cursorContext) {
lightClear(seenRecords);
long propertyRecordId = entity.getNextProp();
long previousRecordId = NULL_REFERENCE.longValue();
boolean chainIsOk = true;
while (!NULL_REFERENCE.is(propertyRecordId) && !context.isCancelled()) {
if (!seenRecords.add(propertyRecordId)) {
primitiveReporter.apply(entity).propertyChainContainsCircularReference(propertyReader.record());
chainIsOk = false;
break;
}
PropertyRecord propertyRecord = propertyReader.read(propertyRecordId);
if (!propertyRecord.inUse()) {
primitiveReporter.apply(entity).propertyNotInUse(propertyRecord);
reporter.forProperty(context.recordLoader.property(previousRecordId, cursorContext)).nextNotInUse(propertyRecord);
chainIsOk = false;
} else {
if (propertyRecord.getPrevProp() != previousRecordId) {
if (NULL_REFERENCE.is(previousRecordId)) {
primitiveReporter.apply(entity).propertyNotFirstInChain(propertyRecord);
} else {
reporter.forProperty(context.recordLoader.property(previousRecordId, cursorContext)).nextDoesNotReferenceBack(propertyRecord);
// prevDoesNotReferenceBack is not reported, unnecessary double report (same inconsistency from different directions)
}
chainIsOk = false;
}
for (PropertyBlock block : propertyRecord) {
int propertyKeyId = block.getKeyIndexId();
if (!checkValidToken(propertyRecord, propertyKeyId, context.tokenHolders.propertyKeyTokens(), neoStores.getPropertyKeyTokenStore(), (property, token) -> reporter.forProperty(property).invalidPropertyKey(block), (property, token) -> reporter.forProperty(property).keyNotInUse(block, token), cursorContext)) {
chainIsOk = false;
}
PropertyType type = block.forceGetType();
Value value = Values.NO_VALUE;
if (type == null) {
reporter.forProperty(propertyRecord).invalidPropertyType(block);
} else {
try {
switch(type) {
case STRING:
dynamicRecords.clear();
if (safeLoadDynamicRecordChain(record -> dynamicRecords.add(record.copy()), stringReader, seenDynamicRecordIds, block.getSingleValueLong(), stringStoreBlockSize, NO_DYNAMIC_HANDLER, (id, record) -> reporter.forProperty(propertyRecord).stringNotInUse(block, record), (id, record) -> reporter.forDynamicBlock(RecordType.STRING_PROPERTY, stringReader.record()).nextNotInUse(record), (id, record) -> reporter.forProperty(propertyRecord).stringEmpty(block, record), record -> reporter.forDynamicBlock(RecordType.STRING_PROPERTY, record).recordNotFullReferencesNext(), record -> reporter.forDynamicBlock(RecordType.STRING_PROPERTY, record).invalidLength())) {
value = propertyStore.getTextValueFor(dynamicRecords, cursorContext);
}
break;
case ARRAY:
dynamicRecords.clear();
if (safeLoadDynamicRecordChain(record -> dynamicRecords.add(record.copy()), arrayReader, seenDynamicRecordIds, block.getSingleValueLong(), arrayStoreBlockSize, NO_DYNAMIC_HANDLER, (id, record) -> reporter.forProperty(propertyRecord).arrayNotInUse(block, record), (id, record) -> reporter.forDynamicBlock(RecordType.ARRAY_PROPERTY, arrayReader.record()).nextNotInUse(record), (id, record) -> reporter.forProperty(propertyRecord).arrayEmpty(block, record), record -> reporter.forDynamicBlock(RecordType.ARRAY_PROPERTY, record).recordNotFullReferencesNext(), record -> reporter.forDynamicBlock(RecordType.ARRAY_PROPERTY, record).invalidLength())) {
value = propertyStore.getArrayFor(dynamicRecords, cursorContext);
}
break;
default:
value = type.value(block, null, cursorContext);
break;
}
} catch (Exception e) {
reporter.forProperty(propertyRecord).invalidPropertyValue(propertyRecord.getId(), block.getKeyIndexId());
}
}
if (value == Values.NO_VALUE) {
chainIsOk = false;
} else if (propertyKeyId >= 0 && intoValues.put(propertyKeyId, value) != null) {
primitiveReporter.apply(entity).propertyKeyNotUniqueInChain();
chainIsOk = false;
}
}
}
previousRecordId = propertyRecordId;
propertyRecordId = propertyRecord.getNextProp();
}
return chainIsOk;
}
use of org.neo4j.kernel.impl.store.PropertyType in project neo4j by neo4j.
the class PropertyBlock method toString.
@Override
public String toString() {
StringBuilder result = new StringBuilder("PropertyBlock[");
PropertyType type = getType();
if (valueBlocks != null) {
result.append("blocks=").append(valueBlocks.length).append(',');
}
result.append(type == null ? "<unknown type>" : type.name()).append(',');
result.append("key=").append(valueBlocks == null ? "?" : Integer.toString(getKeyIndexId()));
if (type != null) {
switch(type) {
case STRING:
case ARRAY:
result.append(",firstDynamic=").append(getSingleValueLong());
break;
default:
Object value = type.value(this, null, CursorContext.NULL).asObject();
if (value != null && value.getClass().isArray()) {
int length = Array.getLength(value);
StringBuilder buf = new StringBuilder(value.getClass().getComponentType().getSimpleName()).append('[');
for (int i = 0; i < length && i <= MAX_ARRAY_TOSTRING_SIZE; i++) {
if (i != 0) {
buf.append(',');
}
buf.append(Array.get(value, i));
}
if (length > MAX_ARRAY_TOSTRING_SIZE) {
buf.append(",...");
}
value = buf.append(']');
}
result.append(",value=").append(value);
break;
}
}
if (!isLight()) {
result.append(",ValueRecords[");
Iterator<DynamicRecord> recIt = valueRecords.iterator();
while (recIt.hasNext()) {
result.append(recIt.next());
if (recIt.hasNext()) {
result.append(',');
}
}
result.append(']');
}
result.append(']');
return result.toString();
}
use of org.neo4j.kernel.impl.store.PropertyType in project neo4j by neo4j.
the class PropertyRecord method ensureBlocksLoaded.
/**
* Reads blocks[] and constructs {@link PropertyBlock} instances from them, making that abstraction
* available to the outside. Done the first time any PropertyBlock is needed or manipulated.
*/
public void ensureBlocksLoaded() {
if (!blocksLoaded) {
assert blockRecordsCursor == 0;
// We haven't loaded the blocks yet, please do so now
int index = 0;
while (index < blocksCursor) {
PropertyType type = PropertyType.getPropertyTypeOrThrow(blocks[index]);
PropertyBlock block = new PropertyBlock();
int length = type.calculateNumberOfBlocksUsed(blocks[index]);
block.setValueBlocks(Arrays.copyOfRange(blocks, index, index + length));
blockRecords[blockRecordsCursor++] = block;
index += length;
}
blocksLoaded = true;
}
}
use of org.neo4j.kernel.impl.store.PropertyType in project neo4j by neo4j.
the class PropertyRecordFormat method read.
@Override
public void read(PropertyRecord record, PageCursor cursor, RecordLoad mode, int recordSize, int recordsPerPage) {
int offsetAtBeginning = cursor.getOffset();
/*
* [pppp,nnnn] previous, next high bits
*/
byte modifiers = cursor.getByte();
long prevMod = (modifiers & 0xF0L) << 28;
long nextMod = (modifiers & 0x0FL) << 32;
long prevProp = cursor.getInt() & 0xFFFFFFFFL;
long nextProp = cursor.getInt() & 0xFFFFFFFFL;
record.initialize(false, BaseRecordFormat.longFromIntAndMod(prevProp, prevMod), BaseRecordFormat.longFromIntAndMod(nextProp, nextMod));
while (cursor.getOffset() - offsetAtBeginning < RECORD_SIZE) {
long block = cursor.getLong();
PropertyType type = PropertyType.getPropertyTypeOrNull(block);
if (type == null) {
// We assume that storage is defragged
break;
}
record.setInUse(true);
record.addLoadedBlock(block);
int numberOfBlocksUsed = type.calculateNumberOfBlocksUsed(block);
if (numberOfBlocksUsed == PropertyType.BLOCKS_USED_FOR_BAD_TYPE_OR_ENCODING) {
cursor.setCursorException("Invalid type or encoding of property block: " + block + " (type = " + type + ")");
return;
}
int additionalBlocks = numberOfBlocksUsed - 1;
if (additionalBlocks * Long.BYTES > RECORD_SIZE - (cursor.getOffset() - offsetAtBeginning)) {
cursor.setCursorException(format("PropertyRecord[%d] claims to have more property blocks than can fit in a record. " + "additionalBlocks:%d, recordSize:%d, cursorOffset:%d, offsetAtBeginning:%d", record.getId(), additionalBlocks, RECORD_SIZE, cursor.getOffset(), offsetAtBeginning));
return;
}
while (additionalBlocks-- > 0) {
record.addLoadedBlock(cursor.getLong());
}
}
}
Aggregations