use of com.apple.foundationdb.record.RecordCoreArgumentException in project fdb-record-layer by FoundationDB.
the class VersionIndexTest method assertMaxVersionsForGroups.
private void assertMaxVersionsForGroups(@Nonnull Object... keyValue) {
if (keyValue.length % 2 != 0) {
throw new RecordCoreArgumentException("expected an even number of keys and values for grouping");
}
TreeMap<Integer, FDBRecordVersion> groupsToVersions = new TreeMap<>();
for (int i = 0; i < keyValue.length; i += 2) {
Integer group = (Integer) keyValue[i];
FDBRecordVersion version = (FDBRecordVersion) keyValue[i + 1];
groupsToVersions.put(group, version);
}
assertMaxVersionsForGroups(groupsToVersions);
}
use of com.apple.foundationdb.record.RecordCoreArgumentException in project fdb-record-layer by FoundationDB.
the class LuceneIndexMaintainer method scan.
/**
* The scan uses the low element in the range to execute the
* MultiFieldQueryParser.
*
* @param scanType the {@link IndexScanType type} of scan to perform
* @param range the range to scan
* @param continuation any continuation from a previous scan invocation
* @param scanProperties skip, limit and other properties of the scan
* @return RecordCursor
*/
@Nonnull
@Override
public RecordCursor<IndexEntry> scan(@Nonnull IndexScanType scanType, @Nonnull TupleRange range, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties) {
LOG.trace("scan scanType={}", scanType);
Verify.verify(range.getLow() != null);
Verify.verify(scanType == IndexScanType.BY_LUCENE || scanType == IndexScanType.BY_LUCENE_FULL_TEXT || scanType == IndexScanType.BY_LUCENE_AUTO_COMPLETE || scanType == IndexScanType.BY_LUCENE_SPELLCHECK);
if (scanType == IndexScanType.BY_LUCENE_AUTO_COMPLETE) {
if (!autoCompleteEnabled) {
throw new RecordCoreArgumentException("Auto-complete unsupported due to not enabled on index").addLogInfo(LogMessageKeys.INDEX_NAME, state.index.getName());
}
if (continuation != null) {
throw new RecordCoreArgumentException("Auto complete does not support scanning with continuation").addLogInfo(LogMessageKeys.INDEX_NAME, state.index.getName());
}
return new LuceneAutoCompleteResultCursor(getSuggester(Tuple.fromStream(range.getLow().stream().skip(1))), range.getLow().getString(0), executor, scanProperties, state, highlightForAutoCompleteIfEnabled);
}
String[] fieldNames = indexTextFields(state.index, state.store.getRecordMetaData());
if (scanType.equals(IndexScanType.BY_LUCENE_SPELLCHECK)) {
if (continuation != null) {
throw new RecordCoreArgumentException("Spellcheck does not currently support continuation scanning");
}
return new LuceneSpellcheckRecordCursor(range.getLow().getString(0), executor, scanProperties, state, Tuple.fromStream(range.getLow().stream().skip(1)), fieldNames);
}
try {
// This cannot work with nested documents the way that we currently use them. BlockJoin will be essential for this
// functionality in this way.
QueryParser parser;
if (scanType == IndexScanType.BY_LUCENE_FULL_TEXT) {
parser = new MultiFieldQueryParser(fieldNames, queryAnalyzer);
parser.setDefaultOperator(QueryParser.Operator.OR);
} else {
// initialize default to scan primary key.
parser = new QueryParser(PRIMARY_KEY_SEARCH_NAME, queryAnalyzer);
}
Query query = parser.parse(range.getLow().getString(0));
return new LuceneRecordCursor(executor, state.context.getPropertyStorage().getPropertyValue(LuceneRecordContextProperties.LUCENE_EXECUTOR_SERVICE), scanProperties, state, query, continuation, state.index.getRootExpression().normalizeKeyForPositions(), Tuple.fromStream(range.getLow().stream().skip(1)));
} catch (Exception ioe) {
throw new RecordCoreArgumentException("Unable to parse range given for query", "range", range, "internalException", ioe);
}
}
use of com.apple.foundationdb.record.RecordCoreArgumentException in project fdb-record-layer by FoundationDB.
the class FDBDirectory method rename.
/**
* It is the caller's responsibility to make the dest (destination) does not exist.
*
* @param source source
* @param dest desc
*/
@Override
public void rename(@Nonnull final String source, @Nonnull final String dest) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(getLogMessage("rename", LogMessageKeys.SOURCE_FILE, source, LogMessageKeys.DEST_FILE, dest));
}
final byte[] key = metaSubspace.pack(source);
context.asyncToSync(FDBStoreTimer.Waits.WAIT_LUCENE_RENAME, context.ensureActive().get(key).thenApply((Function<byte[], Void>) value -> {
if (value == null) {
throw new RecordCoreArgumentException("Invalid source name in rename function for source").addLogInfo(LogMessageKeys.SOURCE_FILE, source).addLogInfo(LogMessageKeys.INDEX_TYPE, IndexTypes.LUCENE).addLogInfo(LogMessageKeys.SUBSPACE, subspace).addLogInfo(LogMessageKeys.COMPRESSION_SUPPOSED, compressionEnabled).addLogInfo(LogMessageKeys.ENCRYPTION_SUPPOSED, encryptionEnabled);
}
fileReferenceCache.invalidate(source);
context.ensureActive().set(metaSubspace.pack(dest), value);
context.ensureActive().clear(key);
return null;
}));
}
use of com.apple.foundationdb.record.RecordCoreArgumentException in project fdb-record-layer by FoundationDB.
the class GeophileBoxLatLon method newBox.
/**
* Get a box with possible wraparound.
* @param latLo low latitude value
* @param latHi high latitude value
* @param lonLo low longitude value
* @param lonHi high longitude value
* @return a new box representing the area between the given boundaries
*/
public static SpatialObject newBox(double latLo, double latHi, double lonLo, double lonHi) {
latLo = fixLat(latLo);
latHi = fixLat(latHi);
lonLo = fixLon(lonLo);
lonHi = fixLon(lonHi);
try {
return lonLo <= lonHi ? new Box(latLo, latHi, lonLo, lonHi) : new GeophileBoxLatLonWithWraparound(latLo, latHi, lonLo, lonHi);
} catch (IllegalArgumentException ex) {
throw new RecordCoreArgumentException(String.format("cannot make box: latLo = %s, latHi = %s, lonLo = %s, lonHi = %s", latLo, latHi, lonLo, lonHi), ex);
}
}
use of com.apple.foundationdb.record.RecordCoreArgumentException in project fdb-record-layer by FoundationDB.
the class FDBRecordStore method repairRecordKeys.
/**
* Validate and repair known potential issues with record keys. Currently, this method is capable of identifying
* and repairing the following scenarios:
* <ul>
* <li>For record stores in which record splitting is disabled but the {@code omitUnsplitRecordSuffix} flag
* is {@code true}, keys found missing the {@link SplitHelper#UNSPLIT_RECORD} suffix will be repaired.</li>
* <li>For record stores in which record splitting is disabled, but the record key suffix is found to be
* a value other than {@link SplitHelper#UNSPLIT_RECORD}, the {@link FDBStoreTimer.Counts#INVALID_SPLIT_SUFFIX}
* counter will be incremented.
* <li>For record stores in which record splitting is disabled, but the record key is longer than expected,
* the {@link FDBStoreTimer.Counts#INVALID_KEY_LENGTH} counter will be incremented.
* </ul>
*
* @param continuation continuation from a previous repair attempt or {@code null} to start from the beginning
* @param scanProperties properties to provide scan limits on the repair process
* record keys should be logged
* @param isDryRun if true, no repairs are made, however counters involving irregular keys or keys that would
* would have been repaired are incremented
* @return a future that completes to a continuation or {@code null} if the repair has been completed
*/
@Nonnull
public CompletableFuture<byte[]> repairRecordKeys(@Nullable byte[] continuation, @Nonnull ScanProperties scanProperties, final boolean isDryRun) {
// If the records aren't split to begin with, then there is nothing to do.
if (getRecordMetaData().isSplitLongRecords()) {
return CompletableFuture.completedFuture(null);
}
if (scanProperties.getExecuteProperties().getIsolationLevel().isSnapshot()) {
throw new RecordCoreArgumentException("Cannot repair record key split markers at SNAPSHOT isolation level").addLogInfo(LogMessageKeys.SCAN_PROPERTIES, scanProperties).addLogInfo(subspaceProvider.logKey(), subspaceProvider.toString(context));
}
final Subspace recordSubspace = recordsSubspace();
KeyValueCursor cursor = KeyValueCursor.Builder.withSubspace(recordSubspace).setContext(getRecordContext()).setContinuation(continuation).setScanProperties(scanProperties).build();
final AtomicReference<byte[]> nextContinuation = new AtomicReference<>();
final FDBRecordContext context = getContext();
return AsyncUtil.whileTrue(() -> cursor.onNext().thenApply(result -> {
if (!result.hasNext()) {
if (result.hasStoppedBeforeEnd()) {
nextContinuation.set(result.getContinuation().toBytes());
}
return false;
}
repairRecordKeyIfNecessary(context, recordSubspace, result.get(), isDryRun);
return true;
})).thenApply(ignored -> nextContinuation.get());
}
Aggregations