FSTReferenceSet.mm 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright 2017 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "Firestore/Source/Local/FSTReferenceSet.h"
  17. #import "Firestore/Source/Local/FSTDocumentReference.h"
  18. #import "Firestore/third_party/Immutable/FSTImmutableSortedSet.h"
  19. #include "Firestore/core/src/firebase/firestore/model/document_key.h"
  20. using firebase::firestore::model::DocumentKey;
  21. using firebase::firestore::model::DocumentKeySet;
  22. NS_ASSUME_NONNULL_BEGIN
  23. #pragma mark - FSTReferenceSet
  24. @interface FSTReferenceSet ()
  25. /** A set of outstanding references to a document sorted by key. */
  26. @property(nonatomic, strong) FSTImmutableSortedSet<FSTDocumentReference *> *referencesByKey;
  27. /** A set of outstanding references to a document sorted by target ID (or batch ID). */
  28. @property(nonatomic, strong) FSTImmutableSortedSet<FSTDocumentReference *> *referencesByID;
  29. @end
  30. @implementation FSTReferenceSet
  31. #pragma mark - Initializer
  32. - (instancetype)init {
  33. self = [super init];
  34. if (self) {
  35. _referencesByKey =
  36. [FSTImmutableSortedSet setWithComparator:FSTDocumentReferenceComparatorByKey];
  37. _referencesByID = [FSTImmutableSortedSet setWithComparator:FSTDocumentReferenceComparatorByID];
  38. }
  39. return self;
  40. }
  41. #pragma mark - Testing helper methods
  42. - (BOOL)isEmpty {
  43. return [self.referencesByKey isEmpty];
  44. }
  45. - (NSUInteger)count {
  46. return self.referencesByKey.count;
  47. }
  48. #pragma mark - Public methods
  49. - (void)addReferenceToKey:(const DocumentKey &)key forID:(int)ID {
  50. FSTDocumentReference *reference = [[FSTDocumentReference alloc] initWithKey:key ID:ID];
  51. self.referencesByKey = [self.referencesByKey setByAddingObject:reference];
  52. self.referencesByID = [self.referencesByID setByAddingObject:reference];
  53. }
  54. - (void)addReferencesToKeys:(const DocumentKeySet &)keys forID:(int)ID {
  55. for (const DocumentKey &key : keys) {
  56. [self addReferenceToKey:key forID:ID];
  57. }
  58. }
  59. - (void)removeReferenceToKey:(const DocumentKey &)key forID:(int)ID {
  60. [self removeReference:[[FSTDocumentReference alloc] initWithKey:key ID:ID]];
  61. }
  62. - (void)removeReferencesToKeys:(const DocumentKeySet &)keys forID:(int)ID {
  63. for (const DocumentKey &key : keys) {
  64. [self removeReferenceToKey:key forID:ID];
  65. }
  66. }
  67. - (void)removeReferencesForID:(int)ID {
  68. FSTDocumentReference *start =
  69. [[FSTDocumentReference alloc] initWithKey:DocumentKey::Empty() ID:ID];
  70. FSTDocumentReference *end =
  71. [[FSTDocumentReference alloc] initWithKey:DocumentKey::Empty() ID:(ID + 1)];
  72. [self.referencesByID enumerateObjectsFrom:start
  73. to:end
  74. usingBlock:^(FSTDocumentReference *reference, BOOL *stop) {
  75. [self removeReference:reference];
  76. }];
  77. }
  78. - (void)removeAllReferences {
  79. for (FSTDocumentReference *reference in self.referencesByKey.objectEnumerator) {
  80. [self removeReference:reference];
  81. }
  82. }
  83. - (void)removeReference:(FSTDocumentReference *)reference {
  84. self.referencesByKey = [self.referencesByKey setByRemovingObject:reference];
  85. self.referencesByID = [self.referencesByID setByRemovingObject:reference];
  86. [self.garbageCollector addPotentialGarbageKey:reference.key];
  87. }
  88. - (DocumentKeySet)referencedKeysForID:(int)ID {
  89. FSTDocumentReference *start =
  90. [[FSTDocumentReference alloc] initWithKey:DocumentKey::Empty() ID:ID];
  91. FSTDocumentReference *end =
  92. [[FSTDocumentReference alloc] initWithKey:DocumentKey::Empty() ID:(ID + 1)];
  93. __block DocumentKeySet keys;
  94. [self.referencesByID enumerateObjectsFrom:start
  95. to:end
  96. usingBlock:^(FSTDocumentReference *reference, BOOL *stop) {
  97. keys = keys.insert(reference.key);
  98. }];
  99. return keys;
  100. }
  101. - (BOOL)containsKey:(const DocumentKey &)key {
  102. // Create a reference with a zero ID as the start position to find any document reference with
  103. // this key.
  104. FSTDocumentReference *reference = [[FSTDocumentReference alloc] initWithKey:key ID:0];
  105. NSEnumerator<FSTDocumentReference *> *enumerator =
  106. [self.referencesByKey objectEnumeratorFrom:reference];
  107. FSTDocumentReference *_Nullable firstReference = [enumerator nextObject];
  108. return firstReference && firstReference.key == reference.key;
  109. }
  110. @end
  111. NS_ASSUME_NONNULL_END