|
21 | 21 | #include <string> |
22 | 22 |
|
23 | 23 | #import "Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h" |
| 24 | +#import "Firestore/Source/Core/FSTQuery.h" |
24 | 25 | #import "Firestore/Source/Local/FSTLevelDBKey.h" |
25 | 26 | #import "Firestore/Source/Local/FSTLocalSerializer.h" |
26 | 27 | #import "Firestore/Source/Local/FSTWriteGroup.h" |
27 | 28 | #import "Firestore/Source/Model/FSTDocument.h" |
28 | 29 | #import "Firestore/Source/Model/FSTDocumentDictionary.h" |
29 | 30 | #import "Firestore/Source/Model/FSTDocumentKey.h" |
30 | 31 | #import "Firestore/Source/Model/FSTDocumentSet.h" |
| 32 | +#import "Firestore/Source/Model/FSTPath.h" |
31 | 33 | #import "Firestore/Source/Util/FSTAssert.h" |
32 | 34 |
|
33 | 35 | #include "Firestore/Port/ordered_code.h" |
@@ -102,18 +104,21 @@ - (nullable FSTMaybeDocument *)entryForKey:(FSTDocumentKey *)documentKey { |
102 | 104 | } |
103 | 105 |
|
104 | 106 | - (FSTDocumentDictionary *)documentsMatchingQuery:(FSTQuery *)query { |
105 | | - // TODO(mikelehen): PERF: At least filter to the documents that match the path of the query. |
106 | 107 | FSTDocumentDictionary *results = [FSTDocumentDictionary documentDictionary]; |
107 | 108 |
|
108 | | - std::string startKey = [FSTLevelDBRemoteDocumentKey keyPrefix]; |
| 109 | + // Documents are ordered by key, so we can use a prefix scan to narrow down |
| 110 | + // the documents we need to match the query against. |
| 111 | + std::string startKey = [FSTLevelDBRemoteDocumentKey keyPrefixWithResourcePath:query.path]; |
109 | 112 | std::unique_ptr<Iterator> it(_db->NewIterator(StandardReadOptions())); |
110 | 113 | it->Seek(startKey); |
111 | 114 |
|
112 | 115 | FSTLevelDBRemoteDocumentKey *currentKey = [[FSTLevelDBRemoteDocumentKey alloc] init]; |
113 | 116 | for (; it->Valid() && [currentKey decodeKey:it->key()]; it->Next()) { |
114 | 117 | FSTMaybeDocument *maybeDoc = |
115 | 118 | [self decodedMaybeDocument:it->value() withKey:currentKey.documentKey]; |
116 | | - if ([maybeDoc isKindOfClass:[FSTDocument class]]) { |
| 119 | + if (![query.path isPrefixOfPath:maybeDoc.key.path]) { |
| 120 | + break; |
| 121 | + } else if ([maybeDoc isKindOfClass:[FSTDocument class]]) { |
117 | 122 | results = [results dictionaryBySettingObject:(FSTDocument *)maybeDoc forKey:maybeDoc.key]; |
118 | 123 | } |
119 | 124 | } |
|
0 commit comments