persistence.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. * Copyright 2019 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef FIRESTORE_CORE_SRC_LOCAL_PERSISTENCE_H_
  17. #define FIRESTORE_CORE_SRC_LOCAL_PERSISTENCE_H_
  18. #include <functional>
  19. #include <string>
  20. #include <utility>
  21. #include "Firestore/core/src/model/types.h"
  22. #include "absl/strings/string_view.h"
  23. namespace firebase {
  24. namespace firestore {
  25. namespace credentials {
  26. class User;
  27. } // namespace credentials
  28. namespace local {
  29. class BundleCache;
  30. class DocumentOverlayCache;
  31. class IndexManager;
  32. class MutationQueue;
  33. class OverlayMigrationManager;
  34. class ReferenceDelegate;
  35. class RemoteDocumentCache;
  36. class TargetCache;
  37. /**
  38. * Persistence is the lowest-level shared interface to data storage in
  39. * Firestore.
  40. *
  41. * Persistence creates MutationQueue and RemoteDocumentCache instances backed
  42. * by some underlying storage mechanism (which might be in-memory or LevelDB).
  43. *
  44. * Persistence also exposes an API to run transactions against the backing
  45. * store. All read and write operations must be wrapped in a transaction.
  46. * Implementations of Persistence only need to guarantee that writes made
  47. * against the transaction are not made to durable storage until the transaction
  48. * commits. Since memory-only storage components do not alter durable storage,
  49. * they are free to ignore the transaction.
  50. *
  51. * This contract is enough to allow the LocalStore to be written independently
  52. * of whether or not the stored state actually is durably persisted. If a user
  53. * enables persistent storage, writes are grouped together to avoid inconsistent
  54. * state that could cause crashes.
  55. *
  56. * Concretely, when persistent storage is enabled, the durable versions of
  57. * MutationQueue, RemoteDocumentCache, and others (the mutators) will group
  58. * their writes in a transaction. Once the local store has completed one logical
  59. * operation, it commits the transaction.
  60. *
  61. * When persistent storage is disabled, the non-durable versions of the mutators
  62. * ignore the transaction. This short-cut is allowed because memory-only storage
  63. * leaves no state so it cannot be inconsistent.
  64. *
  65. * This simplifies the implementations of the mutators and allows memory-only
  66. * implementations to supplement the durable ones without requiring any special
  67. * dual-store implementation of Persistence. The cost is that LocalStore needs
  68. * to be slightly careful about the order of its reads and writes in order to
  69. * avoid relying on being able to read back uncommitted writes.
  70. */
  71. class Persistence {
  72. public:
  73. virtual ~Persistence() = default;
  74. virtual model::ListenSequenceNumber current_sequence_number() const = 0;
  75. /** Releases any resources held during eager shutdown. */
  76. virtual void Shutdown() = 0;
  77. /**
  78. * Returns a MutationQueue representing the persisted mutations for the given
  79. * user.
  80. *
  81. * Note: The implementation is free to return the same instance every time
  82. * this is called for a given user. In particular, the memory-backed
  83. * implementation does this to emulate the persisted implementation to the
  84. * extent possible (e.g. in the case of UID switching from sally=>jack=>sally,
  85. * sally's mutation queue will be preserved).
  86. */
  87. virtual MutationQueue* GetMutationQueue(const credentials::User& user,
  88. IndexManager* index_manager) = 0;
  89. /** Returns a TargetCache representing the persisted cache of queries. */
  90. virtual TargetCache* target_cache() = 0;
  91. /**
  92. * Returns a BundleCache representing the persisted cache of loaded bundles.
  93. */
  94. virtual BundleCache* bundle_cache() = 0;
  95. /**
  96. * Returns a DocumentOverlayCache representing the documents that are mutated
  97. * locally.
  98. *
  99. * Note: The implementation is free to return the same instance every time
  100. * this is called for a given user. In particular, the memory-backed
  101. * implementation does this to emulate the persisted implementation to the
  102. * extent possible (e.g. in the case of UID switching from sally=>jack=>sally,
  103. * sally's document overlay cache will be preserved).
  104. */
  105. virtual DocumentOverlayCache* GetDocumentOverlayCache(
  106. const credentials::User& user) = 0;
  107. /**
  108. * Returns the migration manager responsible for calculating and saving
  109. * overlays.
  110. */
  111. virtual OverlayMigrationManager* GetOverlayMigrationManager(
  112. const credentials::User& user) = 0;
  113. /**
  114. * Returns a RemoteDocumentCache representing the persisted cache of remote
  115. * documents.
  116. */
  117. virtual RemoteDocumentCache* remote_document_cache() = 0;
  118. /** Returns an IndexManager that manages our persisted query indexes. */
  119. virtual IndexManager* GetIndexManager(const credentials::User& user) = 0;
  120. /**
  121. * This property provides access to hooks around the document reference
  122. * lifecycle.
  123. */
  124. virtual ReferenceDelegate* reference_delegate() = 0;
  125. /**
  126. * Releases components that are created for users other than `target_uid`.
  127. *
  128. * This should be invoked after LocalStore initialization which might create
  129. * components for all users in the cache, or after LocalStore switches to
  130. * a new user with `target_uid`.
  131. */
  132. virtual void ReleaseOtherUserSpecificComponents(
  133. const std::string& target_uid) = 0;
  134. /**
  135. * Accepts a function and runs it within a transaction. When called, a
  136. * transaction will be started before a block is run, and committed after the
  137. * block has executed.
  138. *
  139. * @param label A semi-unique name for the transaction, for logging.
  140. * @param block A void-returning function to be executed within the
  141. * transaction.
  142. */
  143. template <typename F>
  144. auto Run(absl::string_view label, F block) ->
  145. typename std::enable_if<std::is_same<void, decltype(block())>::value,
  146. void>::type {
  147. RunInternal(label, std::forward<F>(block));
  148. }
  149. /**
  150. * Accepts a function and runs it within a transaction. When called, a
  151. * transaction will be started before a block is run, and committed after the
  152. * block has executed.
  153. *
  154. * @param label A semi-unique name for the transaction, for logging.
  155. * @param block A function to be executed within the transaction whose return
  156. * value will be the result of the transaction. The type of the return
  157. * value must be default constructible and copy- or move-assignable.
  158. * @return The value returned from the invocation of `block`.
  159. */
  160. template <typename F>
  161. auto Run(absl::string_view label, F block) ->
  162. typename std::enable_if<!std::is_same<void, decltype(block())>::value,
  163. decltype(block())>::type {
  164. decltype(block()) result;
  165. RunInternal(label, [&]() mutable { result = block(); });
  166. return result;
  167. }
  168. private:
  169. virtual void RunInternal(absl::string_view label,
  170. std::function<void()> block) = 0;
  171. /**
  172. * Removes all persistent cache indexes. This feature is implemented in
  173. * `Persistence` instead of `IndexManager` like other SDKs. The reason for
  174. * that is the total operation of `DeleteAllIndexes` may exceed maximum
  175. * operation per transaction. So the SDK needs more than one transaction to
  176. * execute the task, while all functions in `IndexManager` can be carried out
  177. * in one transaction.
  178. */
  179. virtual void DeleteAllFieldIndexes() = 0;
  180. };
  181. } // namespace local
  182. } // namespace firestore
  183. } // namespace firebase
  184. #endif // FIRESTORE_CORE_SRC_LOCAL_PERSISTENCE_H_