Class FDBRecordStore
- java.lang.Object
-
- com.apple.foundationdb.record.provider.foundationdb.FDBStoreBase
-
- com.apple.foundationdb.record.provider.foundationdb.FDBRecordStore
-
- All Implemented Interfaces:
FDBRecordStoreBase<Message>
,RecordMetaDataProvider
@API(STABLE) public class FDBRecordStore extends FDBStoreBase implements FDBRecordStoreBase<Message>
A multi-type record store. By default, this uses Protobuf dynamic messages to process records. However, one can specify a customRecordSerializer
such as aMessageBuilderRecordSerializer
or aTransformedRecordSerializer
to use as an alternative. Unlike the serializers used by anFDBTypedRecordStore
which only need to be able to process records of the appropriate record type, the provided serializer must be able to serialize and deseralize all record types specified by the record store'sRecordMetaData
.Warning: It is unsafe to create and use two
FDBRecordStore
s concurrently over the sameSubspace
within the context of a single transaction, i.e., with the sameFDBRecordContext
. This is because theFDBRecordStore
object maintains state about certain uncommitted operations, and concurrent access through two objects will not see changes to this in-memory state. See Issue #489 for more details. Note also that the record stores returned byFDBRecordStoreBase.getTypedRecordStore(RecordSerializer)
andgetUntypedRecordStore()
will share anFDBRecordStore
with the record store on which they are called, so it is safe to have a typed- and untyped-record store open over the sameSubspace
within the context of the same transaction if one uses one of those methods.- See Also:
FDBRecordStoreBase
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
FDBRecordStore.Builder
A builder forFDBRecordStore
.static class
FDBRecordStore.IndexNotBuiltException
Exception that can be thrown if one attempts to mark an index as readable if it is not yet readable.static class
FDBRecordStore.RebuildIndexReason
Reason that an index is being rebuilt now.-
Nested classes/interfaces inherited from interface com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase
FDBRecordStoreBase.BaseBuilder<M extends Message,R extends FDBRecordStoreBase<M>>, FDBRecordStoreBase.PipelineSizer, FDBRecordStoreBase.RecordExistenceCheck, FDBRecordStoreBase.StoreExistenceCheck, FDBRecordStoreBase.UserVersionChecker, FDBRecordStoreBase.VersionstampSaveBehavior
-
-
Field Summary
-
Fields inherited from class com.apple.foundationdb.record.provider.foundationdb.FDBStoreBase
context, subspaceProvider
-
-
Constructor Summary
Constructors Modifier Constructor Description protected
FDBRecordStore(FDBRecordContext context, SubspaceProvider subspaceProvider, int formatVersion, RecordMetaDataProvider metaDataProvider, RecordSerializer<Message> serializer, IndexMaintainerRegistry indexMaintainerRegistry, IndexMaintenanceFilter indexMaintenanceFilter, FDBRecordStoreBase.PipelineSizer pipelineSizer, FDBRecordStoreStateCache storeStateCache)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods Modifier and Type Method Description void
addRebuildRecordCountsJob(List<CompletableFuture<Void>> work)
void
addRecordReadConflict(Tuple primaryKey)
Add a read conflict as if one had read the record with the given primary key.void
addRecordWriteConflict(Tuple primaryKey)
Add a write conflict as if one had modified the record with the given primary key.FDBRecordStore.Builder
asBuilder()
protected boolean
checkPossiblyRebuildRecordCounts(RecordMetaData metaData, RecordMetaDataProto.DataStoreInfo.Builder info, List<CompletableFuture<Void>> work, int oldFormatVersion)
static CompletableFuture<Void>
checkStoreHeader(RecordMetaDataProto.DataStoreInfo storeHeader, FDBRecordContext context, SubspaceProvider subspaceProvider, Subspace subspace, FDBRecordStoreBase.StoreExistenceCheck existenceCheck)
CompletableFuture<Boolean>
checkVersion(FDBRecordStoreBase.UserVersionChecker userVersionChecker, FDBRecordStoreBase.StoreExistenceCheck existenceCheck)
Checks the meta-data version key of the record store and compares it to the version of the local meta-data object.CompletableFuture<Void>
clearAndMarkIndexWriteOnly(Index index)
Prepare an index for rebuilding by clearing any existing data and marking the index as write-only.CompletableFuture<Void>
clearAndMarkIndexWriteOnly(String indexName)
void
clearHeaderUserField(String userField)
Clear the value of a user-settable field in the store header.CompletableFuture<Void>
clearHeaderUserFieldAsync(String userField)
Clear the value of a user-settable field in the store header.protected void
countKeysAndValues(StoreTimer.Count key, StoreTimer.Count keyBytes, StoreTimer.Count valueBytes, FDBStoredSizes sizeInfo)
void
countKeyValue(StoreTimer.Count key, StoreTimer.Count keyBytes, StoreTimer.Count valueBytes, byte[] k, byte[] v)
void
countKeyValue(StoreTimer.Count key, StoreTimer.Count keyBytes, StoreTimer.Count valueBytes, KeyValue keyValue)
CompletableFuture<Integer>
countRecords(Tuple low, Tuple high, EndpointType lowEndpoint, EndpointType highEndpoint, byte[] continuation, ScanProperties scanProperties)
Count the number of records in the database in a range.static long
decodeRecordCount(byte[] bytes)
void
deleteAllRecords()
Delete all the data in the record store.CompletableFuture<Boolean>
deleteRecordAsync(Tuple primaryKey)
Async version ofFDBRecordStoreBase.deleteRecord(com.apple.foundationdb.tuple.Tuple)
.CompletableFuture<Void>
deleteRecordsWhereAsync(QueryComponent component)
static void
deleteStore(FDBRecordContext context, KeySpacePath path)
Delete the record store at the givenKeySpacePath
.static void
deleteStore(FDBRecordContext context, Subspace subspace)
Delete the record store at the givenSubspace
.protected <M extends Message>
CompletableFuture<Boolean>deleteTypedRecord(RecordSerializer<M> typedSerializer, Tuple primaryKey)
CompletableFuture<Tuple>
evaluateAggregateFunction(List<String> recordTypeNames, IndexAggregateFunction aggregateFunction, TupleRange range, IsolationLevel isolationLevel)
Evaluate anIndexAggregateFunction
against a range of the store.<T> CompletableFuture<T>
evaluateIndexRecordFunction(EvaluationContext evaluationContext, IndexRecordFunction<T> function, FDBRecord<Message> record)
Evaluate aIndexRecordFunction
against a record.<T> CompletableFuture<T>
evaluateStoreFunction(EvaluationContext evaluationContext, StoreRecordFunction<T> function, FDBRecord<Message> record)
Evaluate aStoreRecordFunction
against a record.protected <T,M extends Message>
CompletableFuture<T>evaluateTypedIndexRecordFunction(EvaluationContext evaluationContext, IndexRecordFunction<T> indexRecordFunction, FDBRecord<M> record)
<T,M extends Message>
CompletableFuture<T>evaluateTypedStoreFunction(EvaluationContext evaluationContext, StoreRecordFunction<T> function, FDBRecord<M> record)
CompletableFuture<Optional<Range>>
firstUnbuiltRange(Index index)
Returns the first unbuilt range of an index that is currently being bulit.Map<Index,IndexState>
getAllIndexStates()
Gets a map fromIndex
toIndexState
for all the indexes in the meta-data.FDBRecordContext
getContext()
Get the record context (transaction) to use for the record store.List<Index>
getEnabledIndexes(RecordTypeOrBuilder recordType)
Gets the list of enabled indexes that are on the given record type.List<Index>
getEnabledMultiTypeIndexes(RecordTypeOrBuilder recordType)
Gets the list of enabled indexes that are on multiple record types one of which is the given type.List<Index>
getEnabledUniversalIndexes()
Gets the list of enabled universal indexes, i.e., the indexes on all record types.int
getFormatVersion()
Get the storage format version currently in use for this record store.ByteString
getHeaderUserField(String userField)
Get the value of a user-settable field from the store header.CompletableFuture<IndexBuildState>
getIndexBuildStateAsync(Index index)
Get the progress of building the given index.IndexMaintainer
getIndexMaintainer(Index index)
Get the maintainer for a given index.IndexMaintainerRegistry
getIndexMaintainerRegistry()
IndexMaintenanceFilter
getIndexMaintenanceFilter()
IndexState
getIndexState(Index index)
Get the state of the index for this record store.IndexState
getIndexState(String indexName)
Get the state of the index with the given name for this record store.int
getKeySizeLimit()
Subspace
getLegacyVersionSubspace()
RecordMetaDataProvider
getMetaDataProvider()
Get the provider for the record store's meta-data.FDBRecordStoreBase.PipelineSizer
getPipelineSizer()
Get the function for computing the number of elements to allow in the asynchronous pipeline for an operation of the given type.RecordCursor<Tuple>
getPrimaryKeyBoundaries(Tuple low, Tuple high)
Return a cursor of boundaries separating the key ranges maintained by each FDB server.List<Index>
getReadableIndexes(RecordTypeOrBuilder recordType)
Gets the list of readable indexes that are on the given record type.List<Index>
getReadableMultiTypeIndexes(RecordTypeOrBuilder recordType)
Gets the list of readable indexes that are on multiple record types one of which is the given type.List<Index>
getReadableUniversalIndexes()
Gets the list of readable universal indexes, i.e., the indexes on all record types.protected org.apache.commons.lang3.tuple.Pair<CompletableFuture<Long>,Boolean>
getRecordCountForRebuildIndexes(boolean newStore, boolean rebuildRecordCounts, Map<Index,List<RecordType>> indexes)
Get count of records to pass to checker to decide whether to build right away.RecordMetaData
getRecordMetaData()
Get theRecordMetaData
used by this store.RecordStoreState
getRecordStoreState()
Get theRecordStoreState
for this store.RecordSerializer<Message>
getSerializer()
Get the serializer used to convert records into byte arrays.CompletableFuture<Long>
getSnapshotRecordCount(KeyExpression key, Key.Evaluated value)
Get the number of records in a portion of the record store determined by a group key expression.CompletableFuture<Long>
getSnapshotRecordCountForRecordType(String recordTypeName)
Get the number of records in the record store of the given record type.protected Map<Index,IndexState>
getStatesForRebuildIndexes(FDBRecordStoreBase.UserVersionChecker userVersionChecker, Map<Index,List<RecordType>> indexes, long recordCount, boolean newStore, boolean rebuildRecordCounts, int oldMetaDataVersion, int oldFormatVersion)
FDBRecordStore
getUntypedRecordStore()
Get the untyped record store associated with this possibly typed store.int
getUserVersion()
Get the user version currently in use for this record store.int
getValueSizeLimit()
Subspace
indexRangeSubspace(Index index)
Subspace for index in which to place aRangeSet
.Subspace
indexSecondarySubspace(Index index)
Subspace
indexStateSubspace()
Subspace
indexSubspace(Index index)
Subspace
indexSubspaceFromMaintainer(Index index)
Subspace
indexUniquenessViolationsSubspace(Index index)
Subspace for index in which to place a record in uniqueness violations.boolean
isIndexDisabled(Index index)
Determine if the index is disabled for this record store.boolean
isIndexDisabled(String indexName)
Determine if the index with the given name is disabled for this record store.boolean
isIndexReadable(Index index)
Determine if the index is readable for this record store.boolean
isIndexReadable(String indexName)
Determine if the index with the given name is readable for this record store.boolean
isIndexWriteOnly(Index index)
Determine if the index is write-only for this record store.boolean
isIndexWriteOnly(String indexName)
Determine if the index with the given name is write-only for this record store.CompletableFuture<FDBStoredRecord<Message>>
loadRecordInternal(Tuple primaryKey, ExecuteState executeState, boolean snapshot)
CompletableFuture<RecordStoreState>
loadRecordStoreStateAsync(FDBRecordStoreBase.StoreExistenceCheck existenceCheck)
Loads the current state of the record store within the given subspace asynchronously.Optional<FDBRecordVersion>
loadRecordVersion(Tuple primaryKey)
Load the version of the last time a record with the given primary key was saved.Optional<FDBRecordVersion>
loadRecordVersion(Tuple primaryKey, boolean snapshot)
Overload ofloadRecordVersion(Tuple)
that supports snapshot reads.Optional<CompletableFuture<FDBRecordVersion>>
loadRecordVersionAsync(Tuple primaryKey)
Async version ofloadRecordVersion(Tuple)
.Optional<CompletableFuture<FDBRecordVersion>>
loadRecordVersionAsync(Tuple primaryKey, boolean snapshot)
Async version ofloadRecordVersion(Tuple, boolean)
.CompletableFuture<FDBSyntheticRecord>
loadSyntheticRecord(Tuple primaryKey)
Load asynthetic record
by loading its stored constituent records and synthesizing it from them.protected <M extends Message>
CompletableFuture<FDBStoredRecord<M>>loadTypedRecord(RecordSerializer<M> typedSerializer, Tuple primaryKey, boolean snapshot)
protected <M extends Message>
CompletableFuture<FDBStoredRecord<M>>loadTypedRecord(RecordSerializer<M> typedSerializer, Tuple primaryKey, ExecuteState executeState, boolean snapshot)
CompletableFuture<Boolean>
markIndexDisabled(Index index)
Adds the index to the list of disabled indexes stored within the store.CompletableFuture<Boolean>
markIndexDisabled(String indexName)
Adds the index of the given name to the list of disabled indexes stored within the store.CompletableFuture<Boolean>
markIndexReadable(Index index)
Marks an index as readable.CompletableFuture<Boolean>
markIndexReadable(String indexName)
Marks the index with the given name as readable.CompletableFuture<Boolean>
markIndexWriteOnly(Index index)
Adds the given index to the list of write-only indexes stored within the store.CompletableFuture<Boolean>
markIndexWriteOnly(String indexName)
Adds the index of the given name to the list of write-only indexes stored within the store.protected static QueryComponent
mergeRecordTypeAndComponent(String recordType, QueryComponent component)
static FDBRecordStore.Builder
newBuilder()
IndexOperationResult
performIndexOperation(String indexName, IndexOperation operation)
CompletableFuture<IndexOperationResult>
performIndexOperationAsync(String indexName, IndexOperation operation)
RecordQueryPlan
planQuery(RecordQuery query)
Plan a query.CompletableFuture<Void>
preloadRecordAsync(Tuple primaryKey)
Get record into FDB RYW cache.protected CompletableFuture<Void>
preloadRecordStoreStateAsync()
Loads the current state of the record store asynchronously and caches it in memory so thatgetRecordStoreState()
requires no i/o.protected CompletableFuture<Void>
preloadRecordStoreStateAsync(FDBRecordStoreBase.StoreExistenceCheck existenceCheck, IsolationLevel storeHeaderIsolationLevel, IsolationLevel indexStateIsolationLevel)
Loads the current state of the record store asynchronously and setsrecordStoreStateRef
.protected CompletableFuture<Void>
preloadSubspaceAsync()
Ensure that subspace provider has cachedSubspace
so that callingFDBStoreBase.getSubspace()
will not block.CompletableFuture<Void>
rebuildAllIndexes()
Rebuild all of this store's indexes.CompletableFuture<Void>
rebuildIndex(Index index)
Rebuild an index.CompletableFuture<Void>
rebuildIndex(Index index, Collection<RecordType> recordTypes, FDBRecordStore.RebuildIndexReason reason)
protected CompletableFuture<Void>
rebuildIndexes(Map<Index,List<RecordType>> indexes, Map<Index,IndexState> newStates, List<CompletableFuture<Void>> work, FDBRecordStore.RebuildIndexReason reason, Integer oldMetaDataVersion)
protected CompletableFuture<Void>
rebuildOrMarkIndex(Index index, IndexState indexState, List<RecordType> recordTypes, FDBRecordStore.RebuildIndexReason reason, Integer oldMetaDataVersion)
CompletableFuture<Boolean>
recordExistsAsync(Tuple primaryKey, IsolationLevel isolationLevel)
Check if a record exists in the record store with the given primary key.Subspace
recordsSubspace()
void
removeFormerIndex(FormerIndex formerIndex)
CompletableFuture<byte[]>
repairRecordKeys(byte[] continuation, ScanProperties scanProperties)
CompletableFuture<byte[]>
repairRecordKeys(byte[] continuation, ScanProperties scanProperties, boolean isDryRun)
Validate and repair known potential issues with record keys.CompletableFuture<Void>
resolveUniquenessViolation(Index index, Tuple valueKey, Tuple remainPrimaryKey)
Removes all of the records that have the given value set as their index value (and are thus causing a uniqueness violation) except for the one that has the given primary key (if the key is notnull
).CompletableFuture<FDBStoredRecord<Message>>
saveRecordAsync(Message record, FDBRecordStoreBase.RecordExistenceCheck existenceCheck, FDBRecordVersion version, FDBRecordStoreBase.VersionstampSaveBehavior behavior)
protected void
saveStoreHeader(RecordMetaDataProto.DataStoreInfo storeHeader)
protected <M extends Message>
CompletableFuture<FDBStoredRecord<M>>saveTypedRecord(RecordSerializer<M> typedSerializer, M record, FDBRecordStoreBase.RecordExistenceCheck existenceCheck, FDBRecordVersion version, FDBRecordStoreBase.VersionstampSaveBehavior behavior)
RecordCursor<IndexEntry>
scanIndex(Index index, IndexScanType scanType, TupleRange range, byte[] continuation, ScanProperties scanProperties)
Scan the entries in an index.RecordCursor<FDBStoredRecord<Message>>
scanRecords(Tuple low, Tuple high, EndpointType lowEndpoint, EndpointType highEndpoint, byte[] continuation, ScanProperties scanProperties)
Scan the records in the database in a range.<M extends Message>
RecordCursor<FDBStoredRecord<M>>scanTypedRecords(RecordSerializer<M> typedSerializer, Tuple low, Tuple high, EndpointType lowEndpoint, EndpointType highEndpoint, byte[] continuation, ScanProperties scanProperties)
RecordCursor<RecordIndexUniquenessViolation>
scanUniquenessViolations(Index index, TupleRange range, byte[] continuation, ScanProperties scanProperties)
Scan the list of uniqueness violations identified for an index.void
setHeaderUserField(String userField, byte[] value)
Set the value of a user-settable field in the store header.void
setHeaderUserField(String userField, ByteString value)
Set the value of a user-settable field in the store header.CompletableFuture<Void>
setHeaderUserFieldAsync(String userField, byte[] value)
Set the value of a user-settable field in the store header.CompletableFuture<Void>
setHeaderUserFieldAsync(String userField, ByteString value)
Set the value of a user-settable field in the store header.boolean
setStateCacheability(boolean cacheable)
Set whether the store state is cacheable.CompletableFuture<Boolean>
setStateCacheabilityAsync(boolean cacheable)
Set whether the store state is cacheable.protected RecordType
singleRecordTypeWithPrefixKey(Map<Index,List<RecordType>> indexes)
CompletableFuture<Boolean>
uncheckedMarkIndexReadable(String indexName)
Marks the index with the given name as readable without checking to see if it is ready.void
validateMetaData()
Deprecated.validation is done byRecordMetaDataBuilder
static IndexState
writeOnlyIfTooManyRecordsForRebuild(long recordCount, boolean indexOnNewRecordTypes)
-
Methods inherited from class com.apple.foundationdb.record.provider.foundationdb.FDBStoreBase
addConflictForSubspace, ensureContextActive, getExecutor, getRecordContext, getSubspace, getSubspaceAsync, getSubspaceProvider, getTimer, increment, increment, instrument, instrument, instrument, record, record
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase
countRecords, coveredIndexQueriedRecord, deleteRecord, deleteRecordsWhere, deleteRecordsWhere, deleteRecordsWhereAsync, evaluateAggregateFunction, evaluateAggregateFunction, evaluateRecordFunction, evaluateRecordFunction, evaluateStoreFunction, executeQuery, executeQuery, executeQuery, executeQuery, fetchIndexRecords, fetchIndexRecords, fetchIndexRecords, fetchIndexRecords, getExecutor, getPipelineSize, getSnapshotRecordCount, getSnapshotRecordUpdateCount, getSnapshotRecordUpdateCount, getSubspaceProvider, getTimer, getTypedRecordStore, hasIndexEntryRecord, hasIndexEntryRecord, insertRecord, insertRecordAsync, loadIndexEntryRecord, loadIndexEntryRecord, loadIndexEntryRecord, loadIndexEntryRecord, loadRecord, loadRecord, loadRecordAsync, loadRecordAsync, queriedRecord, queriedRecord, recordExists, recordExists, recordExistsAsync, resolveUniquenessViolation, saveRecord, saveRecord, saveRecord, saveRecord, saveRecord, saveRecordAsync, saveRecordAsync, saveRecordAsync, saveRecordAsync, scanIndex, scanIndexRecords, scanIndexRecords, scanIndexRecords, scanIndexRecords, scanIndexRecords, scanIndexRecords, scanIndexRecordsBetween, scanIndexRecordsEqual, scanRecords, scanRecords, scanUniquenessViolations, scanUniquenessViolations, scanUniquenessViolations, scanUniquenessViolations, scanUniquenessViolations, scanUniquenessViolations, scanUniquenessViolations, updateRecord, updateRecordAsync
-
-
-
-
Field Detail
-
DEFAULT_PIPELINE_SIZE
public static final int DEFAULT_PIPELINE_SIZE
- See Also:
- Constant Field Values
-
DEFAULT_PIPELINE_SIZER
public static final FDBRecordStoreBase.PipelineSizer DEFAULT_PIPELINE_SIZER
-
MAX_RECORDS_FOR_REBUILD
public static final int MAX_RECORDS_FOR_REBUILD
- See Also:
- Constant Field Values
-
MAX_PARALLEL_INDEX_REBUILD
public static final int MAX_PARALLEL_INDEX_REBUILD
- See Also:
- Constant Field Values
-
INFO_ADDED_FORMAT_VERSION
public static final int INFO_ADDED_FORMAT_VERSION
- See Also:
- Constant Field Values
-
RECORD_COUNT_ADDED_FORMAT_VERSION
public static final int RECORD_COUNT_ADDED_FORMAT_VERSION
- See Also:
- Constant Field Values
-
RECORD_COUNT_KEY_ADDED_FORMAT_VERSION
public static final int RECORD_COUNT_KEY_ADDED_FORMAT_VERSION
- See Also:
- Constant Field Values
-
FORMAT_CONTROL_FORMAT_VERSION
public static final int FORMAT_CONTROL_FORMAT_VERSION
- See Also:
- Constant Field Values
-
SAVE_UNSPLIT_WITH_SUFFIX_FORMAT_VERSION
public static final int SAVE_UNSPLIT_WITH_SUFFIX_FORMAT_VERSION
- See Also:
- Constant Field Values
-
SAVE_VERSION_WITH_RECORD_FORMAT_VERSION
public static final int SAVE_VERSION_WITH_RECORD_FORMAT_VERSION
- See Also:
- Constant Field Values
-
CACHEABLE_STATE_FORMAT_VERSION
public static final int CACHEABLE_STATE_FORMAT_VERSION
- See Also:
- Constant Field Values
-
HEADER_USER_FIELDS_FORMAT_VERSION
public static final int HEADER_USER_FIELDS_FORMAT_VERSION
- See Also:
- Constant Field Values
-
MAX_SUPPORTED_FORMAT_VERSION
public static final int MAX_SUPPORTED_FORMAT_VERSION
- See Also:
- Constant Field Values
-
DEFAULT_FORMAT_VERSION
public static final int DEFAULT_FORMAT_VERSION
- See Also:
- Constant Field Values
-
KEY_SIZE_LIMIT
public static final int KEY_SIZE_LIMIT
- See Also:
- Constant Field Values
-
VALUE_SIZE_LIMIT
public static final int VALUE_SIZE_LIMIT
- See Also:
- Constant Field Values
-
STORE_INFO_KEY
protected static final Object STORE_INFO_KEY
-
RECORD_KEY
protected static final Object RECORD_KEY
-
INDEX_KEY
protected static final Object INDEX_KEY
-
INDEX_SECONDARY_SPACE_KEY
protected static final Object INDEX_SECONDARY_SPACE_KEY
-
RECORD_COUNT_KEY
protected static final Object RECORD_COUNT_KEY
-
INDEX_STATE_SPACE_KEY
protected static final Object INDEX_STATE_SPACE_KEY
-
INDEX_RANGE_SPACE_KEY
protected static final Object INDEX_RANGE_SPACE_KEY
-
INDEX_UNIQUENESS_VIOLATIONS_KEY
protected static final Object INDEX_UNIQUENESS_VIOLATIONS_KEY
-
RECORD_VERSION_KEY
protected static final Object RECORD_VERSION_KEY
-
INDEX_BUILD_SPACE_KEY
protected static final Object INDEX_BUILD_SPACE_KEY
-
LITTLE_ENDIAN_INT64_ONE
public static final byte[] LITTLE_ENDIAN_INT64_ONE
-
LITTLE_ENDIAN_INT64_MINUS_ONE
public static final byte[] LITTLE_ENDIAN_INT64_MINUS_ONE
-
formatVersion
protected int formatVersion
-
userVersion
protected int userVersion
-
metaDataProvider
@Nonnull protected final RecordMetaDataProvider metaDataProvider
-
recordStoreStateRef
@Nonnull protected final AtomicReference<MutableRecordStoreState> recordStoreStateRef
-
serializer
@Nonnull protected final RecordSerializer<Message> serializer
-
indexMaintainerRegistry
@Nonnull protected final IndexMaintainerRegistry indexMaintainerRegistry
-
indexMaintenanceFilter
@Nonnull protected final IndexMaintenanceFilter indexMaintenanceFilter
-
pipelineSizer
@Nonnull protected final FDBRecordStoreBase.PipelineSizer pipelineSizer
-
storeStateCache
@Nullable protected final FDBRecordStoreStateCache storeStateCache
-
-
Constructor Detail
-
FDBRecordStore
protected FDBRecordStore(@Nonnull FDBRecordContext context, @Nonnull SubspaceProvider subspaceProvider, int formatVersion, @Nonnull RecordMetaDataProvider metaDataProvider, @Nonnull RecordSerializer<Message> serializer, @Nonnull IndexMaintainerRegistry indexMaintainerRegistry, @Nonnull IndexMaintenanceFilter indexMaintenanceFilter, @Nonnull FDBRecordStoreBase.PipelineSizer pipelineSizer, @Nullable FDBRecordStoreStateCache storeStateCache)
-
-
Method Detail
-
getUntypedRecordStore
public FDBRecordStore getUntypedRecordStore()
Description copied from interface:FDBRecordStoreBase
Get the untyped record store associated with this possibly typed store.- Specified by:
getUntypedRecordStore
in interfaceFDBRecordStoreBase<Message>
- Returns:
- an untyped record store
-
getContext
@Nonnull public FDBRecordContext getContext()
Description copied from interface:FDBRecordStoreBase
Get the record context (transaction) to use for the record store.- Specified by:
getContext
in interfaceFDBRecordStoreBase<Message>
- Returns:
- context the record context / transaction to use
-
getFormatVersion
public int getFormatVersion()
Get the storage format version currently in use for this record store. After callingFDBRecordStoreBase.BaseBuilder.open()
orcheckVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.UserVersionChecker, com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.StoreExistenceCheck)
directly, this will be the format stored in the store's info header. Index maintainers can use this to determine what format to expect / produce.- Returns:
- the storage format version
-
getUserVersion
public int getUserVersion()
Get the user version currently in use for this record store. After callingFDBRecordStoreBase.BaseBuilder.open()
orcheckVersion(com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.UserVersionChecker, com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase.StoreExistenceCheck)
directly, this will be the value stored in the store's info header. This version is returned fromFDBRecordStoreBase.UserVersionChecker.checkUserVersion(int, int, com.apple.foundationdb.record.RecordMetaDataProvider)
and does not have any meaning within the Record Layer core.- Returns:
- the user format version
-
getMetaDataProvider
@Nullable public RecordMetaDataProvider getMetaDataProvider()
Get the provider for the record store's meta-data.- Returns:
- the meta-data source to use
-
getRecordMetaData
@Nonnull public RecordMetaData getRecordMetaData()
Get theRecordMetaData
used by this store.- Specified by:
getRecordMetaData
in interfaceRecordMetaDataProvider
- Returns:
- the associated meta-data
-
getRecordStoreState
@Nonnull public RecordStoreState getRecordStoreState()
Get theRecordStoreState
for this store. This represents the indexes that are disabled or in the process of being rebuilt. If the state is not already loaded, it is loaded synchronously.- Returns:
- the store state for this store
-
getSerializer
@Nonnull public RecordSerializer<Message> getSerializer()
Description copied from interface:FDBRecordStoreBase
Get the serializer used to convert records into byte arrays.- Specified by:
getSerializer
in interfaceFDBRecordStoreBase<Message>
- Returns:
- the serializer to use
-
getIndexMaintainerRegistry
@Nonnull public IndexMaintainerRegistry getIndexMaintainerRegistry()
-
getIndexMaintenanceFilter
@Nonnull public IndexMaintenanceFilter getIndexMaintenanceFilter()
-
saveRecordAsync
@Nonnull public CompletableFuture<FDBStoredRecord<Message>> saveRecordAsync(@Nonnull Message record, @Nonnull FDBRecordStoreBase.RecordExistenceCheck existenceCheck, @Nullable FDBRecordVersion version, @Nonnull FDBRecordStoreBase.VersionstampSaveBehavior behavior)
Async version ofFDBRecordStoreBase.saveRecord(Message, RecordExistenceCheck, FDBRecordVersion, VersionstampSaveBehavior)
.- Specified by:
saveRecordAsync
in interfaceFDBRecordStoreBase<Message>
- Parameters:
record
- the record to saveexistenceCheck
- when to throw an exception if a record with the same primary key does or does not already existversion
- the associated record versionbehavior
- the save behavior w.r.t. the givenversion
- Returns:
- a future that completes with the stored record form of the saved record
-
saveTypedRecord
@Nonnull @API(INTERNAL) protected <M extends Message> CompletableFuture<FDBStoredRecord<M>> saveTypedRecord(@Nonnull RecordSerializer<M> typedSerializer, @Nonnull M record, @Nonnull FDBRecordStoreBase.RecordExistenceCheck existenceCheck, @Nullable FDBRecordVersion version, @Nonnull FDBRecordStoreBase.VersionstampSaveBehavior behavior)
-
loadSyntheticRecord
@Nonnull @API(EXPERIMENTAL) public CompletableFuture<FDBSyntheticRecord> loadSyntheticRecord(@Nonnull Tuple primaryKey)
Load asynthetic record
by loading its stored constituent records and synthesizing it from them.- Parameters:
primaryKey
- the primary key of the synthetic record, which includes the primary keys of the constituents- Returns:
- a future which completes to the synthesized record
-
indexSubspaceFromMaintainer
@Nonnull public Subspace indexSubspaceFromMaintainer(@Nonnull Index index)
-
indexRangeSubspace
@Nonnull public Subspace indexRangeSubspace(@Nonnull Index index)
Subspace for index in which to place aRangeSet
. This is used for determining how much progress has been made on building the index in the case that one is building the index offline.- Parameters:
index
- the index to retrieve the range subspace for- Returns:
- the subspace for the
RangeSet
for the given index
-
indexUniquenessViolationsSubspace
@Nonnull public Subspace indexUniquenessViolationsSubspace(@Nonnull Index index)
Subspace for index in which to place a record in uniqueness violations. This is used while the index is being built to keep track of what values are duplicated and thus have to be addressed later.- Parameters:
index
- the index to retrieve the uniqueness violation subspace for- Returns:
- the subspace for the uniqueness violations for the given index
-
getIndexMaintainer
public IndexMaintainer getIndexMaintainer(@Nonnull Index index)
Get the maintainer for a given index.- Parameters:
index
- the required index- Returns:
- the maintainer for the given index
-
getKeySizeLimit
public int getKeySizeLimit()
-
getValueSizeLimit
public int getValueSizeLimit()
-
performIndexOperationAsync
public CompletableFuture<IndexOperationResult> performIndexOperationAsync(@Nonnull String indexName, @Nonnull IndexOperation operation)
-
performIndexOperation
public IndexOperationResult performIndexOperation(@Nonnull String indexName, @Nonnull IndexOperation operation)
-
loadRecordInternal
@Nonnull public CompletableFuture<FDBStoredRecord<Message>> loadRecordInternal(@Nonnull Tuple primaryKey, @Nonnull ExecuteState executeState, boolean snapshot)
- Specified by:
loadRecordInternal
in interfaceFDBRecordStoreBase<Message>
-
loadTypedRecord
@Nonnull protected <M extends Message> CompletableFuture<FDBStoredRecord<M>> loadTypedRecord(@Nonnull RecordSerializer<M> typedSerializer, @Nonnull Tuple primaryKey, boolean snapshot)
-
loadTypedRecord
@Nonnull protected <M extends Message> CompletableFuture<FDBStoredRecord<M>> loadTypedRecord(@Nonnull RecordSerializer<M> typedSerializer, @Nonnull Tuple primaryKey, @Nonnull ExecuteState executeState, boolean snapshot)
-
loadRecordVersionAsync
@Nonnull public Optional<CompletableFuture<FDBRecordVersion>> loadRecordVersionAsync(@Nonnull Tuple primaryKey)
Async version ofloadRecordVersion(Tuple)
. If the record does not have a version, but that cannot be determined before making a call to the database, this might return a completable future that wrapsnull
.- Parameters:
primaryKey
- the primary key of the record- Returns:
- a future that completes with the version of the record of
Optional.empty()
if versions are not enabled for this store
-
loadRecordVersionAsync
@Nonnull public Optional<CompletableFuture<FDBRecordVersion>> loadRecordVersionAsync(@Nonnull Tuple primaryKey, boolean snapshot)
Async version ofloadRecordVersion(Tuple, boolean)
.- Parameters:
primaryKey
- the primary key of the recordsnapshot
- whether to snapshot read- Returns:
- a future that completes with the version of the record of
Optional.empty()
if versions are not enabled for this store
-
loadRecordVersion
@Nonnull public Optional<FDBRecordVersion> loadRecordVersion(@Nonnull Tuple primaryKey)
Load the version of the last time a record with the given primary key was saved. If the record does not have a version (because the record does not exist or the record was last loaded when versions were not being stored), it will return the emptyOptional
.- Parameters:
primaryKey
- the primary key for the record- Returns:
- an
Optional
that, if not empty, contains record's version
-
loadRecordVersion
@Nonnull public Optional<FDBRecordVersion> loadRecordVersion(@Nonnull Tuple primaryKey, boolean snapshot)
Overload ofloadRecordVersion(Tuple)
that supports snapshot reads. Ifsnapshot
is set totrue
, reading the record's version does not add a read conflict to the store's transaction.- Parameters:
primaryKey
- the primary key for the recordsnapshot
- whether this operation should be done with asnapshot
- Returns:
- an
Optional
that, if not empty, contain's the record version
-
countKeysAndValues
protected void countKeysAndValues(@Nonnull StoreTimer.Count key, @Nonnull StoreTimer.Count keyBytes, @Nonnull StoreTimer.Count valueBytes, @Nonnull FDBStoredSizes sizeInfo)
-
countKeyValue
public void countKeyValue(@Nonnull StoreTimer.Count key, @Nonnull StoreTimer.Count keyBytes, @Nonnull StoreTimer.Count valueBytes, @Nonnull KeyValue keyValue)
-
countKeyValue
public void countKeyValue(@Nonnull StoreTimer.Count key, @Nonnull StoreTimer.Count keyBytes, @Nonnull StoreTimer.Count valueBytes, @Nonnull byte[] k, @Nonnull byte[] v)
-
preloadRecordAsync
@Nonnull public CompletableFuture<Void> preloadRecordAsync(@Nonnull Tuple primaryKey)
Description copied from interface:FDBRecordStoreBase
Get record into FDB RYW cache. Caller needs to hold on to result until ready or else there is a chance it will get GC'ed and cancelled before then.- Specified by:
preloadRecordAsync
in interfaceFDBRecordStoreBase<Message>
- Parameters:
primaryKey
- the primary key for the record to retrieve- Returns:
- a future that will return
null
when the record is preloaded
-
recordExistsAsync
@Nonnull public CompletableFuture<Boolean> recordExistsAsync(@Nonnull Tuple primaryKey, @Nonnull IsolationLevel isolationLevel)
Description copied from interface:FDBRecordStoreBase
Check if a record exists in the record store with the given primary key. This is slightly more efficient than loading the record and checking if that record isnull
as it does not have to deserialize the record, though the record's contents are still read from the database and sent over the network.- Specified by:
recordExistsAsync
in interfaceFDBRecordStoreBase<Message>
- Parameters:
primaryKey
- the primary key of the recordisolationLevel
- the isolation level to use when reading- Returns:
- a future that will complete to
true
if some record in record store has that primary key andfalse
otherwise
-
addRecordReadConflict
public void addRecordReadConflict(@Nonnull Tuple primaryKey)
Description copied from interface:FDBRecordStoreBase
Add a read conflict as if one had read the record with the given primary key. This will cause this transaction to fail (with aFDBExceptions.FDBStoreTransactionConflictException
) if a concurrent transaction modifies the record with the provided primary key. This call however does not require performing any reads against the database, so it is faster and cheaper to perform than a real read. Note also that read-only operations are not checked for conflicts, so if this method is called, but the transaction performs no mutations, the transaction will never be failed with the above exception. Note also that this does not check that a record with this primary key actually exists in the database.One use case is that this can be used to promote a read from
IsolationLevel.SNAPSHOT
toIsolationLevel.SERIALIZABLE
. For example, if one performs a query atIsolationLevel.SNAPSHOT
and then uses a subset of the records to determine a few other writes, then one can add conflicts to only the records actually used.This method should be used with care and is advised only for those users who need extra control over conflict ranges.
- Specified by:
addRecordReadConflict
in interfaceFDBRecordStoreBase<Message>
- Parameters:
primaryKey
- the primary key of the record to add a read conflict on- See Also:
Transaction.addReadConflictRange(byte[], byte[])
-
addRecordWriteConflict
public void addRecordWriteConflict(@Nonnull Tuple primaryKey)
Description copied from interface:FDBRecordStoreBase
Add a write conflict as if one had modified the record with the given primary key. This will cause any concurrent transactions to fail (with aFDBExceptions.FDBStoreTransactionConflictException
) if they read the record with the provided primary key. This call however does not require performing any writes against the database, so it is faster and cheaper to perform than a real write. Note that this does not check if a record with this primary key actually exists in the database, and it does not update any indexes associated with the record. In this way, it is identical (in terms of conflicts) with overwriting the given record with itself, though it will not induce any disk I/O or cause any watches on the modified keys to fire.This method should be used with care and is advised only for those users who need extra control over conflict ranges.
- Specified by:
addRecordWriteConflict
in interfaceFDBRecordStoreBase<Message>
- Parameters:
primaryKey
- the primary key of the record to add a write conflict on- See Also:
Transaction.addWriteConflictRange(byte[], byte[])
-
scanRecords
@Nonnull public RecordCursor<FDBStoredRecord<Message>> scanRecords(@Nullable Tuple low, @Nullable Tuple high, @Nonnull EndpointType lowEndpoint, @Nonnull EndpointType highEndpoint, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties)
Description copied from interface:FDBRecordStoreBase
Scan the records in the database in a range.- Specified by:
scanRecords
in interfaceFDBRecordStoreBase<Message>
- Parameters:
low
- low point of scan rangehigh
- high point of scan pointlowEndpoint
- whether low point is inclusive or exclusivehighEndpoint
- whether high point is inclusive or exclusivecontinuation
- any continuation from a previous scanscanProperties
- skip, limit and other scan properties- Returns:
- a cursor that will scan everything in the range, picking up at continuation, and honoring the given scan properties
-
scanTypedRecords
@Nonnull public <M extends Message> RecordCursor<FDBStoredRecord<M>> scanTypedRecords(@Nonnull RecordSerializer<M> typedSerializer, @Nullable Tuple low, @Nullable Tuple high, @Nonnull EndpointType lowEndpoint, @Nonnull EndpointType highEndpoint, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties)
-
countRecords
@Nonnull public CompletableFuture<Integer> countRecords(@Nullable Tuple low, @Nullable Tuple high, @Nonnull EndpointType lowEndpoint, @Nonnull EndpointType highEndpoint, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties)
Description copied from interface:FDBRecordStoreBase
Count the number of records in the database in a range.- Specified by:
countRecords
in interfaceFDBRecordStoreBase<Message>
- Parameters:
low
- low point of scan rangehigh
- high point of scan pointlowEndpoint
- whether low point is inclusive or exclusivehighEndpoint
- whether high point is inclusive or exclusivecontinuation
- any continuation from a previous scanscanProperties
- skip, limit and other scan properties- Returns:
- a future that will complete with the number of records in the range
-
scanIndex
@Nonnull public RecordCursor<IndexEntry> scanIndex(@Nonnull Index index, @Nonnull IndexScanType scanType, @Nonnull TupleRange range, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties)
Description copied from interface:FDBRecordStoreBase
Scan the entries in an index.- Specified by:
scanIndex
in interfaceFDBRecordStoreBase<Message>
- Parameters:
index
- the index to scanscanType
- the type of scan to performrange
- range to scancontinuation
- any continuation from a previous scanscanProperties
- skip, limit and other scan properties- Returns:
- a cursor that will scan the index, picking up at continuation, and honoring the given scan properties
-
scanUniquenessViolations
@Nonnull public RecordCursor<RecordIndexUniquenessViolation> scanUniquenessViolations(@Nonnull Index index, @Nonnull TupleRange range, @Nullable byte[] continuation, @Nonnull ScanProperties scanProperties)
Description copied from interface:FDBRecordStoreBase
Scan the list of uniqueness violations identified for an index. It looks only for violations within the given range subject to the given limit and (possibly) will go in reverse. They will be returned in an order that is grouped by the index value keys that they have in common and will be ordered within the grouping by the primary key.Because of how the data are stored, each primary key that is part of a uniqueness violation will appear at most once for each index key that is causing a violation. The associated existing key is going to be one of the other keys, but it might not be the only one. This means that the total number of violations per index key is capped at the number of records in the store (rather than the square), but it also means that the existing key data is of limited help.
- Specified by:
scanUniquenessViolations
in interfaceFDBRecordStoreBase<Message>
- Parameters:
index
- the index to scan the uniqueness violations ofrange
- the range of tuples to include in the scancontinuation
- any continuation from a previous scanscanProperties
- skip, limit and other scan properties- Returns:
- a cursor that will return uniqueness violations stored for the given index in the given store
-
resolveUniquenessViolation
@Nonnull public CompletableFuture<Void> resolveUniquenessViolation(@Nonnull Index index, @Nonnull Tuple valueKey, @Nullable Tuple remainPrimaryKey)
Description copied from interface:FDBRecordStoreBase
Removes all of the records that have the given value set as their index value (and are thus causing a uniqueness violation) except for the one that has the given primary key (if the key is notnull
). It also cleans up the set of uniqueness violations so that none of the remaining entries will be associated with the given value key.- Specified by:
resolveUniquenessViolation
in interfaceFDBRecordStoreBase<Message>
- Parameters:
index
- the index to resolve uniqueness violations forvalueKey
- the value of the index that is being removedremainPrimaryKey
- the primary key of the record that should remain (ornull
to remove all of them)- Returns:
- a future that will complete when all of the records have been removed
-
deleteRecordAsync
@Nonnull public CompletableFuture<Boolean> deleteRecordAsync(@Nonnull Tuple primaryKey)
Description copied from interface:FDBRecordStoreBase
Async version ofFDBRecordStoreBase.deleteRecord(com.apple.foundationdb.tuple.Tuple)
.- Specified by:
deleteRecordAsync
in interfaceFDBRecordStoreBase<Message>
- Parameters:
primaryKey
- the primary key of the record to delete- Returns:
- a future that completes
true
if the record was present to be deleted
-
deleteTypedRecord
@Nonnull protected <M extends Message> CompletableFuture<Boolean> deleteTypedRecord(@Nonnull RecordSerializer<M> typedSerializer, @Nonnull Tuple primaryKey)
-
deleteStore
public static void deleteStore(FDBRecordContext context, KeySpacePath path)
Delete the record store at the givenKeySpacePath
. This behaves likedeleteStore(FDBRecordContext, Subspace)
on the record store saved atKeySpacePath.toSubspace(FDBRecordContext)
.- Parameters:
context
- the transactional context in which to delete the record storepath
- the path to the record store- See Also:
deleteStore(FDBRecordContext, Subspace)
-
deleteStore
public static void deleteStore(FDBRecordContext context, Subspace subspace)
Delete the record store at the givenSubspace
. In addition to the store's data this will delete the store's header and therefore will remove any evidence that the store existed.This method does not read the underlying record store, so it does not validate that a record store exists in the given subspace. As it might be the case that this record store has a cacheable store state (see
setStateCacheability(boolean)
), this method resets the database's meta-data version-stamp. As a result, calling this method may cause other clients to invalidate their caches needlessly.- Parameters:
context
- the transactional context in which to delete the record storesubspace
- the subspace containing the record store
-
deleteAllRecords
public void deleteAllRecords()
Description copied from interface:FDBRecordStoreBase
Delete all the data in the record store.Everything except the store header and index state information is cleared from the database. This is is an efficient operation as all data are contiguous. This means that any disabled or write-only index will remain in its disabled or write-only state after all of the data are cleared. If one also wants to reset all index states, one can call
rebuildAllIndexes()
, which should complete quickly on an empty record store. If one wants to remove the record store entirely (including the store header and all index states), one should calldeleteStore(FDBRecordContext, KeySpacePath)
instead of this method.Note that, at the moment, this operation also has the side effect of resetting
MAX_EVER
andMIN_EVER
indexes. See: Issue #398.- Specified by:
deleteAllRecords
in interfaceFDBRecordStoreBase<Message>
- See Also:
deleteStore(FDBRecordContext, KeySpacePath)
,deleteStore(FDBRecordContext, Subspace)
-
deleteRecordsWhereAsync
public CompletableFuture<Void> deleteRecordsWhereAsync(@Nonnull QueryComponent component)
Description copied from interface:FDBRecordStoreBase
Async version ofFDBRecordStoreBase.deleteRecordsWhereAsync(com.apple.foundationdb.record.query.expressions.QueryComponent)
.- Specified by:
deleteRecordsWhereAsync
in interfaceFDBRecordStoreBase<Message>
- Parameters:
component
- the query filter for records to delete efficiently- Returns:
- a future that will be complete when the delete is done
-
mergeRecordTypeAndComponent
@Nonnull protected static QueryComponent mergeRecordTypeAndComponent(@Nonnull String recordType, @Nullable QueryComponent component)
-
getPipelineSizer
public FDBRecordStoreBase.PipelineSizer getPipelineSizer()
Description copied from interface:FDBRecordStoreBase
Get the function for computing the number of elements to allow in the asynchronous pipeline for an operation of the given type.- Specified by:
getPipelineSizer
in interfaceFDBRecordStoreBase<Message>
- Returns:
- the pipeline sizer
-
getSnapshotRecordCount
public CompletableFuture<Long> getSnapshotRecordCount(@Nonnull KeyExpression key, @Nonnull Key.Evaluated value)
Description copied from interface:FDBRecordStoreBase
Get the number of records in a portion of the record store determined by a group key expression. There must be a suitably groupedCOUNT
type index defined.- Specified by:
getSnapshotRecordCount
in interfaceFDBRecordStoreBase<Message>
- Parameters:
key
- the grouping key expressionvalue
- the value ofkey
to match- Returns:
- a future that will complete to the number of records
-
getSnapshotRecordCountForRecordType
public CompletableFuture<Long> getSnapshotRecordCountForRecordType(@Nonnull String recordTypeName)
Description copied from interface:FDBRecordStoreBase
Get the number of records in the record store of the given record type. The record type must have aCOUNT
index defined for it.- Specified by:
getSnapshotRecordCountForRecordType
in interfaceFDBRecordStoreBase<Message>
- Parameters:
recordTypeName
- record type for which to count records- Returns:
- a future that will complete to the number of records
-
decodeRecordCount
public static long decodeRecordCount(@Nullable byte[] bytes)
-
evaluateIndexRecordFunction
@Nonnull public <T> CompletableFuture<T> evaluateIndexRecordFunction(@Nonnull EvaluationContext evaluationContext, @Nonnull IndexRecordFunction<T> function, @Nonnull FDBRecord<Message> record)
Description copied from interface:FDBRecordStoreBase
Evaluate aIndexRecordFunction
against a record.- Specified by:
evaluateIndexRecordFunction
in interfaceFDBRecordStoreBase<Message>
- Type Parameters:
T
- the type of the result- Parameters:
evaluationContext
- evaluation context containing parameter bindingsfunction
- the function to evaluaterecord
- the record to evaluate against- Returns:
- a future that will complete with the result of evaluating the function against the record
-
evaluateTypedIndexRecordFunction
@Nonnull protected <T,M extends Message> CompletableFuture<T> evaluateTypedIndexRecordFunction(@Nonnull EvaluationContext evaluationContext, @Nonnull IndexRecordFunction<T> indexRecordFunction, @Nonnull FDBRecord<M> record)
-
evaluateStoreFunction
@Nonnull public <T> CompletableFuture<T> evaluateStoreFunction(@Nonnull EvaluationContext evaluationContext, @Nonnull StoreRecordFunction<T> function, @Nonnull FDBRecord<Message> record)
Description copied from interface:FDBRecordStoreBase
Evaluate aStoreRecordFunction
against a record.- Specified by:
evaluateStoreFunction
in interfaceFDBRecordStoreBase<Message>
- Type Parameters:
T
- the type of the result- Parameters:
evaluationContext
- evaluation context containing parameter bindingsfunction
- the function to evaluaterecord
- the record to evaluate against- Returns:
- a future that will complete with the result of evaluating the function against the record
-
evaluateTypedStoreFunction
@Nonnull public <T,M extends Message> CompletableFuture<T> evaluateTypedStoreFunction(@Nonnull EvaluationContext evaluationContext, @Nonnull StoreRecordFunction<T> function, @Nonnull FDBRecord<M> record)
-
evaluateAggregateFunction
@Nonnull public CompletableFuture<Tuple> evaluateAggregateFunction(@Nonnull List<String> recordTypeNames, @Nonnull IndexAggregateFunction aggregateFunction, @Nonnull TupleRange range, @Nonnull IsolationLevel isolationLevel)
Description copied from interface:FDBRecordStoreBase
Evaluate anIndexAggregateFunction
against a range of the store.- Specified by:
evaluateAggregateFunction
in interfaceFDBRecordStoreBase<Message>
- Parameters:
recordTypeNames
- record types for which to find a matching indexaggregateFunction
- the function to evaluaterange
- the range of records (group) for which to evaluateisolationLevel
- whether to use snapshot reads- Returns:
- a future that will complete with the result of evaluating the aggregate
-
planQuery
@Nonnull public RecordQueryPlan planQuery(@Nonnull RecordQuery query)
Description copied from interface:FDBRecordStoreBase
Plan a query.- Specified by:
planQuery
in interfaceFDBRecordStoreBase<Message>
- Parameters:
query
- the query to plan- Returns:
- a query plan
- See Also:
RecordQueryPlanner.plan(com.apple.foundationdb.record.query.RecordQuery)
-
writeOnlyIfTooManyRecordsForRebuild
@Nonnull public static IndexState writeOnlyIfTooManyRecordsForRebuild(long recordCount, boolean indexOnNewRecordTypes)
-
checkVersion
@Nonnull public CompletableFuture<Boolean> checkVersion(@Nullable FDBRecordStoreBase.UserVersionChecker userVersionChecker, @Nonnull FDBRecordStoreBase.StoreExistenceCheck existenceCheck)
Checks the meta-data version key of the record store and compares it to the version of the local meta-data object. If the meta-data version stored in the record store does not match the version stored in the local meta-data copy, the following might happen: (1) if the stored version is newer than the local version, this can return an exceptionally completed future with anFDBExceptions.FDBStoreException
indicating that the meta-data is stale; (2) if the stored version is older than the local version, this will update the store to include the changes that have happened since the last meta-data version; and (3) if the versions are the same, it will do nothing. If branch (2) is followed, then the process of updating the store based on the meta-data will do the following: (a) if the number of records is small, it will build all of the indexes that have been added between the two meta-data checks, or (b) if the number of records is large, it will mark the new indexes as write-only. It is then up to the client to start online index build jobs to build those indexes. This will also apply the passedFDBRecordStoreBase.UserVersionChecker
instance to check the user-defined version. The result of this check will be handled the same as with meta-data version changes, i.e., if the user version is newer than the stored version, then version is updated. If the user version is older than the stored version, it will throw an exception about the stale user version. If the two versions are the same, it will do nothing. This will return a future that will either complete exceptionally (in the case of a stale user or meta-data) or will complete withtrue
if the version was changed because the record store had an old version orfalse
if no change to the store was done.- Parameters:
userVersionChecker
- hook for checking if store state for client must changeexistenceCheck
- when to throw an exception if the record store does or does not already exist- Returns:
- future with whether the record store was modified by the check
-
checkStoreHeader
@API(INTERNAL) @Nonnull public static CompletableFuture<Void> checkStoreHeader(@Nonnull RecordMetaDataProto.DataStoreInfo storeHeader, @Nonnull FDBRecordContext context, @Nonnull SubspaceProvider subspaceProvider, @Nonnull Subspace subspace, @Nonnull FDBRecordStoreBase.StoreExistenceCheck existenceCheck)
-
saveStoreHeader
protected void saveStoreHeader(@Nonnull RecordMetaDataProto.DataStoreInfo storeHeader)
-
rebuildAllIndexes
@Nonnull public CompletableFuture<Void> rebuildAllIndexes()
Rebuild all of this store's indexes. All indexes will then be marked as readable when this function completes. Note that this will attempt to read all of the records within this store in a single transaction, so for large record stores, this can run up against transaction time and size limits. For larger stores, one should use theOnlineIndexer
to build each index instead.- Returns:
- a future that will complete when all of the indexes are built
-
clearAndMarkIndexWriteOnly
@Nonnull public CompletableFuture<Void> clearAndMarkIndexWriteOnly(@Nonnull String indexName)
-
clearAndMarkIndexWriteOnly
@Nonnull public CompletableFuture<Void> clearAndMarkIndexWriteOnly(@Nonnull Index index)
Prepare an index for rebuilding by clearing any existing data and marking the index as write-only.- Parameters:
index
- the index to build- Returns:
- a future that completes when the index has been cleared and marked write-only for building
-
setStateCacheabilityAsync
@Nonnull public CompletableFuture<Boolean> setStateCacheabilityAsync(boolean cacheable)
Set whether the store state is cacheable. In particular, this flag determines whether the meta-data version-stamp key is changed whenever theRecordStoreState
is changed. By default, record store state information is not cacheable. This is because for deployments in which there are many record stores sharing the same cluster, updating the meta-data version key every time any store changes its state could lead to performance problems, so (at least for now), this is a feature the user must opt-in to on each record store.- Parameters:
cacheable
- whether the meta-data version-stamp should be invalidated upon store state change- Returns:
- a future that will complete to
true
if the store state's cacheability has changed
-
setStateCacheability
public boolean setStateCacheability(boolean cacheable)
Set whether the store state is cacheable. This operation might block if the record store state has not yet been loaded. UsesetStateCacheabilityAsync(boolean)
in asynchronous contexts.- Parameters:
cacheable
- whether this store's state should be cacheable- Returns:
- whether the record store state cacheability has changed
- See Also:
setStateCacheabilityAsync(boolean)
-
getHeaderUserField
@Nullable public ByteString getHeaderUserField(@Nonnull String userField)
Get the value of a user-settable field from the store header. Each of these fields are written into this record store's store header. This is loaded automatically by the record store as part ofFDBRecordStoreBase.BaseBuilder.createOrOpenAsync()
or one of its variants. This means that reading this information from the header does not require any additional communication with database assuming that the record store has already been initialized. As a result, this is not a blocking call.Using this feature also requires that the record store be on format version
HEADER_USER_FIELDS_FORMAT_VERSION
or higher. There is no change to the on-disk format version from the previous format version except that extra fields in the store header were added. No data migration is necessary to upgrade to that version if an existing store is on the previous format version, but the new version is used to prevent the user from serializing data and then not being able to read it from instances running an older version of the Record Layer.- Parameters:
userField
- the name of the user-settable field to read- Returns:
- the value of that field in the header or
null
if it is unset - See Also:
setHeaderUserFieldAsync(String, ByteString)
-
setHeaderUserFieldAsync
@Nonnull public CompletableFuture<Void> setHeaderUserFieldAsync(@Nonnull String userField, @Nonnull ByteString value)
Set the value of a user-settable field in the store header. The store header contains meta-data that is then used by the Record Layer to determine information including what meta-data version was used the last time the record store was accessed. It is therefore loaded every time the record store is opened by theFDBRecordStoreBase.BaseBuilder.createOrOpenAsync()
or one of its variants. The user may also elect to set fields to custom values that might be meaningful for their application. For example, if the user wishes to migrate from one record type to another, the user might include a field with a value that indicates whether that migration has completed.Note that there are a few potential pitfalls that adopters of this API should be aware of:
-
Because all operations to a single record store must read the store header, every time the
value is updated, any concurrent operations to the store will fail with a
FDBStoreTransactionConflictException
. Therefore, this should only ever be used for data that are mutated at a very low rate. - As this data must be read every time the record store is created (which is at least once per transaction), the value should not be too large. There is not at the moment a hard limit applied, but a good rule of thumb may be to keep the total size from all user fields under a kilobyte.
The value of these fields are simple byte arrays, so the user is free to choose their own serialization format for the value included in this field. One recommended strategy is for the user to use Protobuf to serialize a message with possibly multiple keys and values, each with meaning to the user, and then to write it to a single user field (or a small number if appropriate). This decreases the total size of the user fields when compared to something like storing one user-field for each field (as the Protobuf serialization format is more compact), and it allows the user to follow standard Protobuf evolution guidelines as these fields evolve.
Once set, the value of these fields can be retrieved by calling
getHeaderUserField(String)
. They can be cleared by callingclearHeaderUserFieldAsync(String)
. Within a given transaction, updates to the header fields should be visible throughgetHeaderUserField()
(that is, the header user fields support read-your-writes within a transaction), but the context associated with this store must be committed for other transactions to see the update.Using this feature also requires that the record store be on format version
HEADER_USER_FIELDS_FORMAT_VERSION
or higher. There is no change to the on-disk format version from the previous format version except that extra fields in the store header were added. No data migration is necessary to upgrade to that version if an existing store is on the previous format version, but the new version is used to prevent the user from serializing data and then not being able to read it from instances running an older version of the Record Layer.- Parameters:
userField
- the name of the user-settable field to writevalue
- the value to set the field to- Returns:
- a future that will be ready when setting the field has completed
- See Also:
getHeaderUserField(String)
-
Because all operations to a single record store must read the store header, every time the
value is updated, any concurrent operations to the store will fail with a
-
setHeaderUserFieldAsync
@Nonnull public CompletableFuture<Void> setHeaderUserFieldAsync(@Nonnull String userField, @Nonnull byte[] value)
Set the value of a user-settable field in the store header. The provided byte array will be wrapped in aByteString
and then passed tosetHeaderUserFieldAsync(String, ByteString)
. See that function for more details and for a list of caveats on using this function.- Parameters:
userField
- the name of the user-settable field to writevalue
- the value to set the field to- Returns:
- a future that will be ready when setting the field has completed
- See Also:
setHeaderUserFieldAsync(String, ByteString)
-
setHeaderUserField
public void setHeaderUserField(@Nonnull String userField, @Nonnull ByteString value)
Set the value of a user-settable field in the store header. This is a blocking version ofsetHeaderUserFieldAsync(String, ByteString)
. In most circumstances, this function should not be blocking, but it might if either the store header has not yet been loaded or in some circumstances if the meta-data is cacheable. It should therefore generally be avoided in asynchronous contexts to be safe.- Parameters:
userField
- the name of the user-settable field to writevalue
- the value to set the field to- See Also:
setHeaderUserFieldAsync(String, ByteString)
,setStateCacheabilityAsync(boolean)
-
setHeaderUserField
public void setHeaderUserField(@Nonnull String userField, @Nonnull byte[] value)
Set the value of a user-settable field in the store header. This is a blocking version ofsetHeaderUserFieldAsync(String, byte[])
. In most circumstances, this function should not be blocking, but it might if either the store header has not yet been loaded or in some circumstances if the meta-data is cacheable. It should therefore generally be avoided in asynchronous contexts to be safe.- Parameters:
userField
- the name of the user-settable field to writevalue
- the value to set the field to- See Also:
setHeaderUserFieldAsync(String, ByteString)
,setStateCacheabilityAsync(boolean)
-
clearHeaderUserFieldAsync
@Nonnull public CompletableFuture<Void> clearHeaderUserFieldAsync(@Nonnull String userField)
Clear the value of a user-settable field in the store header. This removes a field from the store header after it has been set bysetHeaderUserFieldAsync(String, ByteString)
. This has the same caveats as that function. In particular, whenever this is called, all concurrent operations to the same record store will also fail with anFDBStoreTransactionConflictException
. As a result, one should avoid clearing these fields too often.- Parameters:
userField
- the name of the user-settable field to clear- Returns:
- a future that will be ready when the field has bean cleared
- See Also:
setHeaderUserFieldAsync(String, ByteString)
-
clearHeaderUserField
public void clearHeaderUserField(@Nonnull String userField)
Clear the value of a user-settable field in the store header. This is a blocking version ofclearHeaderUserFieldAsync(String)
. In most circumstances, this function should not be blocking, but it might if either the store header has not yet been loaded or in some circumstances if the meta-data is cacheable. It should therefore generally be avoided in asynchronous contexts to be safe.- Parameters:
userField
- the name of user-settable field to clear- See Also:
clearHeaderUserFieldAsync(String)
,setStateCacheabilityAsync(boolean)
-
markIndexWriteOnly
@Nonnull public CompletableFuture<Boolean> markIndexWriteOnly(@Nonnull String indexName)
Adds the index of the given name to the list of write-only indexes stored within the store. This will update the list stored within database. This will returntrue
if the store had to be modified in order to mark the index as write only (i.e., the index was not already write-only) andfalse
otherwise.- Parameters:
indexName
- the name of the index to mark as write-only- Returns:
- a future that will contain
true
if the store was modified andfalse
otherwise - Throws:
IllegalArgumentException
- if the index is not present in the meta-data
-
markIndexWriteOnly
@Nonnull public CompletableFuture<Boolean> markIndexWriteOnly(@Nonnull Index index)
Adds the given index to the list of write-only indexes stored within the store. See the version ofmarkIndexWriteOnly()
that takes aString
for more details.- Parameters:
index
- the index to mark as write only- Returns:
- a future that will contain
true
if the store was modified andfalse
otherwise
-
markIndexDisabled
@Nonnull public CompletableFuture<Boolean> markIndexDisabled(@Nonnull String indexName)
Adds the index of the given name to the list of disabled indexes stored within the store. Because reading a disabled index later is unsafe unless one does a rebuild between the time it is marked disabled and the time it is marked readable, marking an index as disabled will also clear the store of all data associated with that index. This will returntrue
if the store had to be modified to mark the index as diabled (i.e., the index was not already disabled) andfalse
otherwise.- Parameters:
indexName
- the name of the index to mark as disabled- Returns:
- a future that will contain
true
if the store was modified andfalse
otherwise - Throws:
IllegalArgumentException
- if the index is not present in the meta-data
-
markIndexDisabled
@Nonnull public CompletableFuture<Boolean> markIndexDisabled(@Nonnull Index index)
Adds the index to the list of disabled indexes stored within the store. See the version ofmarkIndexDisabled(Index)
markIndexDisabled()} that takes aString
for more details.- Parameters:
index
- the index to mark as disabled- Returns:
- a future that will contain
true
if the store was modified andfalse
otherwise
-
firstUnbuiltRange
@Nonnull public CompletableFuture<Optional<Range>> firstUnbuiltRange(@Nonnull Index index)
Returns the first unbuilt range of an index that is currently being bulit. If there is no range that is currently unbuilt, it will return an emptyOptional
. If there is one, it will return anOptional
set to the first unbuilt range it finds.- Parameters:
index
- the index to check built state- Returns:
- a future that will contain the first unbuilt range if any
-
markIndexReadable
@Nonnull public CompletableFuture<Boolean> markIndexReadable(@Nonnull Index index)
Marks an index as readable. See the version ofmarkIndexReadable()
that takes aString
as a parameter for more details.- Parameters:
index
- the index to mark readable- Returns:
- a future that will either complete exceptionally if the index can not
be made readable or will contain
true
if the store was modified andfalse
otherwise
-
markIndexReadable
@Nonnull public CompletableFuture<Boolean> markIndexReadable(@Nonnull String indexName)
Marks the index with the given name as readable. More correctly, it removes if from the write-only list, so future queries (assuming that they reload theRecordStoreState
) will be able to use that index. This will check to make sure that the index is actually built and ready to go before making it readable. If it is not, the future will complete exceptionally with anFDBRecordStore.IndexNotBuiltException
. If the store is modified when marking the index as readable (i.e., if it was previously write-only), then this will returntrue
. Otherwise, it will returnfalse
.- Parameters:
indexName
- the name of the index to mark readable- Returns:
- a future that will either complete exceptionally if the index can not
be made readable or will contain
true
if the store was modified andfalse
otherwise
-
uncheckedMarkIndexReadable
@Nonnull public CompletableFuture<Boolean> uncheckedMarkIndexReadable(@Nonnull String indexName)
Marks the index with the given name as readable without checking to see if it is ready. This is dangerous to do if one has not first verified that the index is ready to be readable as it can cause half-built indexes to be used within queries and can thus produce inconsistent results.- Parameters:
indexName
- the name of the index to mark readable- Returns:
- a future that will contain
true
if the store was modified andfalse
otherwise
-
preloadSubspaceAsync
@Nonnull @API(INTERNAL) protected CompletableFuture<Void> preloadSubspaceAsync()
Ensure that subspace provider has cachedSubspace
so that callingFDBStoreBase.getSubspace()
will not block.- Returns:
- a future that will be complete when the subspace is available
-
preloadRecordStoreStateAsync
@Nonnull @API(INTERNAL) protected CompletableFuture<Void> preloadRecordStoreStateAsync()
Loads the current state of the record store asynchronously and caches it in memory so thatgetRecordStoreState()
requires no i/o.- Returns:
- a future that will be complete when this store has loaded its record store state
-
preloadRecordStoreStateAsync
@Nonnull @API(INTERNAL) protected CompletableFuture<Void> preloadRecordStoreStateAsync(@Nonnull FDBRecordStoreBase.StoreExistenceCheck existenceCheck, @Nonnull IsolationLevel storeHeaderIsolationLevel, @Nonnull IsolationLevel indexStateIsolationLevel)
Loads the current state of the record store asynchronously and setsrecordStoreStateRef
.- Parameters:
existenceCheck
- the action to be taken when the record store already exists (or does not exist yet)storeHeaderIsolationLevel
- the isolation level for loading the store headerindexStateIsolationLevel
- the isolation level for loading index state- Returns:
- a future that will be complete when this store has loaded its record store state
-
loadRecordStoreStateAsync
@API(INTERNAL) @Nonnull public CompletableFuture<RecordStoreState> loadRecordStoreStateAsync(@Nonnull FDBRecordStoreBase.StoreExistenceCheck existenceCheck)
Loads the current state of the record store within the given subspace asynchronously. This method does not cache the state in the memory.- Parameters:
existenceCheck
- the action to be taken when the record store already exists (or does not exist yet)- Returns:
- a future that will contain the state of the record state located at the given subspace
-
getIndexState
@Nonnull public IndexState getIndexState(@Nonnull Index index)
Get the state of the index for this record store. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state. However, if another operation in a different transaction happens concurrently that changes the index's state, operations using the sameFDBRecordContext
as this record store will fail to commit due to conflicts.- Parameters:
index
- the index to check for the state- Returns:
- the state of the given index
- Throws:
IllegalArgumentException
- if no index in the metadata has the same name as this index
-
getIndexState
@Nonnull public IndexState getIndexState(@Nonnull String indexName)
Get the state of the index with the given name for this record store. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state.- Parameters:
indexName
- the name of the index to check for the state- Returns:
- the state of the given index
- Throws:
IllegalArgumentException
- if no index in the metadata has the given name
-
isIndexReadable
public boolean isIndexReadable(@Nonnull Index index)
Determine if the index is readable for this record store. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state. However, if another operation in a different transaction happens concurrently that changes the index's state, operations using the sameFDBRecordContext
as this record store will fail to commit due to conflicts.- Parameters:
index
- the index to check for readability- Returns:
true
if the index is readable andfalse
otherwise- Throws:
IllegalArgumentException
- if no index in the metadata has the same name as this index
-
isIndexReadable
public boolean isIndexReadable(@Nonnull String indexName)
Determine if the index with the given name is readable for this record store. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state.- Parameters:
indexName
- the name of the index to check for readability- Returns:
true
if the named index is readable andfalse
otherwise- Throws:
IllegalArgumentException
- if no index in the metadata has the given name
-
isIndexWriteOnly
public boolean isIndexWriteOnly(@Nonnull Index index)
Determine if the index is write-only for this record store. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state. However, if another operation in a different transaction happens concurrently that changes the index's state, operations using the sameFDBRecordContext
as this record store will fail to commit due to conflicts.- Parameters:
index
- the index to check if write-only- Returns:
true
if the index is write-only andfalse
otherwise- Throws:
IllegalArgumentException
- if no index in the metadata has the same name as this index
-
isIndexWriteOnly
public boolean isIndexWriteOnly(@Nonnull String indexName)
Determine if the index with the given name is write-only for this record store. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state.- Parameters:
indexName
- the name of the index to check if write-only- Returns:
true
if the named index is write-only andfalse
otherwise- Throws:
IllegalArgumentException
- if no index in the metadata has the given name
-
isIndexDisabled
public boolean isIndexDisabled(@Nonnull Index index)
Determine if the index is disabled for this record store. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state. However, if another operation in a different transaction happens concurrently that changes the index's state, operations using the sameFDBRecordContext
as this record store will fail to commit due to conflicts.- Parameters:
index
- the index to check if write-only- Returns:
true
if the index is disabled andfalse
otherwise- Throws:
IllegalArgumentException
- if no index in the metadata has the same name as this index
-
isIndexDisabled
public boolean isIndexDisabled(@Nonnull String indexName)
Determine if the index with the given name is disabled for this record store. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state.- Parameters:
indexName
- the name of the index to check if disabled- Returns:
true
if the named index is disabled andfalse
otherwise- Throws:
IllegalArgumentException
- if no index in the metadata has the given name
-
getIndexBuildStateAsync
public CompletableFuture<IndexBuildState> getIndexBuildStateAsync(Index index)
Get the progress of building the given index.- Parameters:
index
- the index to check the index build state- Returns:
- a future that completes to the progress of building the given index
- See Also:
IndexBuildState
-
getReadableIndexes
@Nonnull public List<Index> getReadableIndexes(@Nonnull RecordTypeOrBuilder recordType)
Gets the list of readable indexes that are on the given record type. This only include thoseIndex
es that are readable, i.e., the index name is not within theRecordStoreState
's list of write-only indexes or its list of disabled indexes.- Parameters:
recordType
- type of record to get the readable indexes of- Returns:
- the list of readable indexes on the given type
-
getEnabledIndexes
@Nonnull public List<Index> getEnabledIndexes(@Nonnull RecordTypeOrBuilder recordType)
Gets the list of enabled indexes that are on the given record type. This only include thoseIndex
es that are enabled, i.e., the index name is not within theRecordStoreState
's list of disabled indexes.- Parameters:
recordType
- type of record to get the enabled indexes of- Returns:
- the list of enabled indexes on the given type
-
getReadableMultiTypeIndexes
@Nonnull public List<Index> getReadableMultiTypeIndexes(@Nonnull RecordTypeOrBuilder recordType)
Gets the list of readable indexes that are on multiple record types one of which is the given type. This only include thoseIndex
es that are readable, i.e., the index name is not within theRecordStoreState
's list of write-only indexes or its list of disabled indexes.- Parameters:
recordType
- type of record to get the readable multi-type indexes of- Returns:
- the list of readable indexes on multiple types including the given type
-
getEnabledMultiTypeIndexes
@Nonnull public List<Index> getEnabledMultiTypeIndexes(@Nonnull RecordTypeOrBuilder recordType)
Gets the list of enabled indexes that are on multiple record types one of which is the given type. This only include thoseIndex
es that are enabled, i.e., the index name is not within theRecordStoreState
's list of disabled indexes.- Parameters:
recordType
- type of record to get the enabled multi-type indexes of- Returns:
- the list of readable indexes on multiple types including the given type
-
getReadableUniversalIndexes
@Nonnull public List<Index> getReadableUniversalIndexes()
Gets the list of readable universal indexes, i.e., the indexes on all record types. This only include thoseIndex
es that are readable, i.e., the index name is not within theRecordStoreState
's list of write-only indexes or its list of disabled indexes.- Returns:
- the list of readable universal indexes
-
getEnabledUniversalIndexes
@Nonnull public List<Index> getEnabledUniversalIndexes()
Gets the list of enabled universal indexes, i.e., the indexes on all record types. This only include thoseIndex
es that are enabled, i.e., the index name is not within theRecordStoreState
's list of disabled indexes.- Returns:
- the list of readable universal indexes
-
getAllIndexStates
@Nonnull public Map<Index,IndexState> getAllIndexStates()
Gets a map fromIndex
toIndexState
for all the indexes in the meta-data. This method will not perform any queries to the underlying database and instead satisfies the answer based on the in-memory cache of store state. However, if another operation in a different transaction happens concurrently that changes the index's state, operations using the sameFDBRecordContext
as this record store will fail to commit due to conflicts.- Returns:
- a map of all the index states.
-
rebuildIndexes
@Nonnull protected CompletableFuture<Void> rebuildIndexes(@Nonnull Map<Index,List<RecordType>> indexes, @Nonnull Map<Index,IndexState> newStates, @Nonnull List<CompletableFuture<Void>> work, @Nonnull FDBRecordStore.RebuildIndexReason reason, @Nullable Integer oldMetaDataVersion)
-
rebuildOrMarkIndex
protected CompletableFuture<Void> rebuildOrMarkIndex(@Nonnull Index index, @Nonnull IndexState indexState, @Nullable List<RecordType> recordTypes, @Nonnull FDBRecordStore.RebuildIndexReason reason, @Nullable Integer oldMetaDataVersion)
-
rebuildIndex
@Nonnull public CompletableFuture<Void> rebuildIndex(@Nonnull Index index)
Rebuild an index. This clears the index and attempts to build it within a single transaction. Upon successful completion, the index is marked as readable and can be used to satisfy queries.Because the operations all occur within a single transaction, for larger record stores, this operation can run into transaction size and time limits. (See: FoundationDB Known Limitations.) To build an index on such a record store, the user should use the
OnlineIndexer
, which breaks up work across multiple transactions to avoid those limits.- Parameters:
index
- the index to rebuild- Returns:
- a future that will complete when the index build has finished
- See Also:
OnlineIndexer
-
rebuildIndex
@Nonnull public CompletableFuture<Void> rebuildIndex(@Nonnull Index index, @Nullable Collection<RecordType> recordTypes, @Nonnull FDBRecordStore.RebuildIndexReason reason)
-
getRecordCountForRebuildIndexes
@Nonnull protected org.apache.commons.lang3.tuple.Pair<CompletableFuture<Long>,Boolean> getRecordCountForRebuildIndexes(boolean newStore, boolean rebuildRecordCounts, @Nonnull Map<Index,List<RecordType>> indexes)
Get count of records to pass to checker to decide whether to build right away.- Parameters:
newStore
-true
if this is a brand new storerebuildRecordCounts
-true
if there is a record count key that needs to be rebuiltindexes
- indexes that need to be built- Returns:
- a pair of a future that completes to the record count for the version checker
and a flag that is
true
if this count is in fact for all record types
-
singleRecordTypeWithPrefixKey
@Nullable protected RecordType singleRecordTypeWithPrefixKey(@Nonnull Map<Index,List<RecordType>> indexes)
-
getStatesForRebuildIndexes
@Nonnull protected Map<Index,IndexState> getStatesForRebuildIndexes(@Nullable FDBRecordStoreBase.UserVersionChecker userVersionChecker, @Nonnull Map<Index,List<RecordType>> indexes, long recordCount, boolean newStore, boolean rebuildRecordCounts, int oldMetaDataVersion, int oldFormatVersion)
-
removeFormerIndex
public void removeFormerIndex(FormerIndex formerIndex)
-
checkPossiblyRebuildRecordCounts
protected boolean checkPossiblyRebuildRecordCounts(@Nonnull RecordMetaData metaData, @Nonnull RecordMetaDataProto.DataStoreInfo.Builder info, @Nonnull List<CompletableFuture<Void>> work, int oldFormatVersion)
-
addRebuildRecordCountsJob
public void addRebuildRecordCountsJob(List<CompletableFuture<Void>> work)
-
getPrimaryKeyBoundaries
@API(EXPERIMENTAL) @Nonnull public RecordCursor<Tuple> getPrimaryKeyBoundaries(@Nonnull Tuple low, @Nonnull Tuple high)
Return a cursor of boundaries separating the key ranges maintained by each FDB server. This information can be useful for splitting a large task (e.g., rebuilding an index for a large record store) into smaller tasks (e.g., rebuilding the index for records in certain primary key ranges) more evenly so that they can be executed in a parallel fashion efficiently. The returned boundaries are an estimate from FDB's locality API and may not represent the exact boundary locations at any database version.The boundaries are returned as a cursor which is sorted and does not contain any duplicates. The first element of the list is greater than or equal to
low
, and the last element is less than or equal tohigh
.This implementation may not work when there are too many shard boundaries to complete in a single transaction.
Note: the returned cursor is blocking and must not be used in an asynchronous context
- Parameters:
low
- low endpoint of primary key range (inclusive)high
- high endpoint of primary key range (exclusive)- Returns:
- the list of boundary primary keys
-
validateMetaData
@Deprecated public void validateMetaData()
Deprecated.validation is done byRecordMetaDataBuilder
Validate the current meta-data for this store.
-
repairRecordKeys
@Nonnull public CompletableFuture<byte[]> repairRecordKeys(@Nullable byte[] continuation, @Nonnull ScanProperties scanProperties)
-
repairRecordKeys
@Nonnull public CompletableFuture<byte[]> repairRecordKeys(@Nullable byte[] continuation, @Nonnull ScanProperties scanProperties, boolean isDryRun)
Validate and repair known potential issues with record keys. Currently, this method is capable of identifying and repairing the following scenarios:- For record stores in which record splitting is disabled but the
omitUnsplitRecordSuffix
flag istrue
, keys found missing theSplitHelper.UNSPLIT_RECORD
suffix will be repaired. - For record stores in which record splitting is disabled, but the record key suffix is found to be
a value other than
SplitHelper.UNSPLIT_RECORD
, theFDBStoreTimer.Counts.INVALID_SPLIT_SUFFIX
counter will be incremented. - For record stores in which record splitting is disabled, but the record key is longer than expected,
the
FDBStoreTimer.Counts.INVALID_KEY_LENGTH
counter will be incremented.
- Parameters:
continuation
- continuation from a previous repair attempt ornull
to start from the beginningscanProperties
- properties to provide scan limits on the repair process record keys should be loggedisDryRun
- if true, no repairs are made, however counters involving irregular keys or keys that would would have been repaired are incremented- Returns:
- a future that completes to a continuation or
null
if the repair has been completed
- For record stores in which record splitting is disabled but the
-
newBuilder
@Nonnull public static FDBRecordStore.Builder newBuilder()
-
asBuilder
@Nonnull public FDBRecordStore.Builder asBuilder()
-
-