use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class CompositePageCursorTest method getLongOffsettedBeyondEndOfViewMustRaiseBoundsFlag.
@Test
public void getLongOffsettedBeyondEndOfViewMustRaiseBoundsFlag() throws Exception {
PageCursor pageCursor = CompositePageCursor.compose(first, PAGE_SIZE, second, PAGE_SIZE);
for (int i = 0; i < 3 * PAGE_SIZE; i++) {
pageCursor.getLong(i);
}
assertTrue(pageCursor.checkAndClearBoundsFlag());
assertFalse(pageCursor.checkAndClearBoundsFlag());
}
use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class CompositePageCursorTest method overlappingOffsettedGetAccess.
@Test
public void overlappingOffsettedGetAccess() throws Exception {
PageCursor c = CompositePageCursor.compose(first, PAGE_SIZE, second, PAGE_SIZE);
assertThat(c.getInt(PAGE_SIZE - 2), is(0xAEAFB0B1));
assertThat(c.getShort(PAGE_SIZE - 1), is((short) 0xAFB0));
assertThat(c.getLong(PAGE_SIZE - 4), is(0xACADAEAFB0B1B2B3L));
}
use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class CompositePageCursorTest method putByteOffsettedBeforeFirstPageMustRaiseBoundsFlag.
@Test
public void putByteOffsettedBeforeFirstPageMustRaiseBoundsFlag() throws Exception {
PageCursor pageCursor = CompositePageCursor.compose(first, PAGE_SIZE, second, PAGE_SIZE);
pageCursor.putByte(-1, (byte) 1);
assertTrue(pageCursor.checkAndClearBoundsFlag());
assertFalse(pageCursor.checkAndClearBoundsFlag());
}
use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class BaseHighLimitRecordFormat method write.
@Override
public void write(RECORD record, PageCursor primaryCursor, int recordSize) throws IOException {
if (record.inUse()) {
// Let the specific implementation provide the additional header bits and we'll provide the core format bits.
byte headerByte = headerBits(record);
assert (headerByte & 0x7) == 0 : "Format-specific header bits (" + headerByte + ") collides with format-generic header bits";
headerByte = set(headerByte, IN_USE_BIT, record.inUse());
headerByte = set(headerByte, HEADER_BIT_RECORD_UNIT, record.requiresSecondaryUnit());
if (record.requiresSecondaryUnit()) {
headerByte = set(headerByte, HEADER_BIT_FIRST_RECORD_UNIT, true);
} else {
headerByte = set(headerByte, HEADER_BIT_FIXED_REFERENCE, !record.isUseFixedReferences());
}
primaryCursor.putByte(headerByte);
if (record.requiresSecondaryUnit()) {
// Write using the normal adapter since the first reference we write cannot really overflow
// into the secondary record
long secondaryUnitId = record.getSecondaryUnitId();
long pageId = pageIdForRecord(secondaryUnitId, primaryCursor.getCurrentPageSize(), recordSize);
int offset = offsetForId(secondaryUnitId, primaryCursor.getCurrentPageSize(), recordSize);
PageCursor secondaryCursor = primaryCursor.openLinkedCursor(pageId);
if (!secondaryCursor.next()) {
// We are not allowed to write this much data to the file, apparently.
record.clear();
return;
}
secondaryCursor.setOffset(offset);
secondaryCursor.putByte((byte) (IN_USE_BIT | HEADER_BIT_RECORD_UNIT));
int recordSizeWithoutHeader = recordSize - HEADER_BYTE;
PageCursor composite = CompositePageCursor.compose(primaryCursor, recordSizeWithoutHeader, secondaryCursor, recordSizeWithoutHeader);
Reference.encode(secondaryUnitId, composite);
doWriteInternal(record, composite);
} else {
doWriteInternal(record, primaryCursor);
}
} else {
markAsUnused(primaryCursor, record, recordSize);
}
}
use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class BaseHighLimitRecordFormat method read.
public void read(RECORD record, PageCursor primaryCursor, RecordLoad mode, int recordSize) throws IOException {
int primaryStartOffset = primaryCursor.getOffset();
byte headerByte = primaryCursor.getByte();
boolean inUse = isInUse(headerByte);
boolean doubleRecordUnit = has(headerByte, HEADER_BIT_RECORD_UNIT);
record.setUseFixedReferences(false);
if (doubleRecordUnit) {
boolean firstRecordUnit = has(headerByte, HEADER_BIT_FIRST_RECORD_UNIT);
if (!firstRecordUnit) {
// This is a record unit and not even the first one, so you cannot go here directly and read it,
// it may only be read as part of reading the primary unit.
record.clear();
// Return and try again
primaryCursor.setCursorException("Expected record to be the first unit in the chain, but record header says it's not");
return;
}
// This is a record that is split into multiple record units. We need a bit more clever
// data structures here. For the time being this means instantiating one object,
// but the trade-off is a great reduction in complexity.
long secondaryId = Reference.decode(primaryCursor);
long pageId = pageIdForRecord(secondaryId, primaryCursor.getCurrentPageSize(), recordSize);
int offset = offsetForId(secondaryId, primaryCursor.getCurrentPageSize(), recordSize);
PageCursor secondaryCursor = primaryCursor.openLinkedCursor(pageId);
if ((!secondaryCursor.next()) | offset < 0) {
// We must have made an inconsistent read of the secondary record unit reference.
// No point in trying to read this.
record.clear();
primaryCursor.setCursorException(illegalSecondaryReferenceMessage(pageId));
return;
}
secondaryCursor.setOffset(offset + HEADER_BYTE);
int primarySize = recordSize - (primaryCursor.getOffset() - primaryStartOffset);
// We *could* sanity check the secondary record header byte here, but we won't. If it is wrong, then we most
// likely did an inconsistent read, in which case we'll just retry. Otherwise, if the header byte is wrong,
// then there is little we can do about it here, since we are not allowed to throw exceptions.
int secondarySize = recordSize - HEADER_BYTE;
PageCursor composite = CompositePageCursor.compose(primaryCursor, primarySize, secondaryCursor, secondarySize);
doReadInternal(record, composite, recordSize, headerByte, inUse);
record.setSecondaryUnitId(secondaryId);
} else {
record.setUseFixedReferences(isUseFixedReferences(headerByte));
doReadInternal(record, primaryCursor, recordSize, headerByte, inUse);
}
}
Aggregations