aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Source/Local
diff options
context:
space:
mode:
authorGravatar Greg Soltis <gsoltis@google.com>2018-03-30 10:18:25 -0700
committerGravatar GitHub <noreply@github.com>2018-03-30 10:18:25 -0700
commit3f36f5467de4c191fa2903743e5a210420e9d49a (patch)
treee73fa2cd4fa299d6220e4ab04daab515ceeca89a /Firestore/Source/Local
parentea490a2c6492e41e892397e044477f778ce358b8 (diff)
Drop FSTWriteGroup (#986)
* Drop write group from remote document change buffer * Unwind some group dependendencies in local store * Write group dropped from local store * Drop write group from mutation queue tests * Drop write group usage from query cache tests * Drop write groups from remote document cache tests * Drop write groups from remote document change buffer tests * Drop write groups and the write group tracker * Style * Put the action in transaction * Merge master, fix test * Fix some compiler warnings but mostly trigger travis * Responses to feedback
Diffstat (limited to 'Firestore/Source/Local')
-rw-r--r--Firestore/Source/Local/FSTLevelDB.mm23
-rw-r--r--Firestore/Source/Local/FSTLocalStore.mm472
-rw-r--r--Firestore/Source/Local/FSTMemoryPersistence.mm14
-rw-r--r--Firestore/Source/Local/FSTPersistence.h26
-rw-r--r--Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.h6
-rw-r--r--Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.mm2
-rw-r--r--Firestore/Source/Local/FSTWriteGroup.h89
-rw-r--r--Firestore/Source/Local/FSTWriteGroup.mm96
-rw-r--r--Firestore/Source/Local/FSTWriteGroupTracker.h50
-rw-r--r--Firestore/Source/Local/FSTWriteGroupTracker.mm63
10 files changed, 237 insertions, 604 deletions
diff --git a/Firestore/Source/Local/FSTLevelDB.mm b/Firestore/Source/Local/FSTLevelDB.mm
index 922c5b4..4812228 100644
--- a/Firestore/Source/Local/FSTLevelDB.mm
+++ b/Firestore/Source/Local/FSTLevelDB.mm
@@ -23,8 +23,6 @@
#import "Firestore/Source/Local/FSTLevelDBMutationQueue.h"
#import "Firestore/Source/Local/FSTLevelDBQueryCache.h"
#import "Firestore/Source/Local/FSTLevelDBRemoteDocumentCache.h"
-#import "Firestore/Source/Local/FSTWriteGroup.h"
-#import "Firestore/Source/Local/FSTWriteGroupTracker.h"
#import "Firestore/Source/Remote/FSTSerializerBeta.h"
#import "Firestore/Source/Util/FSTAssert.h"
#import "Firestore/Source/Util/FSTLogger.h"
@@ -55,7 +53,6 @@ using leveldb::WriteOptions;
@interface FSTLevelDB ()
@property(nonatomic, copy) NSString *directory;
-@property(nonatomic, strong) FSTWriteGroupTracker *writeGroupTracker;
@property(nonatomic, assign, getter=isStarted) BOOL started;
@property(nonatomic, strong, readonly) FSTLocalSerializer *serializer;
@@ -79,7 +76,6 @@ using leveldb::WriteOptions;
serializer:(FSTLocalSerializer *)serializer {
if (self = [super init]) {
_directory = [directory copy];
- _writeGroupTracker = [FSTWriteGroupTracker tracker];
_serializer = serializer;
_transactionRunner.SetBackingPersistence(self);
}
@@ -148,7 +144,7 @@ using leveldb::WriteOptions;
return NO;
}
_ptr.reset(database);
- LevelDbTransaction transaction(_ptr.get());
+ LevelDbTransaction transaction(_ptr.get(), "Start LevelDB");
[FSTLevelDBMigrations runMigrationsWithTransaction:&transaction];
transaction.Commit();
return YES;
@@ -229,9 +225,9 @@ using leveldb::WriteOptions;
return [[FSTLevelDBRemoteDocumentCache alloc] initWithDB:self serializer:self.serializer];
}
-- (void)startTransaction {
+- (void)startTransaction:(absl::string_view)label {
FSTAssert(_transaction == nullptr, @"Starting a transaction while one is already outstanding");
- _transaction = absl::make_unique<LevelDbTransaction>(_ptr.get());
+ _transaction = absl::make_unique<LevelDbTransaction>(_ptr.get(), label);
}
- (void)commitTransaction {
@@ -240,19 +236,6 @@ using leveldb::WriteOptions;
_transaction.reset();
}
-- (FSTWriteGroup *)startGroupWithAction:(NSString *)action {
- FSTAssert(_transaction == nullptr, @"Starting a transaction while one is already outstanding");
- _transaction = absl::make_unique<LevelDbTransaction>(_ptr.get());
- return [self.writeGroupTracker startGroupWithAction:action transaction:_transaction.get()];
-}
-
-- (void)commitGroup:(FSTWriteGroup *)group {
- FSTAssert(_transaction != nullptr, @"Committing a transaction before one is started");
- [self.writeGroupTracker endGroup:group];
- _transaction->Commit();
- _transaction.reset();
-}
-
- (void)shutdown {
FSTAssert(self.isStarted, @"FSTLevelDB shutdown without start!");
self.started = NO;
diff --git a/Firestore/Source/Local/FSTLocalStore.mm b/Firestore/Source/Local/FSTLocalStore.mm
index 74eab48..412ade2 100644
--- a/Firestore/Source/Local/FSTLocalStore.mm
+++ b/Firestore/Source/Local/FSTLocalStore.mm
@@ -31,7 +31,6 @@
#import "Firestore/Source/Local/FSTReferenceSet.h"
#import "Firestore/Source/Local/FSTRemoteDocumentCache.h"
#import "Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.h"
-#import "Firestore/Source/Local/FSTWriteGroup.h"
#import "Firestore/Source/Model/FSTDocument.h"
#import "Firestore/Source/Model/FSTDocumentDictionary.h"
#import "Firestore/Source/Model/FSTMutation.h"
@@ -132,27 +131,27 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)startMutationQueue {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Start MutationQueue"];
- [self.mutationQueue start];
-
- // If we have any leftover mutation batch results from a prior run, just drop them.
- // TODO(http://b/33446471): We probably need to repopulate heldBatchResults or similar instead,
- // but that is not straightforward since we're not persisting the write ack versions.
- [self.heldBatchResults removeAllObjects];
-
- // TODO(mikelehen): This is the only usage of getAllMutationBatchesThroughBatchId:. Consider
- // removing it in favor of a getAcknowledgedBatches method.
- FSTBatchID highestAck = [self.mutationQueue highestAcknowledgedBatchID];
- if (highestAck != kFSTBatchIDUnknown) {
- NSArray<FSTMutationBatch *> *batches =
- [self.mutationQueue allMutationBatchesThroughBatchID:highestAck];
- if (batches.count > 0) {
- // NOTE: This could be more efficient if we had a removeBatchesThroughBatchID, but this set
- // should be very small and this code should go away eventually.
- [self.mutationQueue removeMutationBatches:batches];
+ self.persistence.run("Start MutationQueue", [&]() {
+ [self.mutationQueue start];
+
+ // If we have any leftover mutation batch results from a prior run, just drop them.
+ // TODO(http://b/33446471): We probably need to repopulate heldBatchResults or similar instead,
+ // but that is not straightforward since we're not persisting the write ack versions.
+ [self.heldBatchResults removeAllObjects];
+
+ // TODO(mikelehen): This is the only usage of getAllMutationBatchesThroughBatchId:. Consider
+ // removing it in favor of a getAcknowledgedBatches method.
+ FSTBatchID highestAck = [self.mutationQueue highestAcknowledgedBatchID];
+ if (highestAck != kFSTBatchIDUnknown) {
+ NSArray<FSTMutationBatch *> *batches =
+ [self.mutationQueue allMutationBatchesThroughBatchID:highestAck];
+ if (batches.count > 0) {
+ // NOTE: This could be more efficient if we had a removeBatchesThroughBatchID, but this set
+ // should be very small and this code should go away eventually.
+ [self.mutationQueue removeMutationBatches:batches];
+ }
}
- }
- [self.persistence commitGroup:group];
+ });
}
- (void)startQueryCache {
@@ -166,9 +165,9 @@ NS_ASSUME_NONNULL_BEGIN
- (FSTMaybeDocumentDictionary *)userDidChange:(const User &)user {
// Swap out the mutation queue, grabbing the pending mutation batches before and after.
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"OldBatches"];
- NSArray<FSTMutationBatch *> *oldBatches = [self.mutationQueue allMutationBatches];
- [self.persistence commitGroup:group];
+ NSArray<FSTMutationBatch *> *oldBatches = self.persistence.run(
+ "OldBatches",
+ [&]() -> NSArray<FSTMutationBatch *> * { return [self.mutationQueue allMutationBatches]; });
[self.garbageCollector removeGarbageSource:self.mutationQueue];
@@ -177,83 +176,79 @@ NS_ASSUME_NONNULL_BEGIN
[self startMutationQueue];
- group = [self.persistence startGroupWithAction:@"NewBatches"];
- NSArray<FSTMutationBatch *> *newBatches = [self.mutationQueue allMutationBatches];
-
- // Recreate our LocalDocumentsView using the new MutationQueue.
- self.localDocuments = [FSTLocalDocumentsView viewWithRemoteDocumentCache:self.remoteDocumentCache
- mutationQueue:self.mutationQueue];
-
- // Union the old/new changed keys.
- FSTDocumentKeySet *changedKeys = [FSTDocumentKeySet keySet];
- for (NSArray<FSTMutationBatch *> *batches in @[ oldBatches, newBatches ]) {
- for (FSTMutationBatch *batch in batches) {
- for (FSTMutation *mutation in batch.mutations) {
- changedKeys = [changedKeys setByAddingObject:mutation.key];
+ return self.persistence.run("NewBatches", [&]() -> FSTMaybeDocumentDictionary * {
+ NSArray<FSTMutationBatch *> *newBatches = [self.mutationQueue allMutationBatches];
+
+ // Recreate our LocalDocumentsView using the new MutationQueue.
+ self.localDocuments =
+ [FSTLocalDocumentsView viewWithRemoteDocumentCache:self.remoteDocumentCache
+ mutationQueue:self.mutationQueue];
+
+ // Union the old/new changed keys.
+ FSTDocumentKeySet *changedKeys = [FSTDocumentKeySet keySet];
+ for (NSArray<FSTMutationBatch *> *batches in @[ oldBatches, newBatches ]) {
+ for (FSTMutationBatch *batch in batches) {
+ for (FSTMutation *mutation in batch.mutations) {
+ changedKeys = [changedKeys setByAddingObject:mutation.key];
+ }
}
}
- }
- // Return the set of all (potentially) changed documents as the result of the user change.
- FSTMaybeDocumentDictionary *result = [self.localDocuments documentsForKeys:changedKeys];
- [self.persistence commitGroup:group];
- return result;
+ // Return the set of all (potentially) changed documents as the result of the user change.
+ return [self.localDocuments documentsForKeys:changedKeys];
+ });
}
- (FSTLocalWriteResult *)locallyWriteMutations:(NSArray<FSTMutation *> *)mutations {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Locally write mutations"];
- FIRTimestamp *localWriteTime = [FIRTimestamp timestamp];
- FSTMutationBatch *batch =
- [self.mutationQueue addMutationBatchWithWriteTime:localWriteTime mutations:mutations];
- FSTDocumentKeySet *keys = [batch keys];
- FSTMaybeDocumentDictionary *changedDocuments = [self.localDocuments documentsForKeys:keys];
- [self.persistence commitGroup:group];
- return [FSTLocalWriteResult resultForBatchID:batch.batchID changes:changedDocuments];
+ return self.persistence.run("Locally write mutations", [&]() -> FSTLocalWriteResult * {
+ FIRTimestamp *localWriteTime = [FIRTimestamp timestamp];
+ FSTMutationBatch *batch =
+ [self.mutationQueue addMutationBatchWithWriteTime:localWriteTime mutations:mutations];
+ FSTDocumentKeySet *keys = [batch keys];
+ FSTMaybeDocumentDictionary *changedDocuments = [self.localDocuments documentsForKeys:keys];
+ return [FSTLocalWriteResult resultForBatchID:batch.batchID changes:changedDocuments];
+ });
}
- (FSTMaybeDocumentDictionary *)acknowledgeBatchWithResult:(FSTMutationBatchResult *)batchResult {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Acknowledge batch"];
- id<FSTMutationQueue> mutationQueue = self.mutationQueue;
+ return self.persistence.run("Acknowledge batch", [&]() -> FSTMaybeDocumentDictionary * {
+ id<FSTMutationQueue> mutationQueue = self.mutationQueue;
- [mutationQueue acknowledgeBatch:batchResult.batch streamToken:batchResult.streamToken];
+ [mutationQueue acknowledgeBatch:batchResult.batch streamToken:batchResult.streamToken];
- FSTDocumentKeySet *affected;
- if ([self shouldHoldBatchResultWithVersion:batchResult.commitVersion]) {
- [self.heldBatchResults addObject:batchResult];
- affected = [FSTDocumentKeySet keySet];
- } else {
- FSTRemoteDocumentChangeBuffer *remoteDocuments =
- [FSTRemoteDocumentChangeBuffer changeBufferWithCache:self.remoteDocumentCache];
+ FSTDocumentKeySet *affected;
+ if ([self shouldHoldBatchResultWithVersion:batchResult.commitVersion]) {
+ [self.heldBatchResults addObject:batchResult];
+ affected = [FSTDocumentKeySet keySet];
+ } else {
+ FSTRemoteDocumentChangeBuffer *remoteDocuments =
+ [FSTRemoteDocumentChangeBuffer changeBufferWithCache:self.remoteDocumentCache];
- affected =
- [self releaseBatchResults:@[ batchResult ] group:group remoteDocuments:remoteDocuments];
+ affected = [self releaseBatchResults:@[ batchResult ] remoteDocuments:remoteDocuments];
- [remoteDocuments applyToWriteGroup:group];
- }
+ [remoteDocuments apply];
+ }
- [self.mutationQueue performConsistencyCheck];
+ [self.mutationQueue performConsistencyCheck];
- FSTMaybeDocumentDictionary *result = [self.localDocuments documentsForKeys:affected];
- [self.persistence commitGroup:group];
- return result;
+ return [self.localDocuments documentsForKeys:affected];
+ });
}
- (FSTMaybeDocumentDictionary *)rejectBatchID:(FSTBatchID)batchID {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Reject batch"];
-
- FSTMutationBatch *toReject = [self.mutationQueue lookupMutationBatch:batchID];
- FSTAssert(toReject, @"Attempt to reject nonexistent batch!");
+ return self.persistence.run("Reject batch", [&]() -> FSTMaybeDocumentDictionary * {
+ FSTMutationBatch *toReject = [self.mutationQueue lookupMutationBatch:batchID];
+ FSTAssert(toReject, @"Attempt to reject nonexistent batch!");
- FSTBatchID lastAcked = [self.mutationQueue highestAcknowledgedBatchID];
- FSTAssert(batchID > lastAcked, @"Acknowledged batches can't be rejected.");
+ FSTBatchID lastAcked = [self.mutationQueue highestAcknowledgedBatchID];
+ FSTAssert(batchID > lastAcked, @"Acknowledged batches can't be rejected.");
- FSTDocumentKeySet *affected = [self removeMutationBatch:toReject group:group];
+ FSTDocumentKeySet *affected = [self removeMutationBatch:toReject];
- [self.mutationQueue performConsistencyCheck];
+ [self.mutationQueue performConsistencyCheck];
- FSTMaybeDocumentDictionary *result = [self.localDocuments documentsForKeys:affected];
- [self.persistence commitGroup:group];
- return result;
+ return [self.localDocuments documentsForKeys:affected];
+ });
}
- (nullable NSData *)lastStreamToken {
@@ -261,10 +256,8 @@ NS_ASSUME_NONNULL_BEGIN
}
- (void)setLastStreamToken:(nullable NSData *)streamToken {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Set stream token"];
-
- [self.mutationQueue setLastStreamToken:streamToken];
- [self.persistence commitGroup:group];
+ self.persistence.run("Set stream token",
+ [&]() { [self.mutationQueue setLastStreamToken:streamToken]; });
}
- (FSTSnapshotVersion *)lastRemoteSnapshotVersion {
@@ -272,207 +265,197 @@ NS_ASSUME_NONNULL_BEGIN
}
- (FSTMaybeDocumentDictionary *)applyRemoteEvent:(FSTRemoteEvent *)remoteEvent {
- id<FSTQueryCache> queryCache = self.queryCache;
-
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Apply remote event"];
- FSTRemoteDocumentChangeBuffer *remoteDocuments =
- [FSTRemoteDocumentChangeBuffer changeBufferWithCache:self.remoteDocumentCache];
+ return self.persistence.run("Apply remote event", [&]() -> FSTMaybeDocumentDictionary * {
+ id<FSTQueryCache> queryCache = self.queryCache;
- [remoteEvent.targetChanges enumerateKeysAndObjectsUsingBlock:^(
- NSNumber *targetIDNumber, FSTTargetChange *change, BOOL *stop) {
- FSTTargetID targetID = targetIDNumber.intValue;
+ FSTRemoteDocumentChangeBuffer *remoteDocuments =
+ [FSTRemoteDocumentChangeBuffer changeBufferWithCache:self.remoteDocumentCache];
- // Do not ref/unref unassigned targetIDs - it may lead to leaks.
- FSTQueryData *queryData = self.targetIDs[targetIDNumber];
- if (!queryData) {
- return;
- }
+ [remoteEvent.targetChanges enumerateKeysAndObjectsUsingBlock:^(
+ NSNumber *targetIDNumber, FSTTargetChange *change, BOOL *stop) {
+ FSTTargetID targetID = targetIDNumber.intValue;
- FSTTargetMapping *mapping = change.mapping;
- if (mapping) {
- // First make sure that all references are deleted.
- if ([mapping isKindOfClass:[FSTResetMapping class]]) {
- FSTResetMapping *reset = (FSTResetMapping *)mapping;
- [queryCache removeMatchingKeysForTargetID:targetID];
- [queryCache addMatchingKeys:reset.documents forTargetID:targetID];
+ // Do not ref/unref unassigned targetIDs - it may lead to leaks.
+ FSTQueryData *queryData = self.targetIDs[targetIDNumber];
+ if (!queryData) {
+ return;
+ }
- } else if ([mapping isKindOfClass:[FSTUpdateMapping class]]) {
- FSTUpdateMapping *update = (FSTUpdateMapping *)mapping;
- [queryCache removeMatchingKeys:update.removedDocuments forTargetID:targetID];
- [queryCache addMatchingKeys:update.addedDocuments forTargetID:targetID];
+ FSTTargetMapping *mapping = change.mapping;
+ if (mapping) {
+ // First make sure that all references are deleted.
+ if ([mapping isKindOfClass:[FSTResetMapping class]]) {
+ FSTResetMapping *reset = (FSTResetMapping *)mapping;
+ [queryCache removeMatchingKeysForTargetID:targetID];
+ [queryCache addMatchingKeys:reset.documents forTargetID:targetID];
+
+ } else if ([mapping isKindOfClass:[FSTUpdateMapping class]]) {
+ FSTUpdateMapping *update = (FSTUpdateMapping *)mapping;
+ [queryCache removeMatchingKeys:update.removedDocuments forTargetID:targetID];
+ [queryCache addMatchingKeys:update.addedDocuments forTargetID:targetID];
+
+ } else {
+ FSTFail(@"Unknown mapping type: %@", mapping);
+ }
+ }
+ // Update the resume token if the change includes one. Don't clear any preexisting value.
+ NSData *resumeToken = change.resumeToken;
+ if (resumeToken.length > 0) {
+ queryData = [queryData queryDataByReplacingSnapshotVersion:change.snapshotVersion
+ resumeToken:resumeToken];
+ self.targetIDs[targetIDNumber] = queryData;
+ [self.queryCache updateQueryData:queryData];
+ }
+ }];
+
+ // TODO(klimt): This could probably be an NSMutableDictionary.
+ FSTDocumentKeySet *changedDocKeys = [FSTDocumentKeySet keySet];
+ for (const auto &kv : remoteEvent.documentUpdates) {
+ const DocumentKey &key = kv.first;
+ FSTMaybeDocument *doc = kv.second;
+ changedDocKeys = [changedDocKeys setByAddingObject:key];
+ FSTMaybeDocument *existingDoc = [remoteDocuments entryForKey:key];
+ // Make sure we don't apply an old document version to the remote cache, though we
+ // make an exception for [SnapshotVersion noVersion] which can happen for manufactured
+ // events (e.g. in the case of a limbo document resolution failing).
+ if (!existingDoc || [doc.version isEqual:[FSTSnapshotVersion noVersion]] ||
+ [doc.version compare:existingDoc.version] != NSOrderedAscending) {
+ [remoteDocuments addEntry:doc];
} else {
- FSTFail(@"Unknown mapping type: %@", mapping);
+ FSTLog(
+ @"FSTLocalStore Ignoring outdated watch update for %s. "
+ "Current version: %@ Watch version: %@",
+ key.ToString().c_str(), existingDoc.version, doc.version);
}
- }
- // Update the resume token if the change includes one. Don't clear any preexisting value.
- NSData *resumeToken = change.resumeToken;
- if (resumeToken.length > 0) {
- queryData = [queryData queryDataByReplacingSnapshotVersion:change.snapshotVersion
- resumeToken:resumeToken];
- self.targetIDs[targetIDNumber] = queryData;
- [self.queryCache updateQueryData:queryData];
+ // The document might be garbage because it was unreferenced by everything.
+ // Make sure to mark it as garbage if it is...
+ [self.garbageCollector addPotentialGarbageKey:key];
}
- }];
- // TODO(klimt): This could probably be an NSMutableDictionary.
- FSTDocumentKeySet *changedDocKeys = [FSTDocumentKeySet keySet];
- for (const auto &kv : remoteEvent.documentUpdates) {
- const DocumentKey &key = kv.first;
- FSTMaybeDocument *doc = kv.second;
- changedDocKeys = [changedDocKeys setByAddingObject:key];
- FSTMaybeDocument *existingDoc = [remoteDocuments entryForKey:key];
- // Make sure we don't apply an old document version to the remote cache, though we
- // make an exception for [SnapshotVersion noVersion] which can happen for manufactured
- // events (e.g. in the case of a limbo document resolution failing).
- if (!existingDoc || [doc.version isEqual:[FSTSnapshotVersion noVersion]] ||
- [doc.version compare:existingDoc.version] != NSOrderedAscending) {
- [remoteDocuments addEntry:doc];
- } else {
- FSTLog(
- @"FSTLocalStore Ignoring outdated watch update for %s. "
- "Current version: %@ Watch version: %@",
- key.ToString().c_str(), existingDoc.version, doc.version);
+ // HACK: The only reason we allow omitting snapshot version is so we can synthesize remote
+ // events when we get permission denied errors while trying to resolve the state of a locally
+ // cached document that is in limbo.
+ FSTSnapshotVersion *lastRemoteVersion = [self.queryCache lastRemoteSnapshotVersion];
+ FSTSnapshotVersion *remoteVersion = remoteEvent.snapshotVersion;
+ if (![remoteVersion isEqual:[FSTSnapshotVersion noVersion]]) {
+ FSTAssert([remoteVersion compare:lastRemoteVersion] != NSOrderedAscending,
+ @"Watch stream reverted to previous snapshot?? (%@ < %@)", remoteVersion,
+ lastRemoteVersion);
+ [self.queryCache setLastRemoteSnapshotVersion:remoteVersion];
}
- // The document might be garbage because it was unreferenced by everything.
- // Make sure to mark it as garbage if it is...
- [self.garbageCollector addPotentialGarbageKey:key];
- }
-
- // HACK: The only reason we allow omitting snapshot version is so we can synthesize remote events
- // when we get permission denied errors while trying to resolve the state of a locally cached
- // document that is in limbo.
- FSTSnapshotVersion *lastRemoteVersion = [self.queryCache lastRemoteSnapshotVersion];
- FSTSnapshotVersion *remoteVersion = remoteEvent.snapshotVersion;
- if (![remoteVersion isEqual:[FSTSnapshotVersion noVersion]]) {
- FSTAssert([remoteVersion compare:lastRemoteVersion] != NSOrderedAscending,
- @"Watch stream reverted to previous snapshot?? (%@ < %@)", remoteVersion,
- lastRemoteVersion);
- [self.queryCache setLastRemoteSnapshotVersion:remoteVersion];
- }
-
- FSTDocumentKeySet *releasedWriteKeys =
- [self releaseHeldBatchResultsWithGroup:group remoteDocuments:remoteDocuments];
+ FSTDocumentKeySet *releasedWriteKeys =
+ [self releaseHeldBatchResultsWithRemoteDocuments:remoteDocuments];
- [remoteDocuments applyToWriteGroup:group];
+ [remoteDocuments apply];
- // Union the two key sets.
- __block FSTDocumentKeySet *keysToRecalc = changedDocKeys;
- [releasedWriteKeys enumerateObjectsUsingBlock:^(FSTDocumentKey *key, BOOL *stop) {
- keysToRecalc = [keysToRecalc setByAddingObject:key];
- }];
+ // Union the two key sets.
+ __block FSTDocumentKeySet *keysToRecalc = changedDocKeys;
+ [releasedWriteKeys enumerateObjectsUsingBlock:^(FSTDocumentKey *key, BOOL *stop) {
+ keysToRecalc = [keysToRecalc setByAddingObject:key];
+ }];
- FSTMaybeDocumentDictionary *result = [self.localDocuments documentsForKeys:keysToRecalc];
- [self.persistence commitGroup:group];
- return result;
+ return [self.localDocuments documentsForKeys:keysToRecalc];
+ });
}
- (void)notifyLocalViewChanges:(NSArray<FSTLocalViewChanges *> *)viewChanges {
- FSTReferenceSet *localViewReferences = self.localViewReferences;
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"NotifyLocalViewChanges"];
- for (FSTLocalViewChanges *view in viewChanges) {
- FSTQueryData *queryData = [self.queryCache queryDataForQuery:view.query];
- FSTAssert(queryData, @"Local view changes contain unallocated query.");
- FSTTargetID targetID = queryData.targetID;
- [localViewReferences addReferencesToKeys:view.addedKeys forID:targetID];
- [localViewReferences removeReferencesToKeys:view.removedKeys forID:targetID];
- }
- [self.persistence commitGroup:group];
+ self.persistence.run("NotifyLocalViewChanges", [&]() {
+ FSTReferenceSet *localViewReferences = self.localViewReferences;
+ for (FSTLocalViewChanges *view in viewChanges) {
+ FSTQueryData *queryData = [self.queryCache queryDataForQuery:view.query];
+ FSTAssert(queryData, @"Local view changes contain unallocated query.");
+ FSTTargetID targetID = queryData.targetID;
+ [localViewReferences addReferencesToKeys:view.addedKeys forID:targetID];
+ [localViewReferences removeReferencesToKeys:view.removedKeys forID:targetID];
+ }
+ });
}
- (nullable FSTMutationBatch *)nextMutationBatchAfterBatchID:(FSTBatchID)batchID {
- FSTMutationBatch *result = self.persistence.run([&]() -> FSTMutationBatch * {
- return [self.mutationQueue nextMutationBatchAfterBatchID:batchID];
- });
+ FSTMutationBatch *result =
+ self.persistence.run("NextMutationBatchAfterBatchID", [&]() -> FSTMutationBatch * {
+ return [self.mutationQueue nextMutationBatchAfterBatchID:batchID];
+ });
return result;
}
- (nullable FSTMaybeDocument *)readDocument:(const DocumentKey &)key {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"ReadDocument"];
- FSTMaybeDocument *result = [self.localDocuments documentForKey:key];
- [self.persistence commitGroup:group];
- return result;
+ return self.persistence.run("ReadDocument", [&]() -> FSTMaybeDocument *_Nullable {
+ return [self.localDocuments documentForKey:key];
+ });
}
- (FSTQueryData *)allocateQuery:(FSTQuery *)query {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Allocate query"];
- FSTQueryData *cached = [self.queryCache queryDataForQuery:query];
- FSTTargetID targetID;
- FSTListenSequenceNumber sequenceNumber = [self.listenSequence next];
- if (cached) {
- // This query has been listened to previously, so reuse the previous targetID.
- // TODO(mcg): freshen last accessed date?
- targetID = cached.targetID;
- } else {
- targetID = _targetIDGenerator.NextId();
- cached = [[FSTQueryData alloc] initWithQuery:query
- targetID:targetID
- listenSequenceNumber:sequenceNumber
- purpose:FSTQueryPurposeListen];
- [self.queryCache addQueryData:cached];
- }
- [self.persistence commitGroup:group];
+ FSTQueryData *queryData = self.persistence.run("Allocate query", [&]() -> FSTQueryData * {
+ FSTQueryData *cached = [self.queryCache queryDataForQuery:query];
+ // TODO(mcg): freshen last accessed date if cached exists?
+ if (!cached) {
+ cached = [[FSTQueryData alloc] initWithQuery:query
+ targetID:_targetIDGenerator.NextId()
+ listenSequenceNumber:[self.listenSequence next]
+ purpose:FSTQueryPurposeListen];
+ [self.queryCache addQueryData:cached];
+ }
+ return cached;
+ });
// Sanity check to ensure that even when resuming a query it's not currently active.
- FSTBoxedTargetID *boxedTargetID = @(targetID);
+ FSTBoxedTargetID *boxedTargetID = @(queryData.targetID);
FSTAssert(!self.targetIDs[boxedTargetID], @"Tried to allocate an already allocated query: %@",
query);
- self.targetIDs[boxedTargetID] = cached;
- return cached;
+ self.targetIDs[boxedTargetID] = queryData;
+ return queryData;
}
- (void)releaseQuery:(FSTQuery *)query {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Release query"];
-
- FSTQueryData *queryData = [self.queryCache queryDataForQuery:query];
- FSTAssert(queryData, @"Tried to release nonexistent query: %@", query);
-
- [self.localViewReferences removeReferencesForID:queryData.targetID];
- if (self.garbageCollector.isEager) {
- [self.queryCache removeQueryData:queryData];
- }
- [self.targetIDs removeObjectForKey:@(queryData.targetID)];
+ self.persistence.run("Release query", [&]() {
+ FSTQueryData *queryData = [self.queryCache queryDataForQuery:query];
+ FSTAssert(queryData, @"Tried to release nonexistent query: %@", query);
- // If this was the last watch target, then we won't get any more watch snapshots, so we should
- // release any held batch results.
- if ([self.targetIDs count] == 0) {
- FSTRemoteDocumentChangeBuffer *remoteDocuments =
- [FSTRemoteDocumentChangeBuffer changeBufferWithCache:self.remoteDocumentCache];
+ [self.localViewReferences removeReferencesForID:queryData.targetID];
+ if (self.garbageCollector.isEager) {
+ [self.queryCache removeQueryData:queryData];
+ }
+ [self.targetIDs removeObjectForKey:@(queryData.targetID)];
- [self releaseHeldBatchResultsWithGroup:group remoteDocuments:remoteDocuments];
+ // If this was the last watch target, then we won't get any more watch snapshots, so we should
+ // release any held batch results.
+ if ([self.targetIDs count] == 0) {
+ FSTRemoteDocumentChangeBuffer *remoteDocuments =
+ [FSTRemoteDocumentChangeBuffer changeBufferWithCache:self.remoteDocumentCache];
- [remoteDocuments applyToWriteGroup:group];
- }
+ [self releaseHeldBatchResultsWithRemoteDocuments:remoteDocuments];
- [self.persistence commitGroup:group];
+ [remoteDocuments apply];
+ }
+ });
}
- (FSTDocumentDictionary *)executeQuery:(FSTQuery *)query {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"ExecuteQuery"];
- FSTDocumentDictionary *result = [self.localDocuments documentsMatchingQuery:query];
- [self.persistence commitGroup:group];
- return result;
+ return self.persistence.run("ExecuteQuery", [&]() -> FSTDocumentDictionary * {
+ return [self.localDocuments documentsMatchingQuery:query];
+ });
}
- (FSTDocumentKeySet *)remoteDocumentKeysForTarget:(FSTTargetID)targetID {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"RemoteDocumentKeysForTarget"];
- FSTDocumentKeySet *keySet = [self.queryCache matchingKeysForTargetID:targetID];
- [self.persistence commitGroup:group];
- return keySet;
+ return self.persistence.run("RemoteDocumentKeysForTarget", [&]() -> FSTDocumentKeySet * {
+ return [self.queryCache matchingKeysForTargetID:targetID];
+ });
}
- (void)collectGarbage {
- FSTWriteGroup *group = [self.persistence startGroupWithAction:@"Garbage Collection"];
- // Call collectGarbage regardless of whether isGCEnabled so the referenceSet doesn't continue to
- // accumulate the garbage keys.
- std::set<DocumentKey> garbage = [self.garbageCollector collectGarbage];
- if (garbage.size() > 0) {
- for (const DocumentKey &key : garbage) {
- [self.remoteDocumentCache removeEntryForKey:key];
+ self.persistence.run("Garbage Collection", [&]() {
+ // Call collectGarbage regardless of whether isGCEnabled so the referenceSet doesn't continue to
+ // accumulate the garbage keys.
+ std::set<DocumentKey> garbage = [self.garbageCollector collectGarbage];
+ if (garbage.size() > 0) {
+ for (const DocumentKey &key : garbage) {
+ [self.remoteDocumentCache removeEntryForKey:key];
+ }
}
- }
- [self.persistence commitGroup:group];
+ });
}
/**
@@ -481,9 +464,8 @@ NS_ASSUME_NONNULL_BEGIN
*
* @return the set of keys of docs that were modified by those writes.
*/
-- (FSTDocumentKeySet *)releaseHeldBatchResultsWithGroup:(FSTWriteGroup *)group
- remoteDocuments:
- (FSTRemoteDocumentChangeBuffer *)remoteDocuments {
+- (FSTDocumentKeySet *)releaseHeldBatchResultsWithRemoteDocuments:
+ (FSTRemoteDocumentChangeBuffer *)remoteDocuments {
NSMutableArray<FSTMutationBatchResult *> *toRelease = [NSMutableArray array];
for (FSTMutationBatchResult *batchResult in self.heldBatchResults) {
if (![self isRemoteUpToVersion:batchResult.commitVersion]) {
@@ -496,7 +478,7 @@ NS_ASSUME_NONNULL_BEGIN
return [FSTDocumentKeySet keySet];
} else {
[self.heldBatchResults removeObjectsInRange:NSMakeRange(0, toRelease.count)];
- return [self releaseBatchResults:toRelease group:group remoteDocuments:remoteDocuments];
+ return [self releaseBatchResults:toRelease remoteDocuments:remoteDocuments];
}
}
@@ -512,7 +494,6 @@ NS_ASSUME_NONNULL_BEGIN
}
- (FSTDocumentKeySet *)releaseBatchResults:(NSArray<FSTMutationBatchResult *> *)batchResults
- group:(FSTWriteGroup *)group
remoteDocuments:(FSTRemoteDocumentChangeBuffer *)remoteDocuments {
NSMutableArray<FSTMutationBatch *> *batches = [NSMutableArray array];
for (FSTMutationBatchResult *batchResult in batchResults) {
@@ -520,16 +501,15 @@ NS_ASSUME_NONNULL_BEGIN
[batches addObject:batchResult.batch];
}
- return [self removeMutationBatches:batches group:group];
+ return [self removeMutationBatches:batches];
}
-- (FSTDocumentKeySet *)removeMutationBatch:(FSTMutationBatch *)batch group:(FSTWriteGroup *)group {
- return [self removeMutationBatches:@[ batch ] group:group];
+- (FSTDocumentKeySet *)removeMutationBatch:(FSTMutationBatch *)batch {
+ return [self removeMutationBatches:@[ batch ]];
}
/** Removes all the mutation batches named in the given array. */
-- (FSTDocumentKeySet *)removeMutationBatches:(NSArray<FSTMutationBatch *> *)batches
- group:(FSTWriteGroup *)group {
+- (FSTDocumentKeySet *)removeMutationBatches:(NSArray<FSTMutationBatch *> *)batches {
// TODO(klimt): Could this be an NSMutableDictionary?
__block FSTDocumentKeySet *affectedDocs = [FSTDocumentKeySet keySet];
diff --git a/Firestore/Source/Local/FSTMemoryPersistence.mm b/Firestore/Source/Local/FSTMemoryPersistence.mm
index f1f9885..8d74881 100644
--- a/Firestore/Source/Local/FSTMemoryPersistence.mm
+++ b/Firestore/Source/Local/FSTMemoryPersistence.mm
@@ -21,8 +21,6 @@
#import "Firestore/Source/Local/FSTMemoryMutationQueue.h"
#import "Firestore/Source/Local/FSTMemoryQueryCache.h"
#import "Firestore/Source/Local/FSTMemoryRemoteDocumentCache.h"
-#import "Firestore/Source/Local/FSTWriteGroup.h"
-#import "Firestore/Source/Local/FSTWriteGroupTracker.h"
#import "Firestore/Source/Util/FSTAssert.h"
#include "Firestore/core/src/firebase/firestore/auth/user.h"
@@ -33,7 +31,6 @@ using firebase::firestore::auth::User;
NS_ASSUME_NONNULL_BEGIN
@interface FSTMemoryPersistence ()
-@property(nonatomic, strong, nonnull) FSTWriteGroupTracker *writeGroupTracker;
@property(nonatomic, assign, getter=isStarted) BOOL started;
@end
@@ -62,7 +59,6 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init {
if (self = [super init]) {
- _writeGroupTracker = [FSTWriteGroupTracker tracker];
_queryCache = [[FSTMemoryQueryCache alloc] init];
_remoteDocumentCache = [[FSTMemoryRemoteDocumentCache alloc] init];
}
@@ -103,16 +99,6 @@ NS_ASSUME_NONNULL_BEGIN
return _remoteDocumentCache;
}
-- (FSTWriteGroup *)startGroupWithAction:(NSString *)action {
- return [self.writeGroupTracker startGroupWithAction:action];
-}
-
-- (void)commitGroup:(FSTWriteGroup *)group {
- [self.writeGroupTracker endGroup:group];
-
- FSTAssert(group.isEmpty, @"Memory persistence shouldn't use write groups: %@", group.action);
-}
-
@end
NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Local/FSTPersistence.h b/Firestore/Source/Local/FSTPersistence.h
index 1784163..2294ef1 100644
--- a/Firestore/Source/Local/FSTPersistence.h
+++ b/Firestore/Source/Local/FSTPersistence.h
@@ -19,7 +19,6 @@
#import "Firestore/Source/Util/FSTAssert.h"
#include "Firestore/core/src/firebase/firestore/auth/user.h"
-@class FSTWriteGroup;
@protocol FSTMutationQueue;
@protocol FSTQueryCache;
@protocol FSTRemoteDocumentCache;
@@ -86,28 +85,13 @@ struct FSTTransactionRunner;
/** Creates an FSTRemoteDocumentCache representing the persisted cache of remote documents. */
- (id<FSTRemoteDocumentCache>)remoteDocumentCache;
-/**
- * Creates an FSTWriteGroup with the specified action description.
- *
- * @param action A description of the action performed by this group, used for logging.
- * @return The created group.
- */
-- (FSTWriteGroup *)startGroupWithAction:(NSString *)action;
-
-/**
- * Commits all accumulated changes in the given group. If there are no changes this is a no-op.
- *
- * @param group The group of changes to write as a unit.
- */
-- (void)commitGroup:(FSTWriteGroup *)group;
-
@property(nonatomic, readonly, assign) const FSTTransactionRunner &run;
@end
@protocol FSTTransactional
-- (void)startTransaction;
+- (void)startTransaction:(absl::string_view)label;
- (void)commitTransaction;
@@ -136,14 +120,14 @@ struct FSTTransactionRunner {
*/
template <typename F>
- auto operator()(F block) const ->
+ auto operator()(absl::string_view label, F block) const ->
typename std::enable_if<std::is_void<decltype(block())>::value, void>::type {
__strong id<FSTTransactional> strongDb = _db;
if (!strongDb && _expect_db) {
FSTCFail(@"Transaction runner accessed without underlying db when it expected one");
}
if (strongDb) {
- [strongDb startTransaction];
+ [strongDb startTransaction:label];
}
block();
if (strongDb) {
@@ -152,7 +136,7 @@ struct FSTTransactionRunner {
}
template <typename F>
- auto operator()(F block) const ->
+ auto operator()(absl::string_view label, F block) const ->
typename std::enable_if<!std::is_void<decltype(block())>::value, decltype(block())>::type {
using ReturnT = decltype(block());
__strong id<FSTTransactional> strongDb = _db;
@@ -160,7 +144,7 @@ struct FSTTransactionRunner {
FSTCFail(@"Transaction runner accessed without underlying db when it expected one");
}
if (strongDb) {
- [strongDb startTransaction];
+ [strongDb startTransaction:label];
}
ReturnT result = block();
if (strongDb) {
diff --git a/Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.h b/Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.h
index cfdf55b..be29a89 100644
--- a/Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.h
+++ b/Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.h
@@ -22,7 +22,6 @@ NS_ASSUME_NONNULL_BEGIN
@protocol FSTRemoteDocumentCache;
@class FSTMaybeDocument;
-@class FSTWriteGroup;
/**
* An in-memory buffer of entries to be written to an FSTRemoteDocumentCache. It can be used to
@@ -58,10 +57,9 @@ NS_ASSUME_NONNULL_BEGIN
(const firebase::firestore::model::DocumentKey &)documentKey;
/**
- * Applies buffered changes to the underlying FSTRemoteDocumentCache, using the provided
- * FSTWriteGroup.
+ * Applies buffered changes to the underlying FSTRemoteDocumentCache
*/
-- (void)applyToWriteGroup:(FSTWriteGroup *)group;
+- (void)apply;
@end
diff --git a/Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.mm b/Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.mm
index 0557bce..3812501 100644
--- a/Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.mm
+++ b/Firestore/Source/Local/FSTRemoteDocumentChangeBuffer.mm
@@ -73,7 +73,7 @@ NS_ASSUME_NONNULL_BEGIN
}
}
-- (void)applyToWriteGroup:(FSTWriteGroup *)group {
+- (void)apply {
[self assertValid];
for (const auto &kv : *_changes) {
diff --git a/Firestore/Source/Local/FSTWriteGroup.h b/Firestore/Source/Local/FSTWriteGroup.h
deleted file mode 100644
index a554597..0000000
--- a/Firestore/Source/Local/FSTWriteGroup.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#import <Foundation/Foundation.h>
-
-#include <memory>
-
-#include "Firestore/Source/Local/StringView.h"
-#include "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h"
-#include "leveldb/db.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@class GPBMessage;
-
-/**
- * A group of writes that will be applied together atomically to persistent storage.
- *
- * This class is usable by both Objective-C and Objective-C++ clients. Objective-C clients are able
- * to create a new group and commit it. Objective-C++ clients can additionally add to the group
- * using deleteKey: and putKey:value:.
- *
- * Note that this is a write "group" even though the underlying LevelDB concept is a write "batch"
- * because Firestore already has a concept of mutation batches, which are user-specified groups of
- * changes. This means that an FSTWriteGroup may contain the application of multiple user-specified
- * mutation batches.
- */
-@interface FSTWriteGroup : NSObject
-
-/**
- * Creates a new, empty write group.
- *
- * @param action A description of the action performed by this group, used for logging.
- */
-+ (instancetype)groupWithAction:(NSString *)action;
-
-+ (instancetype)groupWithAction:(NSString *)action
- transaction:(firebase::firestore::local::LevelDbTransaction *)transaction;
-
-- (instancetype)init __attribute__((unavailable("Use a static constructor instead")));
-
-/** The action description assigned to this write group. */
-@property(nonatomic, copy, readonly) NSString *action;
-
-@property(nonatomic, readonly) firebase::firestore::local::LevelDbTransaction *transaction;
-
-/**
- * Marks the given key for deletion.
- *
- * @param key The LevelDB key of the row to delete
- */
-- (void)removeMessageForKey:(Firestore::StringView)key;
-
-/**
- * Sets the row identified by the given key to the value of the given protocol buffer message.
- *
- * @param key The LevelDB Key of the row to set.
- * @param message The protocol buffer message whose serialized contents should be used for the
- * value associated with the key.
- */
-- (void)setMessage:(GPBMessage *)message forKey:(Firestore::StringView)key;
-
-/**
- * Sets the row identified by the given key to the value of the given data bytes.
- *
- * @param key The LevelDB Key of the row to set.
- * @param data The exact value to be associated with the key.
- */
-- (void)setData:(Firestore::StringView)data forKey:(Firestore::StringView)key;
-
-/** Returns YES if the write group has no messages in it. */
-- (BOOL)isEmpty;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Local/FSTWriteGroup.mm b/Firestore/Source/Local/FSTWriteGroup.mm
deleted file mode 100644
index 9aee31a..0000000
--- a/Firestore/Source/Local/FSTWriteGroup.mm
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#import "Firestore/Source/Local/FSTWriteGroup.h"
-
-#include <leveldb/write_batch.h>
-
-#import "Firestore/Source/Local/FSTLevelDBKey.h"
-#import "Firestore/Source/Util/FSTAssert.h"
-
-using firebase::firestore::local::LevelDbTransaction;
-using Firestore::StringView;
-using leveldb::DB;
-using leveldb::Slice;
-using leveldb::Status;
-using leveldb::WriteBatch;
-using leveldb::WriteOptions;
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface FSTWriteGroup ()
-- (instancetype)initWithAction:(NSString *)action NS_DESIGNATED_INITIALIZER;
-- (instancetype)initWithAction:(NSString *)action transaction:(LevelDbTransaction *)transaction;
-@end
-
-@implementation FSTWriteGroup {
- int _changes;
-}
-
-+ (instancetype)groupWithAction:(NSString *)action {
- return [[FSTWriteGroup alloc] initWithAction:action];
-}
-
-+ (instancetype)groupWithAction:(NSString *)action
- transaction:(firebase::firestore::local::LevelDbTransaction *)transaction {
- return [[FSTWriteGroup alloc] initWithAction:action transaction:transaction];
-}
-
-- (instancetype)initWithAction:(NSString *)action {
- if (self = [super init]) {
- _action = action;
- _transaction = nullptr;
- }
- return self;
-}
-
-- (instancetype)initWithAction:(NSString *)action transaction:(LevelDbTransaction *)transaction {
- if (self = [self initWithAction:action]) {
- _transaction = transaction;
- }
- return self;
-}
-
-- (void)removeMessageForKey:(StringView)key {
- FSTAssert(_transaction != nullptr, @"Using group without a transaction");
- Slice keySlice = key;
- _transaction->Delete(keySlice.ToString());
- _changes += 1;
-}
-
-- (void)setMessage:(GPBMessage *)message forKey:(StringView)key {
- FSTAssert(_transaction != nullptr, @"Using group without a transaction");
- Slice keySlice = key;
- _transaction->Put(keySlice.ToString(), message);
- _changes += 1;
-}
-
-- (void)setData:(StringView)data forKey:(StringView)key {
- FSTAssert(_transaction != nullptr, @"Using group without a transaction");
- Slice keySlice = key;
- Slice valueSlice = data;
- std::string value = valueSlice.ToString();
- _transaction->Put(keySlice.ToString(), value);
- _changes += 1;
-}
-
-- (BOOL)isEmpty {
- return _changes == 0;
-}
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Local/FSTWriteGroupTracker.h b/Firestore/Source/Local/FSTWriteGroupTracker.h
deleted file mode 100644
index c4651ab..0000000
--- a/Firestore/Source/Local/FSTWriteGroupTracker.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#import <Foundation/Foundation.h>
-#import "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h"
-
-@class FSTWriteGroup;
-
-NS_ASSUME_NONNULL_BEGIN
-
-/**
- * Helper class for FSTPersistence implementations to create WriteGroups and verify internal
- * contracts are maintained:
- * 1. Can't create a group when an uncommitted group exists (no nesting).
- * 2. Can't commit a group that differs from the last created one.
- */
-@interface FSTWriteGroupTracker : NSObject
-
-/** Creates and returns an FSTWriteGroupTracker instance. */
-+ (instancetype)tracker;
-
-/**
- * Verifies there's no active group already and then creates a new group and stores it for later
- * validation with `endGroup`.
- */
-- (FSTWriteGroup *)startGroupWithAction:(NSString *)action;
-
-- (FSTWriteGroup *)startGroupWithAction:(NSString *)action
- transaction:
- (firebase::firestore::local::LevelDbTransaction *)transaction;
-
-/** Ends a group previously started with `startGroupWithAction`. */
-- (void)endGroup:(FSTWriteGroup *)group;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/Firestore/Source/Local/FSTWriteGroupTracker.mm b/Firestore/Source/Local/FSTWriteGroupTracker.mm
deleted file mode 100644
index 2cb10bd..0000000
--- a/Firestore/Source/Local/FSTWriteGroupTracker.mm
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2017 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.
- */
-
-#import "Firestore/Source/Local/FSTWriteGroupTracker.h"
-
-#import "Firestore/Source/Local/FSTWriteGroup.h"
-#import "Firestore/Source/Util/FSTAssert.h"
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface FSTWriteGroupTracker ()
-@property(nonatomic, strong, nullable) FSTWriteGroup *activeGroup;
-@end
-
-@implementation FSTWriteGroupTracker
-
-+ (instancetype)tracker {
- return [[FSTWriteGroupTracker alloc] init];
-}
-
-- (FSTWriteGroup *)startGroupWithAction:(NSString *)action {
- // NOTE: We can relax this to allow nesting if/when we find we need it.
- FSTAssert(!self.activeGroup,
- @"Attempt to create write group (%@) while existing write group (%@) still active.",
- action, self.activeGroup.action);
- self.activeGroup = [FSTWriteGroup groupWithAction:action];
- return self.activeGroup;
-}
-
-- (FSTWriteGroup *)startGroupWithAction:(NSString *)action
- transaction:
- (firebase::firestore::local::LevelDbTransaction *)transaction {
- // NOTE: We can relax this to allow nesting if/when we find we need it.
- FSTAssert(!self.activeGroup,
- @"Attempt to create write group (%@) while existing write group (%@) still active.",
- action, self.activeGroup.action);
- self.activeGroup = [FSTWriteGroup groupWithAction:action transaction:transaction];
- return self.activeGroup;
-}
-
-- (void)endGroup:(FSTWriteGroup *)group {
- FSTAssert(self.activeGroup == group,
- @"Attempted to end write group (%@) which is different from active group (%@)",
- group.action, self.activeGroup.action);
- self.activeGroup = nil;
-}
-
-@end
-
-NS_ASSUME_NONNULL_END