FSTImmutableSortedDictionary.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * Implementation of an immutable SortedMap using a Left-leaning Red-Black Tree, adapted from the
  3. * implementation in Mugs (http://mads379.github.com/mugs/) by Mads Hartmann Jensen
  4. * (mads379@gmail.com).
  5. *
  6. * Original paper on Left-leaning Red-Black Trees:
  7. * http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf
  8. *
  9. * Invariant 1: No red node has a red child
  10. * Invariant 2: Every leaf path has the same number of black nodes
  11. * Invariant 3: Only the left child can be red (left leaning)
  12. */
  13. #import <Foundation/Foundation.h>
  14. NS_ASSUME_NONNULL_BEGIN
  15. /**
  16. * The size threshold where we use a tree backed sorted map instead of an array backed sorted map.
  17. * This is a more or less arbitrary chosen value, that was chosen to be large enough to fit most of
  18. * object kind of Firebase data, but small enough to not notice degradation in performance for
  19. * inserting and lookups. Feel free to empirically determine this constant, but don't expect much
  20. * gain in real world performance.
  21. */
  22. extern const int kSortedDictionaryArrayToRBTreeSizeThreshold;
  23. /**
  24. * FSTImmutableSortedDictionary is a dictionary. It is immutable, but has methods to create new
  25. * dictionaries that are mutations of it, in an efficient way.
  26. */
  27. @interface FSTImmutableSortedDictionary <KeyType, __covariant ValueType> : NSObject
  28. + (FSTImmutableSortedDictionary *)dictionaryWithComparator:(NSComparator)comparator;
  29. + (FSTImmutableSortedDictionary *)dictionaryWithDictionary:
  30. (NSDictionary<KeyType, ValueType> *)dictionary
  31. comparator:(NSComparator)comparator;
  32. /**
  33. * Creates a new dictionary identical to this one, but with a key-value pair added or updated.
  34. *
  35. * @param aValue The value to associate with the key.
  36. * @param aKey The key to insert/update.
  37. * @return A new dictionary with the added/updated value.
  38. */
  39. - (FSTImmutableSortedDictionary<KeyType, ValueType> *)dictionaryBySettingObject:(ValueType)aValue
  40. forKey:(KeyType)aKey;
  41. /**
  42. * Creates a new dictionary identical to this one, but with a key removed from it.
  43. *
  44. * @param aKey The key to remove.
  45. * @return A new dictionary without that value.
  46. */
  47. - (FSTImmutableSortedDictionary<KeyType, ValueType> *)dictionaryByRemovingObjectForKey:
  48. (KeyType)aKey;
  49. /**
  50. * Looks up a value in the dictionary.
  51. *
  52. * @param key The key to look up.
  53. * @return The value for the key, if present.
  54. */
  55. - (nullable ValueType)objectForKey:(KeyType)key;
  56. /**
  57. * Looks up a value in the dictionary.
  58. *
  59. * @param key The key to look up.
  60. * @return The value for the key, if present.
  61. */
  62. - (ValueType)objectForKeyedSubscript:(KeyType)key;
  63. /**
  64. * Gets the key before the given key in sorted order.
  65. *
  66. * @param key The key to look before.
  67. * @return The key before the given one.
  68. */
  69. - (nullable KeyType)predecessorKey:(KeyType)key;
  70. /**
  71. * Returns the index of the key or NSNotFound if the key is not found.
  72. *
  73. * @param key The key to return the index for.
  74. * @return The index of the key, or NSNotFound if key not found.
  75. */
  76. - (NSUInteger)indexOfKey:(KeyType)key;
  77. /** Returns true if the dictionary contains no elements. */
  78. - (BOOL)isEmpty;
  79. /** Returns the number of items in this dictionary. */
  80. - (NSUInteger)count;
  81. /** Returns the smallest key in this dictionary. */
  82. - (KeyType)minKey;
  83. /** Returns the largest key in this dictionary. */
  84. - (KeyType)maxKey;
  85. /** Calls the given block with each of the items in this dictionary, in order. */
  86. - (void)enumerateKeysAndObjectsUsingBlock:(void (^)(KeyType key, ValueType value, BOOL *stop))block;
  87. /** Calls the given block with each of the items in this dictionary, in reverse order. */
  88. - (void)enumerateKeysAndObjectsReverse:(BOOL)reverse
  89. usingBlock:(void (^)(KeyType key, ValueType value, BOOL *stop))block;
  90. /** Returns true if the dictionary contains the given key. */
  91. - (BOOL)containsKey:(KeyType)key;
  92. - (NSEnumerator<KeyType> *)keyEnumerator;
  93. - (NSEnumerator<KeyType> *)keyEnumeratorFrom:(KeyType)startKey;
  94. /** Enumerator for the range [startKey, endKey). */
  95. - (NSEnumerator<KeyType> *)keyEnumeratorFrom:(KeyType)startKey to:(nullable KeyType)endKey;
  96. - (NSEnumerator<KeyType> *)reverseKeyEnumerator;
  97. - (NSEnumerator<KeyType> *)reverseKeyEnumeratorFrom:(KeyType)startKey;
  98. @end
  99. NS_ASSUME_NONNULL_END