diff options
author | Sebastian Schmidt <mrschmidt@google.com> | 2018-06-12 10:58:35 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-12 10:58:35 -0700 |
commit | afea8d5aacf474b57b4364feda08be9ca195594b (patch) | |
tree | d43c39ae9f71e88d256012f4467cd2b707fc7ddd /Firestore/Source/Remote/FSTRemoteEvent.h | |
parent | 0db8ef7dbe6c8c191252d33090dbb88b98735148 (diff) |
Refactor Remote Event (#1396)
Diffstat (limited to 'Firestore/Source/Remote/FSTRemoteEvent.h')
-rw-r--r-- | Firestore/Source/Remote/FSTRemoteEvent.h | 199 |
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 |