FSTReferenceSet.m 4.7 KB

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