use of com.apple.foundationdb.record.RecordCoreException in project fdb-record-layer by FoundationDB.
the class LuceneIndexMaintainer method update.
@Nonnull
@Override
public <M extends Message> CompletableFuture<Void> update(@Nullable FDBIndexableRecord<M> oldRecord, @Nullable FDBIndexableRecord<M> newRecord) {
LOG.trace("update oldRecord={}, newRecord={}", oldRecord, newRecord);
// Extract information for grouping from old and new records
final KeyExpression root = state.index.getRootExpression();
final Map<Tuple, List<LuceneDocumentFromRecord.DocumentField>> oldRecordFields = LuceneDocumentFromRecord.getRecordFields(root, oldRecord);
final Map<Tuple, List<LuceneDocumentFromRecord.DocumentField>> newRecordFields = LuceneDocumentFromRecord.getRecordFields(root, newRecord);
final Set<Tuple> unchanged = new HashSet<>();
for (Map.Entry<Tuple, List<LuceneDocumentFromRecord.DocumentField>> entry : oldRecordFields.entrySet()) {
if (entry.getValue().equals(newRecordFields.get(entry.getKey()))) {
unchanged.add(entry.getKey());
}
}
for (Tuple t : unchanged) {
newRecordFields.remove(t);
oldRecordFields.remove(t);
}
LOG.trace("update oldFields={}, newFields{}", oldRecordFields, newRecordFields);
// delete old
try {
for (Tuple t : oldRecordFields.keySet()) {
deleteDocument(t, oldRecord.getPrimaryKey().pack());
}
} catch (IOException e) {
throw new RecordCoreException("Issue deleting old index keys", "oldRecord", oldRecord, e);
}
// There's actually no possibility of a NPE here. (line 304/306)
if (newRecord == null) {
return AsyncUtil.DONE;
}
// update new
try {
for (Map.Entry<Tuple, List<LuceneDocumentFromRecord.DocumentField>> entry : newRecordFields.entrySet()) {
writeDocument(entry.getValue(), entry.getKey(), newRecord.getPrimaryKey().pack());
}
} catch (IOException e) {
throw new RecordCoreException("Issue updating new index keys", e).addLogInfo("newRecord", newRecord);
}
return AsyncUtil.DONE;
}
use of com.apple.foundationdb.record.RecordCoreException in project fdb-record-layer by FoundationDB.
the class SortedFileReader method skipLimit.
private void skipLimit(int skip, int limit) throws IOException, GeneralSecurityException {
final RecordSortingProto.SortFileHeader.Builder fileHeader = RecordSortingProto.SortFileHeader.newBuilder();
headerStream.readMessage(fileHeader, ExtensionRegistryLite.getEmptyRegistry());
if (fileHeader.getVersion() != FileSorter.SORT_FILE_VERSION) {
throw new RecordCoreException("file header version mismatch");
}
if (fileHeader.getMetaDataVersion() != adapter.getMetaDataVersion()) {
throw new RecordCoreException("file meta-data version mismatch");
}
sectionFileStart = headerStream.getTotalBytesRead();
headerStream.resetSizeCounter();
// As though end of previous one.
sectionFileEnd = sectionFileStart;
if (skip > 0) {
final FileChannel fileChannel = fileStream.getChannel();
if (skip >= fileHeader.getNumberOfRecords()) {
// We don't need to try to skip when there aren't enough records.
fileChannel.position(fileChannel.size());
recordPosition = fileRecordEnd = fileHeader.getNumberOfRecords();
return;
}
while (true) {
// Skip whole sections until skip position within one.
final long startTime = System.nanoTime();
final RecordSortingProto.SortSectionHeader.Builder sectionHeader = RecordSortingProto.SortSectionHeader.newBuilder();
headerStream.readMessage(sectionHeader, ExtensionRegistryLite.getEmptyRegistry());
sectionRecordStart = sectionHeader.getStartRecordNumber();
sectionRecordEnd = sectionRecordStart + sectionHeader.getNumberOfRecords();
long sectionRecordsPosition = sectionFileStart + headerStream.getTotalBytesRead();
sectionFileEnd = sectionRecordsPosition + sectionHeader.getNumberOfBytes();
if (sectionRecordEnd > skip) {
recordPosition = sectionHeader.getStartRecordNumber();
recordSectionPosition = 0;
if (compressed || encryptionKey != null) {
if (cipher != null) {
FileSorter.initCipherDecrypt(cipher, encryptionKey, sectionHeader);
}
fileChannel.position(sectionFileStart + headerStream.getTotalBytesRead());
InputStream inputStream = FileSorter.wrapInputStream(fileStream, cipher, compressed);
entryStream = CodedInputStream.newInstance(inputStream);
} else {
entryStream = headerStream;
}
break;
}
sectionFileStart = sectionFileEnd;
fileChannel.position(sectionFileStart);
// We can't reuse coded streams as we skip around as they have a buffer.
// Moreover there isn't a public way to make their 4K buffer smaller.
headerStream = CodedInputStream.newInstance(fileStream);
if (timer != null) {
timer.recordSinceNanoTime(SortEvents.Events.FILE_SORT_SKIP_SECTION, startTime);
}
}
while (recordPosition < skip) {
// Skip initial keys and values in this section.
final long startTime = System.nanoTime();
entryStream.skipRawBytes(entryStream.readRawVarint32());
entryStream.skipRawBytes(entryStream.readRawVarint32());
recordPosition++;
recordSectionPosition++;
if (timer != null) {
timer.recordSinceNanoTime(SortEvents.Events.FILE_SORT_SKIP_RECORD, startTime);
}
}
limit += skip;
}
fileRecordEnd = Math.min(limit, fileHeader.getNumberOfRecords());
}
use of com.apple.foundationdb.record.RecordCoreException in project fdb-record-layer by FoundationDB.
the class FileSortCursor method onNext.
@Nonnull
@Override
public CompletableFuture<RecordCursorResult<V>> onNext() {
if (inMemoryIterator != null) {
return CompletableFuture.completedFuture(nextFromIterator());
}
if (fileReader != null) {
return CompletableFuture.completedFuture(nextFromReader());
}
return sorter.load(inputCursor).thenApply(loadResult -> {
inputContinuation = loadResult.getSourceContinuation();
if (loadResult.getSourceNoNextReason().isOutOfBand()) {
// The input cursor did not complete; we must save the sorter state in the continuation so can pick up after.
Collection<V> inMemoryRecords = sorter.getMapSorter().getMap().values();
FileSortCursorContinuation<K, V> continuation = new FileSortCursorContinuation<>(adapter, false, true, inMemoryRecords, sorter.getFiles(), inputContinuation, 0, 0);
return RecordCursorResult.withoutNextValue(continuation, loadResult.getSourceNoNextReason());
}
// Loaded all the records into the sorter, start returning them.
if (loadResult.isInMemory()) {
inMemoryIterator = sorter.getMapSorter().getMap().entrySet().iterator();
for (int i = 0; i < skip; i++) {
if (!inMemoryIterator.hasNext()) {
break;
}
inMemoryIterator.next();
}
return nextFromIterator();
}
if (sorter.getFiles().size() != 1) {
throw new RecordCoreException("sort loading did not produce exactly one file");
}
try {
fileReader = new SortedFileReader<>(sorter.getFiles().get(0), adapter, timer, skip, limit);
} catch (IOException | GeneralSecurityException ex) {
throw new RecordCoreException(ex);
}
return nextFromReader();
});
}
use of com.apple.foundationdb.record.RecordCoreException in project fdb-record-layer by FoundationDB.
the class FileSortCursor method nextFromReader.
@Nonnull
private RecordCursorResult<V> nextFromReader() {
@Nullable V record;
try {
record = fileReader.read();
} catch (IOException | GeneralSecurityException ex) {
throw new RecordCoreException(ex);
}
FileSortCursorContinuation<K, V> continuation = new FileSortCursorContinuation<>(adapter, record == null, false, Collections.emptyList(), sorter.getFiles(), inputContinuation, fileReader.getRecordPosition(), fileReader.getFilePosition());
if (record != null) {
return RecordCursorResult.withNextValue(record, continuation);
} else {
return RecordCursorResult.withoutNextValue(continuation, NoNextReason.SOURCE_EXHAUSTED);
}
}
use of com.apple.foundationdb.record.RecordCoreException in project fdb-record-layer by FoundationDB.
the class FDBDatabaseRunnerTest method runAsyncNonRetriableException.
@Test
public void runAsyncNonRetriableException() {
try (FDBDatabaseRunner runner = database.newRunner()) {
runner.runAsync(context -> {
throw new RecordCoreException("Encountered an I/O error", new FDBException("io_error", 1510));
}).handle((ignore, e) -> {
assertNotNull(e);
assertTrue(e instanceof RecordCoreException);
assertEquals("Encountered an I/O error", e.getMessage());
assertNotNull(e.getCause());
assertTrue(e.getCause() instanceof FDBException);
assertEquals("io_error", e.getCause().getMessage());
assertEquals(FDBError.IO_ERROR.code(), ((FDBException) e.getCause()).getCode());
return null;
}).join();
}
try (FDBDatabaseRunner runner = database.newRunner()) {
runner.runAsync(context -> {
throw new RecordCoreException("Internal error");
}).handle((ignore, e) -> {
assertNotNull(e);
assertTrue(e instanceof RecordCoreException);
assertEquals("Internal error", e.getMessage());
assertNull(e.getCause());
return null;
});
}
}
Aggregations