diff --git a/Firestore/Example/Tests/Local/FSTLRUGarbageCollectorTests.mm b/Firestore/Example/Tests/Local/FSTLRUGarbageCollectorTests.mm index 296791b1ce9..102ee971d52 100644 --- a/Firestore/Example/Tests/Local/FSTLRUGarbageCollectorTests.mm +++ b/Firestore/Example/Tests/Local/FSTLRUGarbageCollectorTests.mm @@ -25,12 +25,12 @@ #import "Firestore/Source/Local/FSTLRUGarbageCollector.h" #import "Firestore/Source/Local/FSTMutationQueue.h" #import "Firestore/Source/Local/FSTPersistence.h" -#import "Firestore/Source/Local/FSTQueryCache.h" #import "Firestore/Source/Model/FSTDocument.h" #import "Firestore/Source/Model/FSTFieldValue.h" #import "Firestore/Source/Model/FSTMutation.h" #import "Firestore/Source/Util/FSTClasses.h" #include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/local/query_cache.h" #include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" #include "Firestore/core/src/firebase/firestore/model/document_key_set.h" #include "Firestore/core/src/firebase/firestore/model/precondition.h" @@ -42,6 +42,7 @@ using firebase::firestore::auth::User; using firebase::firestore::local::LruParams; using firebase::firestore::local::LruResults; +using firebase::firestore::local::QueryCache; using firebase::firestore::local::RemoteDocumentCache; using firebase::firestore::model::DocumentKey; using firebase::firestore::model::DocumentKeyHash; @@ -58,7 +59,7 @@ @implementation FSTLRUGarbageCollectorTests { FSTObjectValue *_testValue; FSTObjectValue *_bigObjectValue; id _persistence; - id _queryCache; + QueryCache *_queryCache; RemoteDocumentCache *_documentCache; id _mutationQueue; id _lruDelegate; @@ -151,7 +152,7 @@ - (FSTQueryData *)nextTestQuery { - (FSTQueryData *)addNextQueryInTransaction { FSTQueryData *queryData = [self nextTestQuery]; - [_queryCache addQueryData:queryData]; + _queryCache->AddTarget(queryData); return queryData; } @@ -161,7 +162,7 @@ - (void)updateTargetInTransaction:(FSTQueryData *)queryData { [queryData queryDataByReplacingSnapshotVersion:queryData.snapshotVersion resumeToken:token sequenceNumber:_persistence.currentSequenceNumber]; - [_queryCache updateQueryData:updated]; + _queryCache->UpdateTarget(updated); } - (FSTQueryData *)addNextQuery { @@ -195,11 +196,11 @@ - (void)markDocumentEligibleForGCInTransaction:(const DocumentKey &)docKey { } - (void)addDocument:(const DocumentKey &)docKey toTarget:(TargetId)targetId { - [_queryCache addMatchingKeys:DocumentKeySet{docKey} forTargetID:targetId]; + _queryCache->AddMatchingKeys(DocumentKeySet{docKey}, targetId); } - (void)removeDocument:(const DocumentKey &)docKey fromTarget:(TargetId)targetId { - [_queryCache removeMatchingKeys:DocumentKeySet{docKey} forTargetID:targetId]; + _queryCache->RemoveMatchingKeys(DocumentKeySet{docKey}, targetId); } /** @@ -388,9 +389,9 @@ - (void)testRemoveQueriesUpThroughSequenceNumber { XCTAssertEqual(10, removed); // Make sure we removed the even targets with targetID <= 20. _persistence.run("verify remaining targets are > 20 or odd", [&]() { - [_queryCache enumerateTargetsUsingBlock:^(FSTQueryData *queryData, BOOL *stop) { + _queryCache->EnumerateTargets(^(FSTQueryData *queryData, BOOL *stop) { XCTAssertTrue(queryData.targetID > 20 || queryData.targetID % 2 == 1); - }]; + }); }); [_persistence shutdown]; } @@ -463,7 +464,7 @@ - (void)testRemoveOrphanedDocuments { _persistence.run("verify", [&]() { for (const DocumentKey &key : toBeRemoved) { XCTAssertNil(_documentCache->Get(key)); - XCTAssertFalse([_queryCache containsKey:key]); + XCTAssertFalse(_queryCache->Contains(key)); } for (const DocumentKey &key : expectedRetained) { XCTAssertNotNil(_documentCache->Get(key), @"Missing document %s", key.ToString().c_str()); @@ -645,7 +646,7 @@ - (void)testRemoveTargetsThenGC { for (const DocumentKey &key : expectedRemoved) { XCTAssertNil(_documentCache->Get(key), @"Did not expect to find %s in document cache", key.ToString().c_str()); - XCTAssertFalse([_queryCache containsKey:key], @"Did not expect to find %s in queryCache", + XCTAssertFalse(_queryCache->Contains(key), @"Did not expect to find %s in queryCache", key.ToString().c_str()); [self expectSentinelRemoved:key]; } diff --git a/Firestore/Example/Tests/Local/FSTLevelDBMigrationsTests.mm b/Firestore/Example/Tests/Local/FSTLevelDBMigrationsTests.mm index 2ef0ed73018..d4d46a496ba 100644 --- a/Firestore/Example/Tests/Local/FSTLevelDBMigrationsTests.mm +++ b/Firestore/Example/Tests/Local/FSTLevelDBMigrationsTests.mm @@ -24,10 +24,10 @@ #import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h" #import "Firestore/Source/Local/FSTLevelDB.h" #import "Firestore/Source/Local/FSTLevelDBMutationQueue.h" -#import "Firestore/Source/Local/FSTLevelDBQueryCache.h" #include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" #include "Firestore/core/src/firebase/firestore/local/leveldb_migrations.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h" #include "Firestore/core/src/firebase/firestore/util/ordered_code.h" #include "Firestore/core/test/firebase/firestore/testutil/testutil.h" #include "absl/strings/match.h" @@ -43,6 +43,7 @@ using firebase::firestore::local::LevelDbMigrations; using firebase::firestore::local::LevelDbMutationKey; using firebase::firestore::local::LevelDbMutationQueueKey; +using firebase::firestore::local::LevelDbQueryCache; using firebase::firestore::local::LevelDbQueryTargetKey; using firebase::firestore::local::LevelDbRemoteDocumentKey; using firebase::firestore::local::LevelDbTargetDocumentKey; @@ -86,11 +87,11 @@ - (void)tearDown { } - (void)testAddsTargetGlobal { - FSTPBTargetGlobal *metadata = [FSTLevelDBQueryCache readTargetMetadataFromDB:_db.get()]; + FSTPBTargetGlobal *metadata = LevelDbQueryCache::ReadMetadata(_db.get()); XCTAssertNil(metadata, @"Not expecting metadata yet, we should have an empty db"); LevelDbMigrations::RunMigrations(_db.get()); - metadata = [FSTLevelDBQueryCache readTargetMetadataFromDB:_db.get()]; + metadata = LevelDbQueryCache::ReadMetadata(_db.get()); XCTAssertNotNil(metadata, @"Migrations should have added the metadata"); } @@ -166,7 +167,7 @@ - (void)testDropsTheQueryCache { ASSERT_FOUND(transaction, key); } - FSTPBTargetGlobal *metadata = [FSTLevelDBQueryCache readTargetMetadataFromDB:_db.get()]; + FSTPBTargetGlobal *metadata = LevelDbQueryCache::ReadMetadata(_db.get()); XCTAssertNotNil(metadata, @"Metadata should have been added"); XCTAssertEqual(metadata.targetCount, 0); } @@ -209,7 +210,7 @@ - (void)testAddsSentinelRows { LevelDbTransaction transaction(_db.get(), "Setup"); // Set up target global - FSTPBTargetGlobal *metadata = [FSTLevelDBQueryCache readTargetMetadataFromDB:_db.get()]; + FSTPBTargetGlobal *metadata = LevelDbQueryCache::ReadMetadata(_db.get()); // Expect that documents missing a row will get the new number metadata.highestListenSequenceNumber = new_sequence_number; transaction.Put(LevelDbTargetGlobalKey::Key(), metadata); diff --git a/Firestore/Example/Tests/Local/FSTLevelDBQueryCacheTests.mm b/Firestore/Example/Tests/Local/FSTLevelDBQueryCacheTests.mm index 1469be7f6e9..5a88c8c331b 100644 --- a/Firestore/Example/Tests/Local/FSTLevelDBQueryCacheTests.mm +++ b/Firestore/Example/Tests/Local/FSTLevelDBQueryCacheTests.mm @@ -14,8 +14,6 @@ * limitations under the License. */ -#import "Firestore/Source/Local/FSTLevelDBQueryCache.h" - #import "Firestore/Source/Core/FSTQuery.h" #import "Firestore/Source/Local/FSTLevelDB.h" #import "Firestore/Source/Local/FSTQueryData.h" @@ -55,7 +53,7 @@ @interface FSTLevelDBQueryCacheTests : FSTQueryCacheTests @implementation FSTLevelDBQueryCacheTests - (LevelDbQueryCache *)getCache:(id)persistence { - return ((FSTLevelDBQueryCache *)([persistence queryCache])).cache; + return static_cast(persistence.queryCache); } - (void)setUp { diff --git a/Firestore/Example/Tests/Local/FSTLocalStoreTests.mm b/Firestore/Example/Tests/Local/FSTLocalStoreTests.mm index 5cff444f6bf..3caa80bf6ef 100644 --- a/Firestore/Example/Tests/Local/FSTLocalStoreTests.mm +++ b/Firestore/Example/Tests/Local/FSTLocalStoreTests.mm @@ -22,7 +22,6 @@ #import "Firestore/Source/Core/FSTQuery.h" #import "Firestore/Source/Local/FSTLocalWriteResult.h" #import "Firestore/Source/Local/FSTPersistence.h" -#import "Firestore/Source/Local/FSTQueryCache.h" #import "Firestore/Source/Local/FSTQueryData.h" #import "Firestore/Source/Model/FSTDocument.h" #import "Firestore/Source/Model/FSTDocumentSet.h" diff --git a/Firestore/Example/Tests/Local/FSTMemoryQueryCacheTests.mm b/Firestore/Example/Tests/Local/FSTMemoryQueryCacheTests.mm index 4ffb39e8cfa..b98b5c3a8aa 100644 --- a/Firestore/Example/Tests/Local/FSTMemoryQueryCacheTests.mm +++ b/Firestore/Example/Tests/Local/FSTMemoryQueryCacheTests.mm @@ -14,8 +14,6 @@ * limitations under the License. */ -#import "Firestore/Source/Local/FSTMemoryQueryCache.h" - #import "Firestore/Source/Local/FSTMemoryPersistence.h" #import "Firestore/Example/Tests/Local/FSTPersistenceTestHelpers.h" @@ -37,7 +35,7 @@ - (void)setUp { [super setUp]; self.persistence = [FSTPersistenceTestHelpers eagerGCMemoryPersistence]; - self.queryCache = ((FSTMemoryQueryCache *)([self.persistence queryCache])).cache; + self.queryCache = self.persistence.queryCache; } - (void)tearDown { diff --git a/Firestore/Source/Local/FSTLRUGarbageCollector.h b/Firestore/Source/Local/FSTLRUGarbageCollector.h index 1eeb5e6bd32..69c8fa85248 100644 --- a/Firestore/Source/Local/FSTLRUGarbageCollector.h +++ b/Firestore/Source/Local/FSTLRUGarbageCollector.h @@ -23,8 +23,6 @@ #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/model/types.h" -@protocol FSTQueryCache; - @class FSTLRUGarbageCollector; extern const firebase::firestore::model::ListenSequenceNumber kFSTListenSequenceNumberInvalid; @@ -108,7 +106,7 @@ struct LruResults { - (size_t)byteSize; /** Returns the number of targets and orphaned documents cached. */ -- (int32_t)sequenceNumberCount; +- (size_t)sequenceNumberCount; /** Access to the underlying LRU Garbage collector instance. */ @property(strong, nonatomic, readonly) FSTLRUGarbageCollector *gc; diff --git a/Firestore/Source/Local/FSTLRUGarbageCollector.mm b/Firestore/Source/Local/FSTLRUGarbageCollector.mm index cc368fd3f8f..3f2ba121004 100644 --- a/Firestore/Source/Local/FSTLRUGarbageCollector.mm +++ b/Firestore/Source/Local/FSTLRUGarbageCollector.mm @@ -22,7 +22,6 @@ #import "Firestore/Source/Local/FSTMutationQueue.h" #import "Firestore/Source/Local/FSTPersistence.h" -#import "Firestore/Source/Local/FSTQueryCache.h" #include "Firestore/core/include/firebase/firestore/timestamp.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/util/log.h" @@ -148,7 +147,7 @@ - (LruResults)runGCWithLiveTargets:(NSDictionary *)l } - (int)queryCountForPercentile:(NSUInteger)percentile { - int totalCount = [_delegate sequenceNumberCount]; + size_t totalCount = [_delegate sequenceNumberCount]; int setSize = (int)((percentile / 100.0f) * totalCount); return setSize; } diff --git a/Firestore/Source/Local/FSTLevelDB.mm b/Firestore/Source/Local/FSTLevelDB.mm index 365b36fe5a5..a05056cf759 100644 --- a/Firestore/Source/Local/FSTLevelDB.mm +++ b/Firestore/Source/Local/FSTLevelDB.mm @@ -23,7 +23,6 @@ #import "Firestore/Source/Core/FSTListenSequence.h" #import "Firestore/Source/Local/FSTLRUGarbageCollector.h" #import "Firestore/Source/Local/FSTLevelDBMutationQueue.h" -#import "Firestore/Source/Local/FSTLevelDBQueryCache.h" #import "Firestore/Source/Local/FSTReferenceSet.h" #import "Firestore/Source/Remote/FSTSerializerBeta.h" @@ -32,6 +31,7 @@ #include "Firestore/core/src/firebase/firestore/core/database_info.h" #include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" #include "Firestore/core/src/firebase/firestore/local/leveldb_migrations.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h" #include "Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.h" #include "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h" #include "Firestore/core/src/firebase/firestore/local/leveldb_util.h" @@ -61,6 +61,7 @@ using firebase::firestore::local::LevelDbDocumentTargetKey; using firebase::firestore::local::LevelDbMigrations; using firebase::firestore::local::LevelDbMutationKey; +using firebase::firestore::local::LevelDbQueryCache; using firebase::firestore::local::LevelDbRemoteDocumentCache; using firebase::firestore::local::LevelDbTransaction; using firebase::firestore::local::LruParams; @@ -87,6 +88,8 @@ - (size_t)byteSize; @property(nonatomic, assign, getter=isStarted) BOOL started; +- (firebase::firestore::local::LevelDbQueryCache *)queryCache; + @end /** @@ -125,7 +128,7 @@ - (instancetype)initWithPersistence:(FSTLevelDB *)persistence lruParams:(LruPara } - (void)start { - ListenSequenceNumber highestSequenceNumber = _db.queryCache.highestListenSequenceNumber; + ListenSequenceNumber highestSequenceNumber = _db.queryCache->highest_listen_sequence_number(); _listenSequence = [[FSTListenSequence alloc] initStartingAfter:highestSequenceNumber]; } @@ -156,7 +159,7 @@ - (void)removeTarget:(FSTQueryData *)queryData { [queryData queryDataByReplacingSnapshotVersion:queryData.snapshotVersion resumeToken:queryData.resumeToken sequenceNumber:[self currentSequenceNumber]]; - [_db.queryCache updateQueryData:updated]; + _db.queryCache->UpdateTarget(updated); } - (void)addReference:(const DocumentKey &)key { @@ -195,29 +198,26 @@ - (BOOL)isPinned:(const DocumentKey &)docKey { } - (void)enumerateTargetsUsingBlock:(void (^)(FSTQueryData *queryData, BOOL *stop))block { - FSTLevelDBQueryCache *queryCache = _db.queryCache; - [queryCache enumerateTargetsUsingBlock:block]; + _db.queryCache->EnumerateTargets(block); } - (void)enumerateMutationsUsingBlock: (void (^)(const DocumentKey &key, ListenSequenceNumber sequenceNumber, BOOL *stop))block { - FSTLevelDBQueryCache *queryCache = _db.queryCache; - [queryCache enumerateOrphanedDocumentsUsingBlock:block]; + _db.queryCache->EnumerateOrphanedDocuments(block); } - (int)removeOrphanedDocumentsThroughSequenceNumber:(ListenSequenceNumber)upperBound { - FSTLevelDBQueryCache *queryCache = _db.queryCache; __block int count = 0; - [queryCache enumerateOrphanedDocumentsUsingBlock:^( - const DocumentKey &docKey, ListenSequenceNumber sequenceNumber, BOOL *stop) { - if (sequenceNumber <= upperBound) { - if (![self isPinned:docKey]) { - count++; - self->_db.remoteDocumentCache->Remove(docKey); - [self removeSentinel:docKey]; - } - } - }]; + _db.queryCache->EnumerateOrphanedDocuments( + ^(const DocumentKey &docKey, ListenSequenceNumber sequenceNumber, BOOL *stop) { + if (sequenceNumber <= upperBound) { + if (![self isPinned:docKey]) { + count++; + self->_db.remoteDocumentCache->Remove(docKey); + [self removeSentinel:docKey]; + } + } + }); return count; } @@ -227,12 +227,11 @@ - (void)removeSentinel:(const DocumentKey &)key { - (int)removeTargetsThroughSequenceNumber:(ListenSequenceNumber)sequenceNumber liveQueries:(NSDictionary *)liveQueries { - FSTLevelDBQueryCache *queryCache = _db.queryCache; - return [queryCache removeQueriesThroughSequenceNumber:sequenceNumber liveQueries:liveQueries]; + return _db.queryCache->RemoveTargets(sequenceNumber, liveQueries); } -- (int32_t)sequenceNumberCount { - __block int32_t totalCount = [_db.queryCache count]; +- (size_t)sequenceNumberCount { + __block size_t totalCount = _db.queryCache->size(); [self enumerateMutationsUsingBlock:^(const DocumentKey &key, ListenSequenceNumber sequenceNumber, BOOL *stop) { totalCount++; @@ -272,7 +271,7 @@ @implementation FSTLevelDB { std::unique_ptr _documentCache; FSTTransactionRunner _transactionRunner; FSTLevelDBLRUDelegate *_referenceDelegate; - FSTLevelDBQueryCache *_queryCache; + std::unique_ptr _queryCache; std::set _users; } @@ -339,14 +338,14 @@ - (instancetype)initWithLevelDB:(std::unique_ptr)db _ptr = std::move(db); _directory = std::move(directory); _serializer = serializer; - _queryCache = [[FSTLevelDBQueryCache alloc] initWithDB:self serializer:self.serializer]; + _queryCache = absl::make_unique(self, _serializer); _documentCache = absl::make_unique(self, _serializer); _referenceDelegate = [[FSTLevelDBLRUDelegate alloc] initWithPersistence:self lruParams:lruParams]; _transactionRunner.SetBackingPersistence(self); _users = std::move(users); // TODO(gsoltis): set up a leveldb transaction for these operations. - [_queryCache start]; + _queryCache->Start(); [_referenceDelegate start]; } return self; @@ -462,8 +461,8 @@ - (LevelDbTransaction *)currentTransaction { return [FSTLevelDBMutationQueue mutationQueueWithUser:user db:self serializer:self.serializer]; } -- (id)queryCache { - return _queryCache; +- (LevelDbQueryCache *)queryCache { + return _queryCache.get(); } - (RemoteDocumentCache *)remoteDocumentCache { diff --git a/Firestore/Source/Local/FSTLevelDBQueryCache.h b/Firestore/Source/Local/FSTLevelDBQueryCache.h deleted file mode 100644 index 91e9693f4e2..00000000000 --- a/Firestore/Source/Local/FSTLevelDBQueryCache.h +++ /dev/null @@ -1,65 +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 - -#include - -#import "Firestore/Source/Local/FSTQueryCache.h" -#include "Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h" -#include "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h" -#include "Firestore/core/src/firebase/firestore/model/types.h" -#include "leveldb/db.h" - -@class FSTLevelDB; -@class FSTLocalSerializer; -@class FSTPBTargetGlobal; - -NS_ASSUME_NONNULL_BEGIN - -/** Cached Queries backed by LevelDB. */ -@interface FSTLevelDBQueryCache : NSObject - -/** - * Retrieves the global singleton metadata row from the given database, if it exists. - * TODO(gsoltis): remove this method once fully ported to transactions. - */ -+ (nullable FSTPBTargetGlobal *)readTargetMetadataFromDB:(leveldb::DB *)db; - -- (instancetype)init NS_UNAVAILABLE; - -/** - * Creates a new query cache in the given LevelDB. - * - * @param db The LevelDB in which to create the cache. - */ -- (instancetype)initWithDB:(FSTLevelDB *)db - serializer:(FSTLocalSerializer *)serializer NS_DESIGNATED_INITIALIZER; - -/** Starts the query cache up. */ -- (void)start; - -- (void)enumerateOrphanedDocumentsUsingBlock: - (void (^)(const firebase::firestore::model::DocumentKey &docKey, - firebase::firestore::model::ListenSequenceNumber sequenceNumber, - BOOL *stop))block; - -// Visible for testing, will go away when this class is fully ported. -@property(readonly, nonatomic) firebase::firestore::local::LevelDbQueryCache *cache; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Local/FSTLevelDBQueryCache.mm b/Firestore/Source/Local/FSTLevelDBQueryCache.mm deleted file mode 100644 index 9899db9f06b..00000000000 --- a/Firestore/Source/Local/FSTLevelDBQueryCache.mm +++ /dev/null @@ -1,156 +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/FSTLevelDBQueryCache.h" - -#include -#include -#include - -#import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h" -#import "Firestore/Source/Core/FSTQuery.h" -#import "Firestore/Source/Local/FSTLevelDB.h" -#import "Firestore/Source/Local/FSTLocalSerializer.h" -#import "Firestore/Source/Local/FSTQueryData.h" - -#include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" -#include "Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h" -#include "Firestore/core/src/firebase/firestore/model/document_key.h" -#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" -#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" -#include "absl/memory/memory.h" -#include "absl/strings/match.h" - -NS_ASSUME_NONNULL_BEGIN - -using firebase::firestore::local::DescribeKey; -using firebase::firestore::local::LevelDbDocumentTargetKey; -using firebase::firestore::local::LevelDbQueryTargetKey; -using firebase::firestore::local::LevelDbQueryCache; -using firebase::firestore::local::LevelDbTargetDocumentKey; -using firebase::firestore::local::LevelDbTargetGlobalKey; -using firebase::firestore::local::LevelDbTargetKey; -using firebase::firestore::local::LevelDbTransaction; -using firebase::firestore::model::DocumentKey; -using firebase::firestore::model::DocumentKeySet; -using firebase::firestore::model::ListenSequenceNumber; -using firebase::firestore::model::SnapshotVersion; -using firebase::firestore::model::TargetId; -using leveldb::DB; -using leveldb::Slice; -using leveldb::Status; - -@implementation FSTLevelDBQueryCache { - std::unique_ptr _cache; -} - -+ (nullable FSTPBTargetGlobal *)readTargetMetadataFromDB:(DB *)db { - return LevelDbQueryCache::ReadMetadata(db); -} - -- (instancetype)initWithDB:(FSTLevelDB *)db serializer:(FSTLocalSerializer *)serializer { - if (self = [super init]) { - HARD_ASSERT(db, "db must not be NULL"); - _cache = absl::make_unique(db, serializer); - } - return self; -} - -- (void)start { - _cache->Start(); -} - -- (LevelDbQueryCache *)cache { - return _cache.get(); -} - -#pragma mark - FSTQueryCache implementation - -- (TargetId)highestTargetID { - return _cache->highest_target_id(); -} - -- (ListenSequenceNumber)highestListenSequenceNumber { - return _cache->highest_listen_sequence_number(); -} - -- (const SnapshotVersion &)lastRemoteSnapshotVersion { - return _cache->GetLastRemoteSnapshotVersion(); -} - -- (void)setLastRemoteSnapshotVersion:(SnapshotVersion)snapshotVersion { - _cache->SetLastRemoteSnapshotVersion(std::move(snapshotVersion)); -} - -- (void)enumerateTargetsUsingBlock:(void (^)(FSTQueryData *queryData, BOOL *stop))block { - _cache->EnumerateTargets(block); -} - -- (void)enumerateOrphanedDocumentsUsingBlock: - (void (^)(const DocumentKey &docKey, ListenSequenceNumber sequenceNumber, BOOL *stop))block { - _cache->EnumerateOrphanedDocuments(block); -} - -- (void)addQueryData:(FSTQueryData *)queryData { - _cache->AddTarget(queryData); -} - -- (void)updateQueryData:(FSTQueryData *)queryData { - _cache->UpdateTarget(queryData); -} - -- (void)removeQueryData:(FSTQueryData *)queryData { - _cache->RemoveTarget(queryData); -} - -- (int)removeQueriesThroughSequenceNumber:(ListenSequenceNumber)sequenceNumber - liveQueries:(NSDictionary *)liveQueries { - return _cache->RemoveTargets(sequenceNumber, liveQueries); -} - -- (int32_t)count { - return _cache->size(); -} - -- (nullable FSTQueryData *)queryDataForQuery:(FSTQuery *)query { - return _cache->GetTarget(query); -} - -#pragma mark Matching Key tracking - -- (void)addMatchingKeys:(const DocumentKeySet &)keys forTargetID:(TargetId)targetID { - _cache->AddMatchingKeys(keys, targetID); -} - -- (void)removeMatchingKeys:(const DocumentKeySet &)keys forTargetID:(TargetId)targetID { - _cache->RemoveMatchingKeys(keys, targetID); -} - -- (void)removeMatchingKeysForTargetID:(TargetId)targetID { - _cache->RemoveAllKeysForTarget(targetID); -} - -- (DocumentKeySet)matchingKeysForTargetID:(TargetId)targetID { - return _cache->GetMatchingKeys(targetID); -} - -- (BOOL)containsKey:(const DocumentKey &)key { - return _cache->Contains(key); -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Local/FSTLocalStore.mm b/Firestore/Source/Local/FSTLocalStore.mm index 684ce15543b..7385a855955 100644 --- a/Firestore/Source/Local/FSTLocalStore.mm +++ b/Firestore/Source/Local/FSTLocalStore.mm @@ -28,7 +28,6 @@ #import "Firestore/Source/Local/FSTLocalWriteResult.h" #import "Firestore/Source/Local/FSTMutationQueue.h" #import "Firestore/Source/Local/FSTPersistence.h" -#import "Firestore/Source/Local/FSTQueryCache.h" #import "Firestore/Source/Local/FSTQueryData.h" #import "Firestore/Source/Local/FSTReferenceSet.h" #import "Firestore/Source/Model/FSTDocument.h" @@ -39,6 +38,7 @@ #include "Firestore/core/src/firebase/firestore/auth/user.h" #include "Firestore/core/src/firebase/firestore/core/target_id_generator.h" #include "Firestore/core/src/firebase/firestore/immutable/sorted_set.h" +#include "Firestore/core/src/firebase/firestore/local/query_cache.h" #include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" #include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" #include "Firestore/core/src/firebase/firestore/util/hard_assert.h" @@ -47,6 +47,7 @@ using firebase::firestore::auth::User; using firebase::firestore::core::TargetIdGenerator; using firebase::firestore::local::LruResults; +using firebase::firestore::local::QueryCache; using firebase::firestore::local::RemoteDocumentCache; using firebase::firestore::model::BatchId; using firebase::firestore::model::DocumentKey; @@ -83,7 +84,7 @@ @interface FSTLocalStore () @property(nonatomic, strong) FSTReferenceSet *localViewReferences; /** Maps a query to the data about that query. */ -@property(nonatomic, strong) id queryCache; +@property(nonatomic) QueryCache *queryCache; /** Maps a targetID to data about its query. */ @property(nonatomic, strong) NSMutableDictionary *targetIDs; @@ -95,6 +96,7 @@ @implementation FSTLocalStore { TargetIdGenerator _targetIDGenerator; /** The set of all cached remote documents. */ RemoteDocumentCache *_remoteDocumentCache; + QueryCache *_queryCache; } - (instancetype)initWithPersistence:(id)persistence @@ -118,7 +120,7 @@ - (instancetype)initWithPersistence:(id)persistence - (void)start { [self startMutationQueue]; - TargetId targetID = [self.queryCache highestTargetID]; + TargetId targetID = _queryCache->highest_target_id(); _targetIDGenerator = TargetIdGenerator::QueryCacheTargetIdGenerator(targetID); } @@ -207,14 +209,13 @@ - (void)setLastStreamToken:(nullable NSData *)streamToken { } - (const SnapshotVersion &)lastRemoteSnapshotVersion { - return [self.queryCache lastRemoteSnapshotVersion]; + return self.queryCache->GetLastRemoteSnapshotVersion(); } - (MaybeDocumentMap)applyRemoteEvent:(FSTRemoteEvent *)remoteEvent { return self.persistence.run("Apply remote event", [&]() -> MaybeDocumentMap { // TODO(gsoltis): move the sequence number into the reference delegate. ListenSequenceNumber sequenceNumber = self.persistence.currentSequenceNumber; - id queryCache = self.queryCache; DocumentKeySet authoritativeUpdates; for (const auto &entry : remoteEvent.targetChanges) { @@ -243,8 +244,8 @@ - (MaybeDocumentMap)applyRemoteEvent:(FSTRemoteEvent *)remoteEvent { authoritativeUpdates = authoritativeUpdates.insert(key); } - [queryCache removeMatchingKeys:change.removedDocuments forTargetID:targetID]; - [queryCache addMatchingKeys:change.addedDocuments forTargetID:targetID]; + _queryCache->RemoveMatchingKeys(change.removedDocuments, targetID); + _queryCache->AddMatchingKeys(change.addedDocuments, targetID); // Update the resume token if the change includes one. Don't clear any preexisting value. // Bump the sequence number as well, so that documents being removed now are ordered later @@ -258,7 +259,7 @@ - (MaybeDocumentMap)applyRemoteEvent:(FSTRemoteEvent *)remoteEvent { self.targetIDs[boxedTargetID] = queryData; if ([self shouldPersistQueryData:queryData oldQueryData:oldQueryData change:change]) { - [self.queryCache updateQueryData:queryData]; + _queryCache->UpdateTarget(queryData); } } } @@ -307,13 +308,13 @@ - (MaybeDocumentMap)applyRemoteEvent:(FSTRemoteEvent *)remoteEvent { // 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. - const SnapshotVersion &lastRemoteVersion = [self.queryCache lastRemoteSnapshotVersion]; + const SnapshotVersion &lastRemoteVersion = _queryCache->GetLastRemoteSnapshotVersion(); const SnapshotVersion &remoteVersion = remoteEvent.snapshotVersion; if (remoteVersion != SnapshotVersion::None()) { HARD_ASSERT(remoteVersion >= lastRemoteVersion, "Watch stream reverted to previous snapshot?? (%s < %s)", remoteVersion.timestamp().ToString(), lastRemoteVersion.timestamp().ToString()); - [self.queryCache setLastRemoteSnapshotVersion:remoteVersion]; + _queryCache->SetLastRemoteSnapshotVersion(remoteVersion); } return [self.localDocuments localViewsForDocuments:changedDocs]; @@ -386,14 +387,14 @@ - (nullable FSTMaybeDocument *)readDocument:(const DocumentKey &)key { - (FSTQueryData *)allocateQuery:(FSTQuery *)query { FSTQueryData *queryData = self.persistence.run("Allocate query", [&]() -> FSTQueryData * { - FSTQueryData *cached = [self.queryCache queryDataForQuery:query]; + FSTQueryData *cached = _queryCache->GetTarget(query); // TODO(mcg): freshen last accessed date if cached exists? if (!cached) { cached = [[FSTQueryData alloc] initWithQuery:query targetID:_targetIDGenerator.NextId() listenSequenceNumber:self.persistence.currentSequenceNumber purpose:FSTQueryPurposeListen]; - [self.queryCache addQueryData:cached]; + _queryCache->AddTarget(cached); } return cached; }); @@ -407,7 +408,7 @@ - (FSTQueryData *)allocateQuery:(FSTQuery *)query { - (void)releaseQuery:(FSTQuery *)query { self.persistence.run("Release query", [&]() { - FSTQueryData *queryData = [self.queryCache queryDataForQuery:query]; + FSTQueryData *queryData = _queryCache->GetTarget(query); HARD_ASSERT(queryData, "Tried to release nonexistent query: %s", query); TargetId targetID = queryData.targetID; @@ -419,7 +420,7 @@ - (void)releaseQuery:(FSTQuery *)query { // conditions and rationale) we need to persist the token now because there will no // longer be an in-memory version to fall back on. queryData = cachedQueryData; - [self.queryCache updateQueryData:queryData]; + _queryCache->UpdateTarget(queryData); } // References for documents sent via Watch are automatically removed when we delete a @@ -443,7 +444,7 @@ - (DocumentMap)executeQuery:(FSTQuery *)query { - (DocumentKeySet)remoteDocumentKeysForTarget:(TargetId)targetID { return self.persistence.run("RemoteDocumentKeysForTarget", [&]() -> DocumentKeySet { - return [self.queryCache matchingKeysForTargetID:targetID]; + return _queryCache->GetMatchingKeys(targetID); }); } diff --git a/Firestore/Source/Local/FSTMemoryPersistence.mm b/Firestore/Source/Local/FSTMemoryPersistence.mm index d246f2a9c60..5c4771c7a74 100644 --- a/Firestore/Source/Local/FSTMemoryPersistence.mm +++ b/Firestore/Source/Local/FSTMemoryPersistence.mm @@ -23,11 +23,11 @@ #import "Firestore/Source/Core/FSTListenSequence.h" #import "Firestore/Source/Local/FSTMemoryMutationQueue.h" -#import "Firestore/Source/Local/FSTMemoryQueryCache.h" #import "Firestore/Source/Local/FSTReferenceSet.h" #include "absl/memory/memory.h" #include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/local/memory_query_cache.h" #include "Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/util/hard_assert.h" @@ -35,6 +35,7 @@ using firebase::firestore::auth::HashUser; using firebase::firestore::auth::User; using firebase::firestore::local::LruParams; +using firebase::firestore::local::MemoryQueryCache; using firebase::firestore::local::MemoryRemoteDocumentCache; using firebase::firestore::model::DocumentKey; using firebase::firestore::model::DocumentKeyHash; @@ -47,7 +48,7 @@ @interface FSTMemoryPersistence () -- (FSTMemoryQueryCache *)queryCache; +- (MemoryQueryCache *)queryCache; - (MemoryRemoteDocumentCache *)remoteDocumentCache; @@ -62,14 +63,14 @@ - (MemoryRemoteDocumentCache *)remoteDocumentCache; @implementation FSTMemoryPersistence { /** - * The FSTQueryCache representing the persisted cache of queries. + * The QueryCache representing the persisted cache of queries. * * Note that this is retained here to make it easier to write tests affecting both the in-memory * and LevelDB-backed persistence layers. Tests can create a new FSTLocalStore wrapping this * FSTPersistence instance and this will make the in-memory persistence layer behave as if it * were actually persisting values. */ - FSTMemoryQueryCache *_queryCache; + std::unique_ptr _queryCache; /** The RemoteDocumentCache representing the persisted cache of remote documents. */ MemoryRemoteDocumentCache _remoteDocumentCache; @@ -98,7 +99,7 @@ + (instancetype)persistenceWithLruParams:(firebase::firestore::local::LruParams) - (instancetype)init { if (self = [super init]) { - _queryCache = [[FSTMemoryQueryCache alloc] initWithPersistence:self]; + _queryCache = absl::make_unique(self); self.started = YES; } return self; @@ -139,8 +140,8 @@ - (ListenSequenceNumber)currentSequenceNumber { return queue; } -- (FSTMemoryQueryCache *)queryCache { - return _queryCache; +- (MemoryQueryCache *)queryCache { + return _queryCache.get(); } - (MemoryRemoteDocumentCache *)remoteDocumentCache { @@ -172,7 +173,7 @@ - (instancetype)initWithPersistence:(FSTMemoryPersistence *)persistence _currentSequenceNumber = kFSTListenSequenceNumberInvalid; // Theoretically this is always 0, since this is all in-memory... ListenSequenceNumber highestSequenceNumber = - _persistence.queryCache.highestListenSequenceNumber; + _persistence.queryCache->highest_listen_sequence_number(); _listenSequence = [[FSTListenSequence alloc] initStartingAfter:highestSequenceNumber]; _serializer = serializer; } @@ -199,7 +200,7 @@ - (void)removeTarget:(FSTQueryData *)queryData { FSTQueryData *updated = [queryData queryDataByReplacingSnapshotVersion:queryData.snapshotVersion resumeToken:queryData.resumeToken sequenceNumber:_currentSequenceNumber]; - [_persistence.queryCache updateQueryData:updated]; + _persistence.queryCache->UpdateTarget(updated); } - (void)limboDocumentUpdated:(const DocumentKey &)key { @@ -215,7 +216,7 @@ - (void)commitTransaction { } - (void)enumerateTargetsUsingBlock:(void (^)(FSTQueryData *queryData, BOOL *stop))block { - return [_persistence.queryCache enumerateTargetsUsingBlock:block]; + return _persistence.queryCache->EnumerateTargets(block); } - (void)enumerateMutationsUsingBlock: @@ -234,12 +235,11 @@ - (void)enumerateMutationsUsingBlock: - (int)removeTargetsThroughSequenceNumber:(ListenSequenceNumber)sequenceNumber liveQueries:(NSDictionary *)liveQueries { - return [_persistence.queryCache removeQueriesThroughSequenceNumber:sequenceNumber - liveQueries:liveQueries]; + return _persistence.queryCache->RemoveTargets(sequenceNumber, liveQueries); } -- (int32_t)sequenceNumberCount { - __block int32_t totalCount = [_persistence.queryCache count]; +- (size_t)sequenceNumberCount { + __block size_t totalCount = _persistence.queryCache->size(); [self enumerateMutationsUsingBlock:^(const DocumentKey &key, ListenSequenceNumber sequenceNumber, BOOL *stop) { totalCount++; @@ -286,7 +286,7 @@ - (BOOL)isPinnedAtSequenceNumber:(ListenSequenceNumber)upperBound if ([_additionalReferences containsKey:key]) { return YES; } - if ([_persistence.queryCache containsKey:key]) { + if (_persistence.queryCache->Contains(key)) { return YES; } auto it = _sequenceNumbers.find(key); @@ -301,7 +301,7 @@ - (size_t)byteSize { // used for testing. The algorithm here (loop through everything, serialize it // and count bytes) is inefficient and inexact, but won't run in production. size_t count = 0; - count += [_persistence.queryCache byteSizeWithSerializer:_serializer]; + count += _persistence.queryCache->CalculateByteSize(_serializer); count += _persistence.remoteDocumentCache->CalculateByteSize(_serializer); const MutationQueues &queues = [_persistence mutationQueues]; for (const auto &entry : queues) { @@ -338,11 +338,10 @@ - (void)addInMemoryPins:(FSTReferenceSet *)set { } - (void)removeTarget:(FSTQueryData *)queryData { - for (const DocumentKey &docKey : - [_persistence.queryCache matchingKeysForTargetID:queryData.targetID]) { + for (const DocumentKey &docKey : _persistence.queryCache->GetMatchingKeys(queryData.targetID)) { _orphaned->insert(docKey); } - [_persistence.queryCache removeQueryData:queryData]; + _persistence.queryCache->RemoveTarget(queryData); } - (void)addReference:(const DocumentKey &)key { @@ -358,7 +357,7 @@ - (void)removeMutationReference:(const DocumentKey &)key { } - (BOOL)isReferenced:(const DocumentKey &)key { - if ([[_persistence queryCache] containsKey:key]) { + if (_persistence.queryCache->Contains(key)) { return YES; } if ([self mutationQueuesContainKey:key]) { diff --git a/Firestore/Source/Local/FSTMemoryQueryCache.h b/Firestore/Source/Local/FSTMemoryQueryCache.h deleted file mode 100644 index 3ad9e6a8c12..00000000000 --- a/Firestore/Source/Local/FSTMemoryQueryCache.h +++ /dev/null @@ -1,44 +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 - -#import "Firestore/Source/Local/FSTQueryCache.h" -#include "Firestore/core/src/firebase/firestore/local/memory_query_cache.h" - -NS_ASSUME_NONNULL_BEGIN - -@class FSTLocalSerializer; -@class FSTMemoryPersistence; - -/** - * An implementation of the FSTQueryCache protocol that merely keeps queries in memory, suitable - * for online only clients with persistence disabled. - */ -@interface FSTMemoryQueryCache : NSObject - -- (instancetype)initWithPersistence:(FSTMemoryPersistence *)persistence NS_DESIGNATED_INITIALIZER; - -- (instancetype)init NS_UNAVAILABLE; - -- (size_t)byteSizeWithSerializer:(FSTLocalSerializer *)serializer; - -// Visible for testing, will go away when this class is fully ported. -@property(readonly, nonatomic) firebase::firestore::local::MemoryQueryCache *cache; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Local/FSTMemoryQueryCache.mm b/Firestore/Source/Local/FSTMemoryQueryCache.mm deleted file mode 100644 index e38ac4d830e..00000000000 --- a/Firestore/Source/Local/FSTMemoryQueryCache.mm +++ /dev/null @@ -1,131 +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/FSTMemoryQueryCache.h" - -#import - -#include -#include - -#import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h" -#import "Firestore/Source/Core/FSTQuery.h" -#import "Firestore/Source/Local/FSTMemoryPersistence.h" -#import "Firestore/Source/Local/FSTQueryData.h" -#import "Firestore/Source/Local/FSTReferenceSet.h" - -#include "Firestore/core/src/firebase/firestore/local/memory_query_cache.h" -#include "Firestore/core/src/firebase/firestore/model/document_key.h" -#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" -#include "absl/memory/memory.h" - -using firebase::firestore::local::MemoryQueryCache; -using firebase::firestore::model::DocumentKey; -using firebase::firestore::model::DocumentKeySet; -using firebase::firestore::model::ListenSequenceNumber; -using firebase::firestore::model::SnapshotVersion; -using firebase::firestore::model::TargetId; - -NS_ASSUME_NONNULL_BEGIN - -@implementation FSTMemoryQueryCache { - std::unique_ptr _cache; -} - -- (MemoryQueryCache *)cache { - return _cache.get(); -} - -- (instancetype)initWithPersistence:(FSTMemoryPersistence *)persistence { - if (self = [super init]) { - _cache = absl::make_unique(persistence); - } - return self; -} - -#pragma mark - FSTQueryCache implementation -#pragma mark Query tracking - -- (TargetId)highestTargetID { - return _cache->highest_target_id(); -} - -- (ListenSequenceNumber)highestListenSequenceNumber { - return _cache->highest_listen_sequence_number(); -} - -- (const SnapshotVersion &)lastRemoteSnapshotVersion { - return _cache->GetLastRemoteSnapshotVersion(); -} - -- (void)setLastRemoteSnapshotVersion:(SnapshotVersion)snapshotVersion { - _cache->SetLastRemoteSnapshotVersion(std::move(snapshotVersion)); -} - -- (void)addQueryData:(FSTQueryData *)queryData { - _cache->AddTarget(queryData); -} - -- (void)updateQueryData:(FSTQueryData *)queryData { - _cache->UpdateTarget(queryData); -} - -- (int32_t)count { - return _cache->size(); -} - -- (void)removeQueryData:(FSTQueryData *)queryData { - _cache->RemoveTarget(queryData); -} - -- (nullable FSTQueryData *)queryDataForQuery:(FSTQuery *)query { - return _cache->GetTarget(query); -} - -- (void)enumerateTargetsUsingBlock:(void (^)(FSTQueryData *queryData, BOOL *stop))block { - _cache->EnumerateTargets(block); -} - -- (int)removeQueriesThroughSequenceNumber:(ListenSequenceNumber)sequenceNumber - liveQueries:(NSDictionary *)liveQueries { - return _cache->RemoveTargets(sequenceNumber, liveQueries); -} - -#pragma mark Reference tracking - -- (void)addMatchingKeys:(const DocumentKeySet &)keys forTargetID:(TargetId)targetID { - _cache->AddMatchingKeys(keys, targetID); -} - -- (void)removeMatchingKeys:(const DocumentKeySet &)keys forTargetID:(TargetId)targetID { - _cache->RemoveMatchingKeys(keys, targetID); -} - -- (DocumentKeySet)matchingKeysForTargetID:(TargetId)targetID { - return _cache->GetMatchingKeys(targetID); -} - -- (BOOL)containsKey:(const firebase::firestore::model::DocumentKey &)key { - return _cache->Contains(key); -} - -- (size_t)byteSizeWithSerializer:(FSTLocalSerializer *)serializer { - return _cache->CalculateByteSize(serializer); -} - -@end - -NS_ASSUME_NONNULL_END diff --git a/Firestore/Source/Local/FSTPersistence.h b/Firestore/Source/Local/FSTPersistence.h index 8c9b7a62136..bcd6b71cedb 100644 --- a/Firestore/Source/Local/FSTPersistence.h +++ b/Firestore/Source/Local/FSTPersistence.h @@ -17,6 +17,7 @@ #import #include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/local/query_cache.h" #include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" #include "Firestore/core/src/firebase/firestore/model/document_key.h" #include "Firestore/core/src/firebase/firestore/model/types.h" @@ -26,7 +27,6 @@ @class FSTQueryData; @class FSTReferenceSet; @protocol FSTMutationQueue; -@protocol FSTQueryCache; @protocol FSTReferenceDelegate; struct FSTTransactionRunner; @@ -79,7 +79,7 @@ NS_ASSUME_NONNULL_BEGIN - (id)mutationQueueForUser:(const firebase::firestore::auth::User &)user; /** Creates an FSTQueryCache representing the persisted cache of queries. */ -- (id)queryCache; +- (firebase::firestore::local::QueryCache *)queryCache; /** Creates an FSTRemoteDocumentCache representing the persisted cache of remote documents. */ - (firebase::firestore::local::RemoteDocumentCache *)remoteDocumentCache; diff --git a/Firestore/Source/Local/FSTQueryCache.h b/Firestore/Source/Local/FSTQueryCache.h deleted file mode 100644 index ac2de98c48f..00000000000 --- a/Firestore/Source/Local/FSTQueryCache.h +++ /dev/null @@ -1,126 +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 - -#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" -#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" -#include "Firestore/core/src/firebase/firestore/model/types.h" - -@class FSTDocumentSet; -@class FSTMaybeDocument; -@class FSTQuery; -@class FSTQueryData; - -NS_ASSUME_NONNULL_BEGIN - -/** - * Represents cached queries received from the remote backend. This contains both a mapping between - * queries and the documents that matched them according to the server, but also metadata about the - * queries. - * - * The cache is keyed by FSTQuery and entries in the cache are FSTQueryData instances. - */ -@protocol FSTQueryCache - -/** - * Returns the highest target ID of any query in the cache. Typically called during startup to - * seed a target ID generator and avoid collisions with existing queries. If there are no queries - * in the cache, returns zero. - */ -- (firebase::firestore::model::TargetId)highestTargetID; - -/** - * Returns the highest listen sequence number of any query seen by the cache. - */ -- (firebase::firestore::model::ListenSequenceNumber)highestListenSequenceNumber; - -/** - * A global snapshot version representing the last consistent snapshot we received from the - * backend. This is monotonically increasing and any snapshots received from the backend prior to - * this version (e.g. for targets resumed with a resume_token) should be suppressed (buffered) - * until the backend has caught up to this snapshot version again. This prevents our cache from - * ever going backwards in time. - * - * This is updated whenever our we get a TargetChange with a read_time and empty target_ids. - */ -- (const firebase::firestore::model::SnapshotVersion &)lastRemoteSnapshotVersion; - -/** - * Set the snapshot version representing the last consistent snapshot received from the backend. - * (see -lastRemoteSnapshotVersion for more details). - * - * @param snapshotVersion The new snapshot version. - */ -- (void)setLastRemoteSnapshotVersion:(firebase::firestore::model::SnapshotVersion)snapshotVersion; - -/** - * Adds an entry in the cache. - * - * The cache key is extracted from `queryData.query`. The key must not already exist in the cache. - * - * @param queryData A new FSTQueryData instance to put in the cache. - */ -- (void)addQueryData:(FSTQueryData *)queryData; - -/** - * Updates an entry in the cache. - * - * The cache key is extracted from `queryData.query`. The entry must already exist in the cache, - * and it will be replaced. - * @param queryData An FSTQueryData instance to replace an existing entry in the cache - */ -- (void)updateQueryData:(FSTQueryData *)queryData; - -/** Removes the cached entry for the given query data (no-op if no entry exists). */ -- (void)removeQueryData:(FSTQueryData *)queryData; - -- (void)enumerateTargetsUsingBlock:(void (^)(FSTQueryData *queryData, BOOL *stop))block; - -- (int)removeQueriesThroughSequenceNumber: - (firebase::firestore::model::ListenSequenceNumber)sequenceNumber - liveQueries:(NSDictionary *)liveQueries; - -/** Returns the number of targets cached. */ -- (int32_t)count; - -/** - * Looks up an FSTQueryData entry in the cache. - * - * @param query The query corresponding to the entry to look up. - * @return The cached FSTQueryData entry, or nil if the cache has no entry for the query. - */ -- (nullable FSTQueryData *)queryDataForQuery:(FSTQuery *)query; - -/** Adds the given document keys to cached query results of the given target ID. */ -- (void)addMatchingKeys:(const firebase::firestore::model::DocumentKeySet &)keys - forTargetID:(firebase::firestore::model::TargetId)targetID; - -/** Removes the given document keys from the cached query results of the given target ID. */ -- (void)removeMatchingKeys:(const firebase::firestore::model::DocumentKeySet &)keys - forTargetID:(firebase::firestore::model::TargetId)targetID; - -- (firebase::firestore::model::DocumentKeySet)matchingKeysForTargetID: - (firebase::firestore::model::TargetId)targetID; - -/** - * Checks to see if there are any references to a document with the given key. - */ -- (BOOL)containsKey:(const firebase::firestore::model::DocumentKey &)key; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h b/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h index 00dc1eb91ae..136d22805c3 100644 --- a/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h +++ b/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h @@ -102,7 +102,7 @@ class LevelDbQueryCache : public QueryCache { bool Contains(const model::DocumentKey& key) override; // Other methods and accessors - int32_t size() const override { + size_t size() const override { return metadata_.targetCount; } diff --git a/Firestore/core/src/firebase/firestore/local/memory_query_cache.h b/Firestore/core/src/firebase/firestore/local/memory_query_cache.h index bd3b2e7ae2b..da08f2876fd 100644 --- a/Firestore/core/src/firebase/firestore/local/memory_query_cache.h +++ b/Firestore/core/src/firebase/firestore/local/memory_query_cache.h @@ -76,8 +76,8 @@ class MemoryQueryCache : public QueryCache { // Other methods and accessors size_t CalculateByteSize(FSTLocalSerializer* serializer); - int32_t size() const override { - return static_cast([queries_ count]); + size_t size() const override { + return [queries_ count]; } model::ListenSequenceNumber highest_listen_sequence_number() const override { diff --git a/Firestore/core/src/firebase/firestore/local/query_cache.h b/Firestore/core/src/firebase/firestore/local/query_cache.h index 5d7d4c15657..9060713af1f 100644 --- a/Firestore/core/src/firebase/firestore/local/query_cache.h +++ b/Firestore/core/src/firebase/firestore/local/query_cache.h @@ -107,7 +107,7 @@ class QueryCache { // Accessors /** Returns the number of targets cached. */ - virtual int32_t size() const = 0; + virtual size_t size() const = 0; /** * Returns the highest listen sequence number of any query seen by the cache.