Search in sources :

Example 56 with RecordCoreException

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;
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) KeyExpression(com.apple.foundationdb.record.metadata.expressions.KeyExpression) List(java.util.List) IOException(java.io.IOException) Map(java.util.Map) Tuple(com.apple.foundationdb.tuple.Tuple) HashSet(java.util.HashSet) Nonnull(javax.annotation.Nonnull)

Example 57 with RecordCoreException

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());
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) FileChannel(java.nio.channels.FileChannel) FileInputStream(java.io.FileInputStream) CodedInputStream(com.google.protobuf.CodedInputStream) InputStream(java.io.InputStream)

Example 58 with RecordCoreException

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();
    });
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) Nonnull(javax.annotation.Nonnull)

Example 59 with RecordCoreException

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);
    }
}
Also used : RecordCoreException(com.apple.foundationdb.record.RecordCoreException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) Nullable(javax.annotation.Nullable) Nonnull(javax.annotation.Nonnull)

Example 60 with RecordCoreException

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;
        });
    }
}
Also used : Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) RecordMetaData(com.apple.foundationdb.record.RecordMetaData) BeforeEach(org.junit.jupiter.api.BeforeEach) FDBDatabaseTest.testStoreAndRetrieveSimpleRecord(com.apple.foundationdb.record.provider.foundationdb.FDBDatabaseTest.testStoreAndRetrieveSimpleRecord) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CompletableFuture(java.util.concurrent.CompletableFuture) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) AtomicReference(java.util.concurrent.atomic.AtomicReference) Tuple(com.apple.foundationdb.tuple.Tuple) Vector(java.util.Vector) RecordCoreRetriableTransactionException(com.apple.foundationdb.record.RecordCoreRetriableTransactionException) ImmutableList(com.google.common.collect.ImmutableList) FDBError(com.apple.foundationdb.FDBError) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) Tag(org.junit.jupiter.api.Tag) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) ThreadContext(org.apache.logging.log4j.ThreadContext) TestRecords1Proto(com.apple.foundationdb.record.TestRecords1Proto) ImmutableMap(com.google.common.collect.ImmutableMap) Executor(java.util.concurrent.Executor) Tags(com.apple.test.Tags) CompletionException(java.util.concurrent.CompletionException) UUID(java.util.UUID) Test(org.junit.jupiter.api.Test) Consumer(java.util.function.Consumer) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) List(java.util.List) FDBException(com.apple.foundationdb.FDBException) ForkJoinPool(java.util.concurrent.ForkJoinPool) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Message(com.google.protobuf.Message) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) RecordCoreException(com.apple.foundationdb.record.RecordCoreException) FDBException(com.apple.foundationdb.FDBException) Test(org.junit.jupiter.api.Test)

Aggregations

RecordCoreException (com.apple.foundationdb.record.RecordCoreException)121 Nonnull (javax.annotation.Nonnull)58 Test (org.junit.jupiter.api.Test)42 Index (com.apple.foundationdb.record.metadata.Index)37 List (java.util.List)35 Nullable (javax.annotation.Nullable)31 Tuple (com.apple.foundationdb.tuple.Tuple)29 ArrayList (java.util.ArrayList)27 KeyExpression (com.apple.foundationdb.record.metadata.expressions.KeyExpression)26 CompletableFuture (java.util.concurrent.CompletableFuture)25 Collectors (java.util.stream.Collectors)24 Collections (java.util.Collections)22 GroupingKeyExpression (com.apple.foundationdb.record.metadata.expressions.GroupingKeyExpression)19 Set (java.util.Set)19 Function (java.util.function.Function)19 IndexEntry (com.apple.foundationdb.record.IndexEntry)17 TupleRange (com.apple.foundationdb.record.TupleRange)17 IndexTypes (com.apple.foundationdb.record.metadata.IndexTypes)17 RecordCursor (com.apple.foundationdb.record.RecordCursor)16 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)15