FSTReferenceSet.mm 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. #include "Firestore/core/src/firebase/firestore/model/document_key.h"
  19. using firebase::firestore::model::DocumentKey;
  20. NS_ASSUME_NONNULL_BEGIN
  21. #pragma mark - FSTReferenceSet
  22. @interface FSTReferenceSet ()
  23. /** A set of outstanding references to a document sorted by key. */
  24. @property(nonatomic, strong) FSTImmutableSortedSet<FSTDocumentReference *> *referencesByKey;
  25. /** A set of outstanding references to a document sorted by target ID (or batch ID). */
  26. @property(nonatomic, strong) FSTImmutableSortedSet<FSTDocumentReference *> *referencesByID;
  27. @end
  28. @implementation FSTReferenceSet
  29. #pragma mark - Initializer
  30. - (instancetype)init {
  31. self = [super init];
  32. if (self) {
  33. _referencesByKey =
  34. [FSTImmutableSortedSet setWithComparator:FSTDocumentReferenceComparatorByKey];
  35. _referencesByID = [FSTImmutableSortedSet setWithComparator:FSTDocumentReferenceComparatorByID];
  36. }
  37. return self;
  38. }
  39. #pragma mark - Testing helper methods
  40. - (BOOL)isEmpty {
  41. return [self.referencesByKey isEmpty];
  42. }
  43. - (NSUInteger)count {
  44. return self.referencesByKey.count;
  45. }
  46. #pragma mark - Public methods
  47. - (void)addReferenceToKey:(const DocumentKey &)key forID:(int)ID {
  48. FSTDocumentReference *reference = [[FSTDocumentReference alloc] initWithKey:key ID:ID];
  49. self.referencesByKey = [self.referencesByKey setByAddingObject:reference];
  50. self.referencesByID = [self.referencesByID setByAddingObject:reference];
  51. }
  52. - (void)addReferencesToKeys:(FSTDocumentKeySet *)keys forID:(int)ID {
  53. [keys enumerateObjectsUsingBlock:^(FSTDocumentKey *key, BOOL *stop) {
  54. [self addReferenceToKey:key forID:ID];
  55. }];
  56. }
  57. - (void)removeReferenceToKey:(const DocumentKey &)key forID:(int)ID {
  58. [self removeReference:[[FSTDocumentReference alloc] initWithKey:key ID:ID]];
  59. }
  60. - (void)removeReferencesToKeys:(FSTDocumentKeySet *)keys forID:(int)ID {
  61. [keys enumerateObjectsUsingBlock:^(FSTDocumentKey *key, BOOL *stop) {
  62. [self removeReferenceToKey:key forID:ID];
  63. }];
  64. }
  65. - (void)removeReferencesForID:(int)ID {
  66. FSTDocumentReference *start =
  67. [[FSTDocumentReference alloc] initWithKey:DocumentKey::Empty() ID:ID];
  68. FSTDocumentReference *end =
  69. [[FSTDocumentReference alloc] initWithKey:DocumentKey::Empty() ID:(ID + 1)];
  70. [self.referencesByID enumerateObjectsFrom:start
  71. to:end
  72. usingBlock:^(FSTDocumentReference *reference, BOOL *stop) {
  73. [self removeReference:reference];
  74. }];
  75. }
  76. - (void)removeAllReferences {
  77. for (FSTDocumentReference *reference in self.referencesByKey.objectEnumerator) {
  78. [self removeReference:reference];
  79. }
  80. }
  81. - (void)removeReference:(FSTDocumentReference *)reference {
  82. self.referencesByKey = [self.referencesByKey setByRemovingObject:reference];
  83. self.referencesByID = [self.referencesByID setByRemovingObject:reference];
  84. [self.garbageCollector addPotentialGarbageKey:reference.key];
  85. }
  86. - (FSTDocumentKeySet *)referencedKeysForID:(int)ID {
  87. FSTDocumentReference *start =
  88. [[FSTDocumentReference alloc] initWithKey:DocumentKey::Empty() ID:ID];
  89. FSTDocumentReference *end =
  90. [[FSTDocumentReference alloc] initWithKey:DocumentKey::Empty() ID:(ID + 1)];
  91. __block FSTDocumentKeySet *keys = [FSTDocumentKeySet keySet];
  92. [self.referencesByID enumerateObjectsFrom:start
  93. to:end
  94. usingBlock:^(FSTDocumentReference *reference, BOOL *stop) {
  95. keys = [keys setByAddingObject:reference.key];
  96. }];
  97. return keys;
  98. }
  99. - (BOOL)containsKey:(const DocumentKey &)key {
  100. // Create a reference with a zero ID as the start position to find any document reference with
  101. // this key.
  102. FSTDocumentReference *reference = [[FSTDocumentReference alloc] initWithKey:key ID:0];
  103. NSEnumerator<FSTDocumentReference *> *enumerator =
  104. [self.referencesByKey objectEnumeratorFrom:reference];
  105. FSTDocumentReference *_Nullable firstReference = [enumerator nextObject];
  106. return firstReference && firstReference.key == reference.key;
  107. }
  108. @end
  109. NS_ASSUME_NONNULL_END