| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- /*
- * Copyright 2019 Google
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifndef FIRESTORE_CORE_SRC_LOCAL_PERSISTENCE_H_
- #define FIRESTORE_CORE_SRC_LOCAL_PERSISTENCE_H_
- #include <functional>
- #include <string>
- #include <utility>
- #include "Firestore/core/src/model/types.h"
- #include "absl/strings/string_view.h"
- namespace firebase {
- namespace firestore {
- namespace credentials {
- class User;
- } // namespace credentials
- namespace local {
- class BundleCache;
- class DocumentOverlayCache;
- class IndexManager;
- class MutationQueue;
- class OverlayMigrationManager;
- class ReferenceDelegate;
- class RemoteDocumentCache;
- class TargetCache;
- /**
- * Persistence is the lowest-level shared interface to data storage in
- * Firestore.
- *
- * Persistence creates MutationQueue and RemoteDocumentCache instances backed
- * by some underlying storage mechanism (which might be in-memory or LevelDB).
- *
- * Persistence also exposes an API to run transactions against the backing
- * store. All read and write operations must be wrapped in a transaction.
- * Implementations of Persistence only need to guarantee that writes made
- * against the transaction are not made to durable storage until the transaction
- * commits. Since memory-only storage components do not alter durable storage,
- * they are free to ignore the transaction.
- *
- * This contract is enough to allow the LocalStore to be written independently
- * of whether or not the stored state actually is durably persisted. If a user
- * enables persistent storage, writes are grouped together to avoid inconsistent
- * state that could cause crashes.
- *
- * Concretely, when persistent storage is enabled, the durable versions of
- * MutationQueue, RemoteDocumentCache, and others (the mutators) will group
- * their writes in a transaction. Once the local store has completed one logical
- * operation, it commits the transaction.
- *
- * When persistent storage is disabled, the non-durable versions of the mutators
- * ignore the transaction. This short-cut is allowed because memory-only storage
- * leaves no state so it cannot be inconsistent.
- *
- * This simplifies the implementations of the mutators and allows memory-only
- * implementations to supplement the durable ones without requiring any special
- * dual-store implementation of Persistence. The cost is that LocalStore needs
- * to be slightly careful about the order of its reads and writes in order to
- * avoid relying on being able to read back uncommitted writes.
- */
- class Persistence {
- public:
- virtual ~Persistence() = default;
- virtual model::ListenSequenceNumber current_sequence_number() const = 0;
- /** Releases any resources held during eager shutdown. */
- virtual void Shutdown() = 0;
- /**
- * Returns a MutationQueue representing the persisted mutations for the given
- * user.
- *
- * Note: The implementation is free to return the same instance every time
- * this is called for a given user. In particular, the memory-backed
- * implementation does this to emulate the persisted implementation to the
- * extent possible (e.g. in the case of UID switching from sally=>jack=>sally,
- * sally's mutation queue will be preserved).
- */
- virtual MutationQueue* GetMutationQueue(const credentials::User& user,
- IndexManager* index_manager) = 0;
- /** Returns a TargetCache representing the persisted cache of queries. */
- virtual TargetCache* target_cache() = 0;
- /**
- * Returns a BundleCache representing the persisted cache of loaded bundles.
- */
- virtual BundleCache* bundle_cache() = 0;
- /**
- * Returns a DocumentOverlayCache representing the documents that are mutated
- * locally.
- *
- * Note: The implementation is free to return the same instance every time
- * this is called for a given user. In particular, the memory-backed
- * implementation does this to emulate the persisted implementation to the
- * extent possible (e.g. in the case of UID switching from sally=>jack=>sally,
- * sally's document overlay cache will be preserved).
- */
- virtual DocumentOverlayCache* GetDocumentOverlayCache(
- const credentials::User& user) = 0;
- /**
- * Returns the migration manager responsible for calculating and saving
- * overlays.
- */
- virtual OverlayMigrationManager* GetOverlayMigrationManager(
- const credentials::User& user) = 0;
- /**
- * Returns a RemoteDocumentCache representing the persisted cache of remote
- * documents.
- */
- virtual RemoteDocumentCache* remote_document_cache() = 0;
- /** Returns an IndexManager that manages our persisted query indexes. */
- virtual IndexManager* GetIndexManager(const credentials::User& user) = 0;
- /**
- * This property provides access to hooks around the document reference
- * lifecycle.
- */
- virtual ReferenceDelegate* reference_delegate() = 0;
- /**
- * Releases components that are created for users other than `target_uid`.
- *
- * This should be invoked after LocalStore initialization which might create
- * components for all users in the cache, or after LocalStore switches to
- * a new user with `target_uid`.
- */
- virtual void ReleaseOtherUserSpecificComponents(
- const std::string& target_uid) = 0;
- /**
- * Accepts a function and runs it within a transaction. When called, a
- * transaction will be started before a block is run, and committed after the
- * block has executed.
- *
- * @param label A semi-unique name for the transaction, for logging.
- * @param block A void-returning function to be executed within the
- * transaction.
- */
- template <typename F>
- auto Run(absl::string_view label, F block) ->
- typename std::enable_if<std::is_same<void, decltype(block())>::value,
- void>::type {
- RunInternal(label, std::forward<F>(block));
- }
- /**
- * Accepts a function and runs it within a transaction. When called, a
- * transaction will be started before a block is run, and committed after the
- * block has executed.
- *
- * @param label A semi-unique name for the transaction, for logging.
- * @param block A function to be executed within the transaction whose return
- * value will be the result of the transaction. The type of the return
- * value must be default constructible and copy- or move-assignable.
- * @return The value returned from the invocation of `block`.
- */
- template <typename F>
- auto Run(absl::string_view label, F block) ->
- typename std::enable_if<!std::is_same<void, decltype(block())>::value,
- decltype(block())>::type {
- decltype(block()) result;
- RunInternal(label, [&]() mutable { result = block(); });
- return result;
- }
- private:
- virtual void RunInternal(absl::string_view label,
- std::function<void()> block) = 0;
- /**
- * Removes all persistent cache indexes. This feature is implemented in
- * `Persistence` instead of `IndexManager` like other SDKs. The reason for
- * that is the total operation of `DeleteAllIndexes` may exceed maximum
- * operation per transaction. So the SDK needs more than one transaction to
- * execute the task, while all functions in `IndexManager` can be carried out
- * in one transaction.
- */
- virtual void DeleteAllFieldIndexes() = 0;
- };
- } // namespace local
- } // namespace firestore
- } // namespace firebase
- #endif // FIRESTORE_CORE_SRC_LOCAL_PERSISTENCE_H_
|