Class FDBRecordStore

    • Field Detail

      • 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
      • 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
      • INT64_ZERO

        public static final byte[] INT64_ZERO
      • formatVersion

        protected int formatVersion
      • userVersion

        protected int userVersion
    • Method Detail

      • getMetaDataProvider

        @Nullable
        public RecordMetaDataProvider getMetaDataProvider()
        Get the provider for the record store's meta-data.
        Returns:
        the meta-data source to use
      • getRecordStoreState

        @Nonnull
        public RecordStoreState getRecordStoreState()
        Get the RecordStoreState 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
      • indexRangeSubspace

        @Nonnull
        public Subspace indexRangeSubspace​(@Nonnull
                                           Index index)
        Subspace for index in which to place a RangeSet. 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()
      • loadRecordVersionAsync

        @Nonnull
        public Optional<CompletableFuture<FDBRecordVersion>> loadRecordVersionAsync​(@Nonnull
                                                                                    Tuple primaryKey)
        Async version of loadRecordVersion(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 wraps null.
        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
      • 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 empty Optional.
        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 of loadRecordVersion(Tuple) that supports snapshot reads. If snapshot is set to true, reading the record's version does not add a read conflict to the store's transaction.
        Parameters:
        primaryKey - the primary key for the record
        snapshot - whether this operation should be done with a snapshot
        Returns:
        an Optional that, if not empty, contain's the record version
      • 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 interface FDBRecordStoreBase<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 is null 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 interface FDBRecordStoreBase<Message>
        Parameters:
        primaryKey - the primary key of the record
        isolationLevel - 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 and false 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 a FDBExceptions.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 to IsolationLevel.SERIALIZABLE. For example, if one performs a query at IsolationLevel.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 interface FDBRecordStoreBase<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 a FDBExceptions.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 interface FDBRecordStoreBase<Message>
        Parameters:
        primaryKey - the primary key of the record to add a write conflict on
        See Also:
        Transaction.addWriteConflictRange(byte[], byte[])
      • 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 interface FDBRecordStoreBase<Message>
        Parameters:
        index - the index to scan the uniqueness violations of
        range - the range of tuples to include in the scan
        continuation - any continuation from a previous scan
        scanProperties - 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 not null). 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 interface FDBRecordStoreBase<Message>
        Parameters:
        index - the index to resolve uniqueness violations for
        valueKey - the value of the index that is being removed
        remainPrimaryKey - the primary key of the record that should remain (or null to remove all of them)
        Returns:
        a future that will complete when all of the records have been removed
      • deleteStore

        public static void deleteStore​(FDBRecordContext context,
                                       Subspace subspace)
        Delete the record store at the given Subspace. 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 store
        subspace - the subspace containing the record store
      • decodeRecordCount

        public static long decodeRecordCount​(@Nullable
                                             byte[] bytes)
      • 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 an FDBExceptions.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 passed FDBRecordStoreBase.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 with true if the version was changed because the record store had an old version or false if no change to the store was done.
        Parameters:
        userVersionChecker - hook for checking if store state for client must change
        existenceCheck - 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
      • 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 the OnlineIndexer 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
                                                                  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 the RecordStoreState 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. Use setStateCacheabilityAsync(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 of FDBRecordStoreBase.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 the FDBRecordStoreBase.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 calling clearHeaderUserFieldAsync(String). Within a given transaction, updates to the header fields should be visible through getHeaderUserField() (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 write
        value - the value to set the field to
        Returns:
        a future that will be ready when setting the field has completed
        See Also:
        getHeaderUserField(String)
      • 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 of setHeaderUserFieldAsync(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 write
        value - the value to set the field to
        See Also:
        setHeaderUserFieldAsync(String, ByteString), setStateCacheabilityAsync(boolean)
      • clearHeaderUserField

        public void clearHeaderUserField​(@Nonnull
                                         String userField)
        Clear the value of a user-settable field in the store header. This is a blocking version of clearHeaderUserFieldAsync(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 return true 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) and false 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 and false 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 of markIndexWriteOnly() that takes a String for more details.
        Parameters:
        index - the index to mark as write only
        Returns:
        a future that will contain true if the store was modified and false 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 return true if the store had to be modified to mark the index as diabled (i.e., the index was not already disabled) and false otherwise.
        Parameters:
        indexName - the name of the index to mark as disabled
        Returns:
        a future that will contain true if the store was modified and false 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 of markIndexDisabled(Index) markIndexDisabled()} that takes a String for more details.
        Parameters:
        index - the index to mark as disabled
        Returns:
        a future that will contain true if the store was modified and false 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 empty Optional. If there is one, it will return an Optional 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 of markIndexReadable() that takes a String 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 and false 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 the RecordStoreState) 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 an FDBRecordStore.IndexNotBuiltException. If the store is modified when marking the index as readable (i.e., if it was previously write-only), then this will return true. Otherwise, it will return false.
        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 and false 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 and false otherwise
      • preloadRecordStoreStateAsync

        @Nonnull
        @API(INTERNAL)
        protected CompletableFuture<Void> preloadRecordStoreStateAsync()
        Loads the current state of the record store asynchronously and caches it in memory so that getRecordStoreState() 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 sets recordStoreStateRef.
        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 header
        indexStateIsolationLevel - 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 same FDBRecordContext 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 same FDBRecordContext 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 and false 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 and false 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 same FDBRecordContext 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 and false 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 and false 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 same FDBRecordContext 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 and false 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 and false 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 those Indexes that are readable, i.e., the index name is not within the RecordStoreState'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 those Indexes that are enabled, i.e., the index name is not within the RecordStoreState'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 those Indexes that are readable, i.e., the index name is not within the RecordStoreState'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 those Indexes that are enabled, i.e., the index name is not within the RecordStoreState'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 those Indexes that are readable, i.e., the index name is not within the RecordStoreState'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 those Indexes that are enabled, i.e., the index name is not within the RecordStoreState's list of disabled indexes.
        Returns:
        the list of readable universal indexes
      • getAllIndexStates

        @Nonnull
        public Map<Index,​IndexState> getAllIndexStates()
        Gets a map from Index to IndexState 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 same FDBRecordContext as this record store will fail to commit due to conflicts.
        Returns:
        a map of all the index states.
      • 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
      • 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 store
        rebuildRecordCounts - true if there is a record count key that needs to be rebuilt
        indexes - 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
      • removeFormerIndex

        public void removeFormerIndex​(FormerIndex formerIndex)
      • 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 to high.

        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 by RecordMetaDataBuilder
        Validate the current meta-data for this store.
      • 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:
        Parameters:
        continuation - continuation from a previous repair attempt or null to start from the beginning
        scanProperties - properties to provide scan limits on the repair process record keys should be logged
        isDryRun - 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