use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class MuninnPageCacheTest method mustUnblockPageFaultersWhenEvictionGetsException.
@Test(timeout = SEMI_LONG_TIMEOUT_MILLIS)
public void mustUnblockPageFaultersWhenEvictionGetsException() throws Exception {
writeInitialDataTo(file("a"));
FileSystemAbstraction fs = new DelegatingFileSystemAbstraction(this.fs) {
@Override
public StoreChannel open(File fileName, String mode) throws IOException {
return new DelegatingStoreChannel(super.open(fileName, mode)) {
@Override
public void writeAll(ByteBuffer src, long position) throws IOException {
throw new IOException("uh-oh...");
}
};
}
};
MuninnPageCache pageCache = createPageCache(fs, 2, 8, PageCacheTracer.NULL, DefaultPageCursorTracerSupplier.INSTANCE);
final PagedFile pagedFile = pageCache.map(file("a"), 8);
// all writes.
try (PageCursor cursor = pagedFile.io(0, PF_SHARED_WRITE_LOCK)) {
for (int i = 0; i < 1000; i++) {
assertTrue(cursor.next());
}
fail("Expected an exception at this point");
} catch (IOException ignore) {
// Good.
}
}
use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class CommonAbstractStore method extractHeaderRecord.
private void extractHeaderRecord(PagedFile pagedFile) throws IOException {
if (getNumberOfReservedLowIds() > 0) {
try (PageCursor pageCursor = pagedFile.io(0, PF_SHARED_READ_LOCK)) {
if (pageCursor.next()) {
do {
pageCursor.setOffset(0);
readHeaderAndInitializeRecordFormat(pageCursor);
} while (pageCursor.shouldRetry());
if (pageCursor.checkAndClearBoundsFlag()) {
throw new UnderlyingStorageException("Out of page bounds when reading header; page size too small: " + pageCache.pageSize() + " bytes.");
}
} else {
throw new StoreNotFoundException("Fail to read header record of store file: " + storageFileName);
}
}
} else {
readHeaderAndInitializeRecordFormat(null);
}
recordSize = determineRecordSize();
}
use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class CommonAbstractStore method getRawRecordData.
public byte[] getRawRecordData(long id) throws IOException {
byte[] data = new byte[recordSize];
long pageId = pageIdForRecord(id);
int offset = offsetForId(id);
try (PageCursor cursor = storeFile.io(pageId, PagedFile.PF_SHARED_READ_LOCK)) {
if (cursor.next()) {
do {
cursor.setOffset(offset);
cursor.getBytes(data);
} while (cursor.shouldRetry());
checkForDecodingErrors(cursor, id, CHECK);
}
}
return data;
}
use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class CommonAbstractStore method rebuildIdGenerator.
/**
* Should rebuild the id generator from scratch.
* <p>
* Note: This method may be called both while the store has the store file mapped in the
* page cache, and while the store file is not mapped. Implementers must therefore
* map their own temporary PagedFile for the store file, and do their file IO through that,
* if they need to access the data in the store file.
*/
final void rebuildIdGenerator() {
int blockSize = getRecordSize();
if (blockSize <= 0) {
throw new InvalidRecordException("Illegal blockSize: " + blockSize);
}
log.info("Rebuilding id generator for[" + getStorageFileName() + "] ...");
closeIdGenerator();
createIdGenerator(getIdFileName());
openIdGenerator();
long defraggedCount = 0;
boolean fastRebuild = isOnlyFastIdGeneratorRebuildEnabled(configuration);
try {
long foundHighId = scanForHighId();
setHighId(foundHighId);
if (!fastRebuild) {
try (PageCursor cursor = storeFile.io(0, PF_SHARED_WRITE_LOCK | PF_READ_AHEAD)) {
defraggedCount = rebuildIdGeneratorSlow(cursor, getRecordsPerPage(), blockSize, foundHighId);
}
}
} catch (IOException e) {
throw new UnderlyingStorageException("Unable to rebuild id generator " + getStorageFileName(), e);
}
log.info("[" + getStorageFileName() + "] high id=" + getHighId() + " (defragged=" + defraggedCount + ")");
log.info(getStorageFileName() + " rebuild id generator, highId=" + getHighId() + " defragged count=" + defraggedCount);
if (!fastRebuild) {
closeIdGenerator();
openIdGenerator();
}
}
use of org.neo4j.io.pagecache.PageCursor in project neo4j by neo4j.
the class MetaDataStore method setRecord.
/**
* Writes a record in a neostore file.
* This method only works for neostore files of the current version.
*
* @param pageCache {@link PageCache} the {@code neostore} file lives in.
* @param neoStore {@link File} pointing to the neostore.
* @param position record {@link Position}.
* @param value value to write in that record.
* @return the previous value before writing.
* @throws IOException if any I/O related error occurs.
*/
public static long setRecord(PageCache pageCache, File neoStore, Position position, long value) throws IOException {
long previousValue = FIELD_NOT_INITIALIZED;
int pageSize = getPageSize(pageCache);
try (PagedFile pagedFile = pageCache.map(neoStore, pageSize)) {
int offset = offset(position);
try (PageCursor cursor = pagedFile.io(0, PagedFile.PF_SHARED_WRITE_LOCK)) {
if (cursor.next()) {
// We're overwriting a record, get the previous value
cursor.setOffset(offset);
byte inUse = cursor.getByte();
long record = cursor.getLong();
if (inUse == Record.IN_USE.byteValue()) {
previousValue = record;
}
// Write the value
cursor.setOffset(offset);
cursor.putByte(Record.IN_USE.byteValue());
cursor.putLong(value);
if (cursor.checkAndClearBoundsFlag()) {
MetaDataRecord neoStoreRecord = new MetaDataRecord();
neoStoreRecord.setId(position.id);
throw new UnderlyingStorageException(buildOutOfBoundsExceptionMessage(neoStoreRecord, 0, offset, RECORD_SIZE, pageSize, neoStore.getAbsolutePath()));
}
}
}
}
return previousValue;
}
Aggregations