aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Source/Remote/FSTRemoteEvent.h
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/Source/Remote/FSTRemoteEvent.h')
-rw-r--r--Firestore/Source/Remote/FSTRemoteEvent.h199
1 files changed, 81 insertions, 118 deletions
diff --git a/Firestore/Source/Remote/FSTRemoteEvent.h b/Firestore/Source/Remote/FSTRemoteEvent.h
index c84e34d..9ea0f9c 100644
--- a/Firestore/Source/Remote/FSTRemoteEvent.h
+++ b/Firestore/Source/Remote/FSTRemoteEvent.h
@@ -17,6 +17,9 @@
#import <Foundation/Foundation.h>
#include <map>
+#include <set>
+#include <unordered_map>
+#include <unordered_set>
#import "Firestore/Source/Core/FSTTypes.h"
#import "Firestore/Source/Model/FSTDocumentDictionary.h"
@@ -30,128 +33,82 @@
@class FSTMaybeDocument;
@class FSTWatchChange;
@class FSTQueryData;
+@class FSTDocumentWatchChange;
+@class FSTWatchTargetChange;
+@class FSTExistenceFilterWatchChange;
NS_ASSUME_NONNULL_BEGIN
-#pragma mark - FSTTargetMapping
-
-/**
- * TargetMapping represents a change to the documents in a query from the server. This can either
- * be an incremental Update or a full Reset.
- *
- * <p>This is an empty abstract class so that all the different kinds of changes can have a common
- * base class.
- */
-@interface FSTTargetMapping : NSObject
-
-/**
- * Strips out mapping changes that aren't actually changes. That is, if the document already
- * existed in the target, and is being added in the target, and this is not a reset, we can
- * skip doing the work to associate the document with the target because it has already been done.
- */
-- (void)filterUpdatesUsingExistingKeys:
- (const firebase::firestore::model::DocumentKeySet &)existingKeys;
-
-@end
-
-#pragma mark - FSTResetMapping
-
-/** The new set of documents to replace the current documents for a target. */
-@interface FSTResetMapping : FSTTargetMapping
-
/**
- * Creates a new mapping with the keys for the given documents added. This is intended primarily
- * for testing.
+ * Interface implemented by RemoteStore to expose target metadata to the FSTWatchChangeAggregator.
*/
-+ (FSTResetMapping *)mappingWithDocuments:(NSArray<FSTDocument *> *)documents;
-
-/** The new set of documents for the target. */
-- (const firebase::firestore::model::DocumentKeySet &)documents;
-@end
-
-#pragma mark - FSTUpdateMapping
+@protocol FSTTargetMetadataProvider
/**
- * A target should update its set of documents with the given added/removed set of documents.
+ * Returns the set of remote document keys for the given target ID as of the last raised snapshot.
*/
-@interface FSTUpdateMapping : FSTTargetMapping
+- (firebase::firestore::model::DocumentKeySet)remoteKeysForTarget:(FSTBoxedTargetID *)targetID;
/**
- * Creates a new mapping with the keys for the given documents added. This is intended primarily
- * for testing.
+ * Returns the FSTQueryData for an active target ID or 'null' if this query has become inactive
*/
-+ (FSTUpdateMapping *)mappingWithAddedDocuments:(NSArray<FSTDocument *> *)added
- removedDocuments:(NSArray<FSTDocument *> *)removed;
+- (nullable FSTQueryData *)queryDataForTarget:(FSTBoxedTargetID *)targetID;
-- (firebase::firestore::model::DocumentKeySet)applyTo:
- (const firebase::firestore::model::DocumentKeySet &)keys;
-
-/** The documents added to the target. */
-- (const firebase::firestore::model::DocumentKeySet &)addedDocuments;
-/** The documents removed from the target. */
-- (const firebase::firestore::model::DocumentKeySet &)removedDocuments;
@end
#pragma mark - FSTTargetChange
/**
- * Represents an update to the current status of a target, either explicitly having no new state, or
- * the new value to set. Note "current" has special meaning in the RPC protocol that implies that a
- * target is both up-to-date and consistent with the rest of the watch stream.
- */
-typedef NS_ENUM(NSUInteger, FSTCurrentStatusUpdate) {
- /** The current status is not affected and should not be modified */
- FSTCurrentStatusUpdateNone,
- /** The target must be marked as no longer "current" */
- FSTCurrentStatusUpdateMarkNotCurrent,
- /** The target must be marked as "current" */
- FSTCurrentStatusUpdateMarkCurrent,
-};
-
-/**
- * A part of an FSTRemoteEvent specifying set of changes to a specific target. These changes track
- * what documents are currently included in the target as well as the current snapshot version and
- * resume token but the actual changes *to* documents are not part of the FSTTargetChange since
- * documents may be part of multiple targets.
+ * An FSTTargetChange specifies the set of changes for a specific target as part of an
+ * FSTRemoteEvent. These changes track which documents are added, modified or emoved, as well as the
+ * target's resume token and whether the target is marked CURRENT.
+ *
+ * The actual changes *to* documents are not part of the FSTTargetChange since documents may be part
+ * of multiple targets.
*/
@interface FSTTargetChange : NSObject
/**
* Creates a new target change with the given SnapshotVersion.
*/
-- (instancetype)initWithSnapshotVersion:
- (firebase::firestore::model::SnapshotVersion)snapshotVersion;
+- (instancetype)initWithResumeToken:(NSData *)resumeToken
+ current:(BOOL)current
+ addedDocuments:(firebase::firestore::model::DocumentKeySet)addedDocuments
+ modifiedDocuments:(firebase::firestore::model::DocumentKeySet)modifiedDocuments
+ removedDocuments:(firebase::firestore::model::DocumentKeySet)removedDocuments
+ NS_DESIGNATED_INITIALIZER;
+
+- (instancetype)init NS_UNAVAILABLE;
/**
- * Creates a new target change with the given documents. Instances of FSTDocument are considered
- * added. Instance of FSTDeletedDocument are considered removed. This is intended primarily for
- * testing.
+ * An opaque, server-assigned token that allows watching a query to be resumed after
+ * disconnecting without retransmitting all the data that matches the query. The resume token
+ * essentially identifies a point in time from which the server should resume sending results.
*/
-+ (instancetype)changeWithDocuments:(NSArray<FSTMaybeDocument *> *)docs
- currentStatusUpdate:(FSTCurrentStatusUpdate)currentStatusUpdate;
+@property(nonatomic, strong, readonly) NSData *resumeToken;
/**
- * The snapshot version representing the last state at which this target received a consistent
- * snapshot from the backend.
+ * The "current" (synced) status of this target. Note that "current" has special meaning in the RPC
+ * protocol that implies that a target is both up-to-date and consistent with the rest of the watch
+ * stream.
*/
-- (const firebase::firestore::model::SnapshotVersion &)snapshotVersion;
+@property(nonatomic, assign, readonly) BOOL current;
/**
- * The new "current" (synced) status of this target. Set to CurrentStatusUpdateNone if the status
- * should not be updated. Note "current" has special meaning for in the RPC protocol that implies
- * that a target is both up-to-date and consistent with the rest of the watch stream.
+ * The set of documents that were newly assigned to this target as part of this remote event.
*/
-@property(nonatomic, assign, readonly) FSTCurrentStatusUpdate currentStatusUpdate;
+- (const firebase::firestore::model::DocumentKeySet &)addedDocuments;
-/** A set of changes to documents in this target. */
-@property(nonatomic, strong, readonly) FSTTargetMapping *mapping;
+/**
+ * The set of documents that were already assigned to this target but received an update during this
+ * remote event.
+ */
+- (const firebase::firestore::model::DocumentKeySet &)modifiedDocuments;
/**
- * An opaque, server-assigned token that allows watching a query to be resumed after disconnecting
- * without retransmitting all the data that matches the query. The resume token essentially
- * identifies a point in time from which the server should resume sending results.
+ * The set of documents that were removed from this target as part of this remote event.
*/
-@property(nonatomic, strong, readonly) NSData *resumeToken;
+- (const firebase::firestore::model::DocumentKeySet &)removedDocuments;
@end
@@ -165,34 +122,38 @@ typedef NS_ENUM(NSUInteger, FSTCurrentStatusUpdate) {
- (instancetype)
initWithSnapshotVersion:(firebase::firestore::model::SnapshotVersion)snapshotVersion
- targetChanges:(NSMutableDictionary<NSNumber *, FSTTargetChange *> *)targetChanges
+ targetChanges:(std::unordered_map<FSTTargetID, FSTTargetChange *>)targetChanges
+ targetMismatches:(std::unordered_set<FSTTargetID>)targetMismatches
documentUpdates:
- (std::map<firebase::firestore::model::DocumentKey, FSTMaybeDocument *>)documentUpdates
+ (std::unordered_map<firebase::firestore::model::DocumentKey,
+ FSTMaybeDocument *,
+ firebase::firestore::model::DocumentKeyHash>)documentUpdates
limboDocuments:(firebase::firestore::model::DocumentKeySet)limboDocuments;
/** The snapshot version this event brings us up to. */
- (const firebase::firestore::model::SnapshotVersion &)snapshotVersion;
-/** A map from target to changes to the target. See TargetChange. */
-@property(nonatomic, strong, readonly)
- NSDictionary<FSTBoxedTargetID *, FSTTargetChange *> *targetChanges;
-
/**
- * A set of which documents have changed or been deleted, along with the doc's new values
- * (if not deleted).
+ * A set of which document updates are due only to limbo resolution targets.
*/
-- (const std::map<firebase::firestore::model::DocumentKey, FSTMaybeDocument *> &)documentUpdates;
-
- (const firebase::firestore::model::DocumentKeySet &)limboDocumentChanges;
-/** Adds a document update to this remote event */
-- (void)addDocumentUpdate:(FSTMaybeDocument *)document;
+/** A map from target to changes to the target. See TargetChange. */
+- (const std::unordered_map<FSTTargetID, FSTTargetChange *> &)targetChanges;
-/** Handles an existence filter mismatch */
-- (void)handleExistenceFilterMismatchForTargetID:(FSTBoxedTargetID *)targetID;
+/**
+ * A set of targets that is known to be inconsistent. Listens for these targets should be
+ * re-established without resume tokens.
+ */
+- (const std::unordered_set<FSTTargetID> &)targetMismatches;
-- (void)synthesizeDeleteForLimboTargetChange:(FSTTargetChange *)targetChange
- key:(const firebase::firestore::model::DocumentKey &)key;
+/**
+ * A set of which documents have changed or been deleted, along with the doc's new values (if not
+ * deleted).
+ */
+- (const std::unordered_map<firebase::firestore::model::DocumentKey,
+ FSTMaybeDocument *,
+ firebase::firestore::model::DocumentKeyHash> &)documentUpdates;
@end
@@ -204,33 +165,35 @@ initWithSnapshotVersion:(firebase::firestore::model::SnapshotVersion)snapshotVer
*/
@interface FSTWatchChangeAggregator : NSObject
-- (instancetype)
-initWithSnapshotVersion:(firebase::firestore::model::SnapshotVersion)snapshotVersion
- listenTargets:(NSDictionary<FSTBoxedTargetID *, FSTQueryData *> *)listenTargets
- pendingTargetResponses:(NSDictionary<FSTBoxedTargetID *, NSNumber *> *)pendingTargetResponses
+- (instancetype)initWithTargetMetadataProvider:(id<FSTTargetMetadataProvider>)targetMetadataProvider
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
-/** The number of pending responses that are being waited on from watch */
-@property(nonatomic, strong, readonly)
- NSMutableDictionary<FSTBoxedTargetID *, NSNumber *> *pendingTargetResponses;
+/** Processes and adds the FSTDocumentWatchChange to the current set of changes. */
+- (void)handleDocumentChange:(FSTDocumentWatchChange *)documentChange;
-/** Aggregates a watch change into the current state */
-- (void)addWatchChange:(FSTWatchChange *)watchChange;
+/** Processes and adds the WatchTargetChange to the current set of changes. */
+- (void)handleTargetChange:(FSTWatchTargetChange *)targetChange;
-/** Aggregates all provided watch changes to the current state in order */
-- (void)addWatchChanges:(NSArray<FSTWatchChange *> *)watchChanges;
+/**
+ * Handles existence filters and synthesizes deletes for filter mismatches. Targets that are
+ * invalidated by filter mismatches are added to `targetMismatches`.
+ */
+- (void)handleExistenceFilter:(FSTExistenceFilterWatchChange *)existenceFilter;
+
+/**
+ * Increment the number of acks needed from watch before we can consider the server to be 'in-sync'
+ * with the client's active targets.
+ */
+- (void)recordTargetRequest:(FSTBoxedTargetID *)targetID;
/**
* Converts the current state into a remote event with the snapshot version taken from the
* initializer.
*/
-- (FSTRemoteEvent *)remoteEvent;
-
-/** The existence filters - if any - for the given target IDs. */
-@property(nonatomic, strong, readonly)
- NSDictionary<FSTBoxedTargetID *, FSTExistenceFilter *> *existenceFilters;
+- (FSTRemoteEvent *)remoteEventAtSnapshotVersion:
+ (const firebase::firestore::model::SnapshotVersion &)snapshotVersion;
@end