|
|
- #pragma once
-
- #include "IAsyncContext.h"
- #include "IDescriptor.h"
-
- namespace fsdk {
-
- #ifndef DOXYGEN_SHOULD_SKIP_THIS
- DECLARE_SMARTPTR(IStaticDescriptorStorage);
- DECLARE_SMARTPTR(IDynamicDescriptorStorage);
- DECLARE_SMARTPTR(IIndex);
- DECLARE_SMARTPTR(IDenseIndex);
- DECLARE_SMARTPTR(IDynamicIndex);
- DECLARE_SMARTPTR(IIndexBuilder);
- #endif
-
- /// Intergral type used as identification of descriptor in internal storage.
- using DescriptorId = size_t;
-
- /**
- * @brief Result of index search.
- * */
- struct SearchResult : MatchingResult {
- /// Identificator of descriptor in some storage.
- DescriptorId index;
-
- /// Default constructor.
- SearchResult() noexcept
- : MatchingResult()
- , index(std::numeric_limits<DescriptorId>::max())
- {}
-
- /**
- * @brief Construct structure with parameters.
- * @param [in] distance Distance between descriptors.
- * @param [in] similarity Similarity between descriptors.
- * @param [in] index Index of found descriptors in some storage.
- * */
- SearchResult(
- float distance,
- float similarity,
- DescriptorId index) noexcept
- : MatchingResult(distance, similarity)
- , index(index)
- {}
- };
-
- /**
- * @brief Static descriptor storage interface.
- * @details You may think of it as read only access to some internal container.
- * */
- struct IStaticDescriptorStorage {
- /**
- * @brief Requests descriptor data out of internal storage.
- * @param [in] index Identification value of some descriptor. Might be received either
- * by using @see IDynamicDescriptorStorage::append methods, or as output of
- * @see IIndex::search query. Must be less than @see size().
- * @param [out] descriptor Ptr to created descriptor object with correctly set
- * version and length. Only changes data of passed descriptor.
- * @return Result with error code.
- * @see IDescriptor, DescriptorId, Result and FSDKError for details.
- * */
- virtual Result<FSDKError> descriptorByIndex(
- const DescriptorId index,
- IDescriptor* descriptor) const noexcept = 0;
-
- /**
- * @brief Return version of stored descriptors.
- * @return Version of stored descriptors. If not initialized, 0 is returned.
- * */
- virtual uint32_t getDescriptorVersion() const noexcept = 0;
-
- /**
- * @brief Return size of internal storage.
- * @return Size of internal storage. If not initialized, 0 is returned.
- * */
- virtual uint64_t size() const noexcept = 0;
- };
-
- /**
- * @brief Dynamic descriptor storage interface.
- * @details You may think of it as read+write access to some internal container.
- * */
- struct IDynamicDescriptorStorage
- : IStaticDescriptorStorage {
- /**
- * @brief Appends descriptor to internal storage.
- * If used on @see IDynamicIndex graph updates itself too.
- * @param [in] descriptor Ptr to created descriptor with correct length, version
- * and data.
- * @return ResultValue with error code and identification
- * of appended descriptor. Such identification might be used to query descriptor
- * with @see IStaticDescriptorStorage::descriptorByIndex or remove it from storage
- * with @see removeDescriptor.
- * @see IDescriptor, DescriptorId, ResultValue and FSDKError for details.
- * */
- virtual ResultValue<FSDKError, DescriptorId> appendDescriptor(
- const IDescriptor* descriptor) noexcept = 0;
-
- /**
- * @brief Appends batch of descriptors to internal storage.
- * If used on @see IDynamicIndex graph updates itself too.
- * @param [in] batch Batch of descriptors with correct length, version and data.
- * @return ResultValue with error code and identification
- * of the first appended descriptor. Other descriptors from batch are appended
- * sequentially in the same order as they are in the batch. Such identification
- * might be used to query descriptor with
- * @see IStaticDescriptorStorage::descriptorByIndex or remove it from storage
- * with @see removeDescriptor.
- * @see IDescriptorBatch, DescriptorId, ResultValue and FSDKError for details.
- * */
- virtual ResultValue<FSDKError, DescriptorId> appendBatch(
- const IDescriptorBatch* batch) noexcept = 0;
-
- /**
- * @brief Removes descriptor out of internal storage.
- * If used on @see IDynamicIndex graph updates itself too.
- * @note IMPORTANT: If used on @see IDynamicIndex it will NOT actually erase
- * descriptor with given index out of internal storage. Instead, it will
- * remove it out of graph, so it is not searchable.
- * @note If used on @see IIndexBuilder, it WILL actually erase it. But beware:
- * if your storage is big enough performance might be very poor, because
- * descriptors are stored sequentially in vector-like data structure, so every
- * element after erased will be moved.
- * @param [in] index Identification of descriptors position in internal storage.
- * Is received by using append methods or @IIndex::search.
- * @return Result with error code.
- * @see DescriptorId, Result and FSDKError for details.
- * */
- virtual Result<FSDKError> removeDescriptor(const DescriptorId index) noexcept = 0;
- };
-
- /**
- * @brief Base index interface.
- * @details You may think of index as some data structure optimized for search queries.
- * */
- struct IIndex
- : IRefCounted {
- /**
- * @brief Search for descriptors with the shorter distance to passed descriptor.
- * @param [in] reference Descriptor to match against index.
- * @param [in] maxResultsCount Maximum count of results. It is upper bound value, it
- * does not guarantee to return exactly this amount of results.
- * @param [out] results C-Array of at least @see maxResultsCount size. Is filled with
- * query results.
- * @return ResultValue with error code and count of found descriptors.
- * @see IDescriptor, SearchResult, ResultValue and FSDKError for details.
- * */
- virtual ResultValue<FSDKError, int> search(
- const IDescriptor* reference,
- int maxResultsCount,
- SearchResult* results) const noexcept = 0;
- };
-
- /**
- * @brief Dense (read only) index interface.
- * */
- struct IDenseIndex
- : IStaticDescriptorStorage
- , IIndex {
-
- };
-
- /**
- * @brief Dynamic index interface.
- * */
- struct IDynamicIndex
- : IDynamicDescriptorStorage
- , IIndex {
- /**
- * @brief Saves index as dense.
- * @details To load saved index use @see IFaceEngine::loadDenseIndex method.
- * Dense index cannot be loaded as dynamic.
- * @param [in] path Path to file to be created and filled with index data. Any
- * extension is acceptable.
- * @return Result with error code.
- * @see Result and FSDKError for details.
- * */
- virtual Result<FSDKError> saveToDenseIndex(const char* path) const noexcept = 0;
-
- /**
- * @brief Saves index as dynamic.
- * @details To load saved index use @see IFaceEngine::loadDynamicIndex method.
- * Dynamic index cannot be loaded as dense.
- * @param [in] path Path to file to be created and filled with index data. Any
- * extension is acceptable.
- * @return Result with error code.
- * @see Result and FSDKError for details.
- * */
- virtual Result<FSDKError> saveToDynamicIndex(const char* path) const noexcept = 0;
-
- /**
- * @brief Returns count of indexed descriptors.
- * @details You may wonder why this method exists if IDynamicIndex already
- * inherits IStaticDescriptorStorage::size method. The reason is that
- * @see IDynamicDescriptorStorage::removeDescriptor behaves differently on
- * @see IIndexBuild and IDynamicIndex. On builder it does actually erases
- * descriptor out of internal storage, but it does not erase it if used on
- * IDynamicIndex. The reason is that graph data structure relies on indexes
- * being constant, so removeDescriptor only removes it out of graph, so it is not
- * discoverable by @see IIndex::search. So this methods returns actuall data
- * storage size minus count of removed descriptors.
- * @return Count of indexed descriptors.
- * */
- virtual uint64_t countOfIndexedDescriptors() const noexcept = 0;
- };
-
- /**
- * @brief Progress tracker interface.
- * @details Implement this interface to be able to get progress info on some operation.
- * */
- struct IProgressTracker {
- /**
- * @brief Function is called on some operation progress change.
- * @param [in] completion float value in [0..1] range.
- * */
- virtual void progress(const float completion) const noexcept = 0;
- };
-
- /**
- * @brief Index builder interface.
- * */
- struct IIndexBuilder
- : IDynamicDescriptorStorage
- , IRefCounted {
- /**
- * @brief Builds index with every descriptor appended. Blocks until completed.
- * @details Is very heavy method in terms of computing load.
- * @param [in] progressTracker Some object that is being reported to with progress.
- * If its nullptr, dont report progress.
- * @return ResultValue with error code and created index object.
- * @see IProgressTracker, IDynamicIndex, ResultValue and FSDKError for details.
- * */
- virtual ResultValue<FSDKError, IDynamicIndex*> buildIndex(
- const IProgressTracker* const progressTracker = nullptr) noexcept = 0;
-
- /**
- * @brief Builds index with every descriptor appended. Non blocking operation.
- * @details Is very heavy method in terms of computing load.
- * @param [in] asyncContext Asynchronous context to run build on.
- * @param [in] progressTracker Some object that is being reported to with progress.
- * If its nullptr, dont report progress.
- * @return ResultValue with error code and created index object.
- * @see IAsyncContext, IProgressTracker, Future, IDynamicIndex, ResultValue and FSDKError for details.
- * */
- virtual ResultValue<FSDKError, Future<ResultValue<FSDKError, IDynamicIndex*>>>
- buildIndexAsync(
- IAsyncContext* const asyncContext,
- const IProgressTracker* const progressTracker = nullptr) noexcept = 0;
- };
-
-
- }
-
|