Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ImmutableSortedDictionary.cs
Go to the documentation of this file.
5using System.Linq;
7
9
10public static class ImmutableSortedDictionary
11{
16
18 {
19 return ImmutableSortedDictionary<TKey, TValue>.Empty.WithComparers(keyComparer);
20 }
21
26
31
36
41
43 {
44 return Create<TKey, TValue>().ToBuilder();
45 }
46
48 {
49 return Create<TKey, TValue>(keyComparer).ToBuilder();
50 }
51
53 {
54 return Create(keyComparer, valueComparer).ToBuilder();
55 }
56
66
72
77
82
92
94 {
95 return source.ToImmutableSortedDictionary(keyComparer, null);
96 }
97
99 {
100 return source.ToImmutableSortedDictionary(null, null);
101 }
102}
103[DebuggerDisplay("Count = {Count}")]
105public sealed class ImmutableSortedDictionary<TKey, TValue> : IImmutableDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, ISortKeyCollection<TKey>, IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection where TKey : notnull
106{
107 [DebuggerDisplay("Count = {Count}")]
109 public sealed class Builder : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection
110 {
112
114
116
117 private int _count;
118
120
121 private int _version;
122
123 private object _syncRoot;
124
126
128
130
132
133 public int Count => _count;
134
136
137 internal int Version => _version;
138
139 private Node Root
140 {
141 get
142 {
143 return _root;
144 }
145 set
146 {
147 _version++;
148 if (_root != value)
149 {
150 _root = value;
151 _immutable = null;
152 }
153 }
154 }
155
156 public TValue this[TKey key]
157 {
158 get
159 {
161 {
162 return value;
163 }
165 }
166 set
167 {
170 {
171 _count++;
172 }
173 }
174 }
175
176 bool IDictionary.IsFixedSize => false;
177
178 bool IDictionary.IsReadOnly => false;
179
180 ICollection IDictionary.Keys => Keys.ToArray(Count);
181
182 ICollection IDictionary.Values => Values.ToArray(Count);
183
185 object ICollection.SyncRoot
186 {
187 get
188 {
189 if (_syncRoot == null)
190 {
191 Interlocked.CompareExchange<object>(ref _syncRoot, new object(), (object)null);
192 }
193 return _syncRoot;
194 }
195 }
196
198 bool ICollection.IsSynchronized => false;
199
201 {
202 get
203 {
204 return _keyComparer;
205 }
206 set
207 {
208 Requires.NotNull(value, "value");
209 if (value == _keyComparer)
210 {
211 return;
212 }
214 int num = 0;
216 {
217 while (enumerator.MoveNext())
218 {
219 KeyValuePair<TKey, TValue> current = enumerator.Current;
220 node = node.Add(current.Key, current.Value, value, _valueComparer, out var mutated);
221 if (mutated)
222 {
223 num++;
224 }
225 }
226 }
228 Root = node;
229 _count = num;
230 }
231 }
232
234 {
235 get
236 {
237 return _valueComparer;
238 }
239 set
240 {
241 Requires.NotNull(value, "value");
242 if (value != _valueComparer)
243 {
245 _immutable = null;
246 }
247 }
248 }
249
250 object? IDictionary.this[object key]
251 {
252 get
253 {
254 return this[(TKey)key];
255 }
256 set
257 {
258 this[(TKey)key] = (TValue)value;
259 }
260 }
261
263 {
264 Requires.NotNull(map, "map");
265 _root = map._root;
266 _keyComparer = map.KeyComparer;
267 _valueComparer = map.ValueComparer;
268 _count = map.Count;
269 _immutable = map;
270 }
271
272 public ref readonly TValue ValueRef(TKey key)
273 {
274 Requires.NotNullAllowStructs(key, "key");
276 }
277
278 void IDictionary.Add(object key, object value)
279 {
280 Add((TKey)key, (TValue)value);
281 }
282
284 {
285 return ContainsKey((TKey)key);
286 }
287
292
293 void IDictionary.Remove(object key)
294 {
295 Remove((TKey)key);
296 }
297
299 {
301 }
302
303 public void Add(TKey key, TValue value)
304 {
306 if (mutated)
307 {
308 _count++;
309 }
310 }
311
312 public bool ContainsKey(TKey key)
313 {
315 }
316
317 public bool Remove(TKey key)
318 {
320 if (mutated)
321 {
322 _count--;
323 }
324 return mutated;
325 }
326
327 public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
328 {
330 }
331
332 public bool TryGetKey(TKey equalKey, out TKey actualKey)
333 {
334 Requires.NotNullAllowStructs(equalKey, "equalKey");
336 }
337
339 {
340 Add(item.Key, item.Value);
341 }
342
343 public void Clear()
344 {
346 _count = 0;
347 }
348
353
358
360 {
361 if (Contains(item))
362 {
363 return Remove(item.Key);
364 }
365 return false;
366 }
367
372
377
382
383 public bool ContainsValue(TValue value)
384 {
386 }
387
389 {
390 Requires.NotNull(items, "items");
391 foreach (KeyValuePair<TKey, TValue> item in items)
392 {
393 Add(item);
394 }
395 }
396
398 {
399 Requires.NotNull(keys, "keys");
400 foreach (TKey key in keys)
401 {
402 Remove(key);
403 }
404 }
405
406 public TValue? GetValueOrDefault(TKey key)
407 {
408 return GetValueOrDefault(key, default(TValue));
409 }
410
411 public TValue GetValueOrDefault(TKey key, TValue defaultValue)
412 {
413 Requires.NotNullAllowStructs(key, "key");
415 {
416 return value;
417 }
418 return defaultValue;
419 }
420
429 }
430
432 public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IEnumerator, IDisposable, ISecurePooledObjectUser
433 {
435
436 private readonly Builder _builder;
437
438 private readonly int _poolUserId;
439
440 private Node _root;
441
443
444 private Node _current;
445
447
449 {
450 get
451 {
453 if (_current != null)
454 {
455 return _current.Value;
456 }
457 throw new InvalidOperationException();
458 }
459 }
460
461 int ISecurePooledObjectUser.PoolUserId => _poolUserId;
462
463 object IEnumerator.Current => Current;
464
465 internal Enumerator(Node root, Builder? builder = null)
466 {
467 Requires.NotNull(root, "root");
468 _root = root;
470 _current = null;
471 _enumeratingBuilderVersion = builder?.Version ?? (-1);
473 _stack = null;
474 if (!_root.IsEmpty)
475 {
476 if (!s_enumeratingStacks.TryTake(this, out _stack))
477 {
478 _stack = s_enumeratingStacks.PrepNew(this, new Stack<RefAsValueType<Node>>(root.Height));
479 }
481 }
482 }
483
484 public void Dispose()
485 {
486 _root = null;
487 _current = null;
488 if (_stack != null && _stack.TryUse(ref this, out var value))
489 {
490 value.ClearFastWhenEmpty();
491 s_enumeratingStacks.TryAdd(this, _stack);
492 }
493 _stack = null;
494 }
495
496 public bool MoveNext()
497 {
500 if (_stack != null)
501 {
502 Stack<RefAsValueType<Node>> stack = _stack.Use(ref this);
503 if (stack.Count > 0)
504 {
505 PushLeft((_current = stack.Pop().Value).Right);
506 return true;
507 }
508 }
509 _current = null;
510 return false;
511 }
512
513 public void Reset()
514 {
517 _current = null;
518 if (_stack != null)
519 {
520 Stack<RefAsValueType<Node>> stack = _stack.Use(ref this);
521 stack.ClearFastWhenEmpty();
523 }
524 }
525
526 internal void ThrowIfDisposed()
527 {
528 if (_root == null || (_stack != null && !_stack.IsOwned(ref this)))
529 {
530 Requires.FailObjectDisposed(this);
531 }
532 }
533
541
542 private void PushLeft(Node node)
543 {
544 Requires.NotNull(node, "node");
545 Stack<RefAsValueType<Node>> stack = _stack.Use(ref this);
546 while (!node.IsEmpty)
547 {
548 stack.Push(new RefAsValueType<Node>(node));
549 node = node.Left;
550 }
551 }
552 }
553
554 [DebuggerDisplay("{_key} = {_value}")]
555 internal sealed class Node : IBinaryTree<KeyValuePair<TKey, TValue>>, IBinaryTree, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
556 {
557 internal static readonly Node EmptyNode = new Node();
558
559 private readonly TKey _key;
560
561 private readonly TValue _value;
562
563 private bool _frozen;
564
565 private byte _height;
566
567 private Node _left;
568
569 private Node _right;
570
571 public bool IsEmpty => _left == null;
572
574
576
577 public int Height => _height;
578
579 public Node? Left => _left;
580
581 IBinaryTree? IBinaryTree.Left => _left;
582
583 public Node? Right => _right;
584
585 IBinaryTree? IBinaryTree.Right => _right;
586
588
589 int IBinaryTree.Count
590 {
591 get
592 {
593 throw new NotSupportedException();
594 }
595 }
596
598
600
601 private Node()
602 {
603 _frozen = true;
604 }
605
606 private Node(TKey key, TValue value, Node left, Node right, bool frozen = false)
607 {
608 Requires.NotNullAllowStructs(key, "key");
609 Requires.NotNull(left, "left");
610 Requires.NotNull(right, "right");
611 _key = key;
612 _value = value;
613 _left = left;
614 _right = right;
615 _height = checked((byte)(1 + Math.Max(left._height, right._height)));
616 _frozen = frozen;
617 }
618
620 {
621 return new Enumerator(this);
622 }
623
628
633
635 {
636 return new Enumerator(this, builder);
637 }
638
640 {
641 Requires.NotNull(array, "array");
642 Requires.Range(arrayIndex >= 0, "arrayIndex");
643 Requires.Range(array.Length >= arrayIndex + dictionarySize, "arrayIndex");
645 while (enumerator.MoveNext())
646 {
647 KeyValuePair<TKey, TValue> current = enumerator.Current;
648 array[arrayIndex++] = current;
649 }
650 }
651
652 internal void CopyTo(Array array, int arrayIndex, int dictionarySize)
653 {
654 Requires.NotNull(array, "array");
655 Requires.Range(arrayIndex >= 0, "arrayIndex");
656 Requires.Range(array.Length >= arrayIndex + dictionarySize, "arrayIndex");
658 while (enumerator.MoveNext())
659 {
660 KeyValuePair<TKey, TValue> current = enumerator.Current;
661 array.SetValue(new DictionaryEntry(current.Key, current.Value), arrayIndex++);
662 }
663 }
664
671
673 {
674 Requires.NotNullAllowStructs(key, "key");
675 Requires.NotNull(keyComparer, "keyComparer");
676 Requires.NotNull(valueComparer, "valueComparer");
679 }
680
682 {
683 Requires.NotNullAllowStructs(key, "key");
684 Requires.NotNull(keyComparer, "keyComparer");
685 Requires.NotNull(valueComparer, "valueComparer");
687 }
688
689 internal Node Remove(TKey key, IComparer<TKey> keyComparer, out bool mutated)
690 {
691 Requires.NotNullAllowStructs(key, "key");
692 Requires.NotNull(keyComparer, "keyComparer");
693 return RemoveRecursive(key, keyComparer, out mutated);
694 }
695
696 internal ref readonly TValue ValueRef(TKey key, IComparer<TKey> keyComparer)
697 {
698 Requires.NotNullAllowStructs(key, "key");
699 Requires.NotNull(keyComparer, "keyComparer");
700 Node node = Search(key, keyComparer);
701 if (node.IsEmpty)
702 {
704 }
705 return ref node._value;
706 }
707
708 internal bool TryGetValue(TKey key, IComparer<TKey> keyComparer, [MaybeNullWhen(false)] out TValue value)
709 {
710 Requires.NotNullAllowStructs(key, "key");
711 Requires.NotNull(keyComparer, "keyComparer");
712 Node node = Search(key, keyComparer);
713 if (node.IsEmpty)
714 {
715 value = default(TValue);
716 return false;
717 }
718 value = node._value;
719 return true;
720 }
721
722 internal bool TryGetKey(TKey equalKey, IComparer<TKey> keyComparer, out TKey actualKey)
723 {
724 Requires.NotNullAllowStructs(equalKey, "equalKey");
725 Requires.NotNull(keyComparer, "keyComparer");
726 Node node = Search(equalKey, keyComparer);
727 if (node.IsEmpty)
728 {
730 return false;
731 }
732 actualKey = node._key;
733 return true;
734 }
735
736 internal bool ContainsKey(TKey key, IComparer<TKey> keyComparer)
737 {
738 Requires.NotNullAllowStructs(key, "key");
739 Requires.NotNull(keyComparer, "keyComparer");
740 return !Search(key, keyComparer).IsEmpty;
741 }
742
744 {
745 Requires.NotNull(valueComparer, "valueComparer");
747 {
748 while (enumerator.MoveNext())
749 {
750 if (valueComparer.Equals(value, enumerator.Current.Value))
751 {
752 return true;
753 }
754 }
755 }
756 return false;
757 }
758
760 {
761 Requires.NotNullAllowStructs(pair.Key, "Key");
762 Requires.NotNull(keyComparer, "keyComparer");
763 Requires.NotNull(valueComparer, "valueComparer");
764 Node node = Search(pair.Key, keyComparer);
765 if (node.IsEmpty)
766 {
767 return false;
768 }
769 return valueComparer.Equals(node._value, pair.Value);
770 }
771
772 internal void Freeze()
773 {
774 if (!_frozen)
775 {
776 _left.Freeze();
777 _right.Freeze();
778 _frozen = true;
779 }
780 }
781
782 private static Node RotateLeft(Node tree)
783 {
784 Requires.NotNull(tree, "tree");
785 if (tree._right.IsEmpty)
786 {
787 return tree;
788 }
789 Node right = tree._right;
790 return right.Mutate(tree.Mutate(null, right._left));
791 }
792
793 private static Node RotateRight(Node tree)
794 {
795 Requires.NotNull(tree, "tree");
796 if (tree._left.IsEmpty)
797 {
798 return tree;
799 }
800 Node left = tree._left;
801 return left.Mutate(null, tree.Mutate(left._right));
802 }
803
804 private static Node DoubleLeft(Node tree)
805 {
806 Requires.NotNull(tree, "tree");
807 if (tree._right.IsEmpty)
808 {
809 return tree;
810 }
811 Node tree2 = tree.Mutate(null, RotateRight(tree._right));
812 return RotateLeft(tree2);
813 }
814
815 private static Node DoubleRight(Node tree)
816 {
817 Requires.NotNull(tree, "tree");
818 if (tree._left.IsEmpty)
819 {
820 return tree;
821 }
822 Node tree2 = tree.Mutate(RotateLeft(tree._left));
823 return RotateRight(tree2);
824 }
825
826 private static int Balance(Node tree)
827 {
828 Requires.NotNull(tree, "tree");
829 return tree._right._height - tree._left._height;
830 }
831
832 private static bool IsRightHeavy(Node tree)
833 {
834 Requires.NotNull(tree, "tree");
835 return Balance(tree) >= 2;
836 }
837
838 private static bool IsLeftHeavy(Node tree)
839 {
840 Requires.NotNull(tree, "tree");
841 return Balance(tree) <= -2;
842 }
843
844 private static Node MakeBalanced(Node tree)
845 {
846 Requires.NotNull(tree, "tree");
847 if (IsRightHeavy(tree))
848 {
849 if (Balance(tree._right) >= 0)
850 {
851 return RotateLeft(tree);
852 }
853 return DoubleLeft(tree);
854 }
855 if (IsLeftHeavy(tree))
856 {
857 if (Balance(tree._left) <= 0)
858 {
859 return RotateRight(tree);
860 }
861 return DoubleRight(tree);
862 }
863 return tree;
864 }
865
867 {
868 Requires.NotNull(items, "items");
869 Requires.Range(start >= 0, "start");
870 Requires.Range(length >= 0, "length");
871 if (length == 0)
872 {
873 return EmptyNode;
874 }
875 int num = (length - 1) / 2;
876 int num2 = length - 1 - num;
877 Node left = NodeTreeFromList(items, start, num2);
878 Node right = NodeTreeFromList(items, start + num2 + 1, num);
880 return new Node(keyValuePair.Key, keyValuePair.Value, left, right, frozen: true);
881 }
882
884 {
885 replacedExistingValue = false;
886 if (IsEmpty)
887 {
888 mutated = true;
889 return new Node(key, value, this, this);
890 }
891 Node node = this;
892 int num = keyComparer.Compare(key, _key);
893 if (num > 0)
894 {
896 if (mutated)
897 {
898 node = Mutate(null, right);
899 }
900 }
901 else if (num < 0)
902 {
904 if (mutated)
905 {
906 node = Mutate(left);
907 }
908 }
909 else
910 {
911 if (valueComparer.Equals(_value, value))
912 {
913 mutated = false;
914 return this;
915 }
917 {
919 }
920 mutated = true;
922 node = new Node(key, value, _left, _right);
923 }
924 if (!mutated)
925 {
926 return node;
927 }
928 return MakeBalanced(node);
929 }
930
931 private Node RemoveRecursive(TKey key, IComparer<TKey> keyComparer, out bool mutated)
932 {
933 if (IsEmpty)
934 {
935 mutated = false;
936 return this;
937 }
938 Node node = this;
939 int num = keyComparer.Compare(key, _key);
940 if (num == 0)
941 {
942 mutated = true;
944 {
945 node = EmptyNode;
946 }
947 else if (_right.IsEmpty && !_left.IsEmpty)
948 {
949 node = _left;
950 }
951 else if (!_right.IsEmpty && _left.IsEmpty)
952 {
953 node = _right;
954 }
955 else
956 {
957 Node node2 = _right;
958 while (!node2._left.IsEmpty)
959 {
960 node2 = node2._left;
961 }
962 bool mutated2;
963 Node right = _right.Remove(node2._key, keyComparer, out mutated2);
964 node = node2.Mutate(_left, right);
965 }
966 }
967 else if (num < 0)
968 {
969 Node left = _left.Remove(key, keyComparer, out mutated);
970 if (mutated)
971 {
972 node = Mutate(left);
973 }
974 }
975 else
976 {
977 Node right2 = _right.Remove(key, keyComparer, out mutated);
978 if (mutated)
979 {
980 node = Mutate(null, right2);
981 }
982 }
983 if (!node.IsEmpty)
984 {
985 return MakeBalanced(node);
986 }
987 return node;
988 }
989
990 private Node Mutate(Node left = null, Node right = null)
991 {
992 if (_frozen)
993 {
994 return new Node(_key, _value, left ?? _left, right ?? _right);
995 }
996 if (left != null)
997 {
998 _left = left;
999 }
1000 if (right != null)
1001 {
1002 _right = right;
1003 }
1004 _height = checked((byte)(1 + Math.Max(_left._height, _right._height)));
1005 return this;
1006 }
1007
1008 private Node Search(TKey key, IComparer<TKey> keyComparer)
1009 {
1010 if (IsEmpty)
1011 {
1012 return this;
1013 }
1014 int num = keyComparer.Compare(key, _key);
1015 if (num == 0)
1016 {
1017 return this;
1018 }
1019 if (num > 0)
1020 {
1021 return _right.Search(key, keyComparer);
1022 }
1023 return _left.Search(key, keyComparer);
1024 }
1025 }
1026
1028
1029 private readonly Node _root;
1030
1031 private readonly int _count;
1032
1034
1036
1038
1039 public bool IsEmpty => _root.IsEmpty;
1040
1041 public int Count => _count;
1042
1044
1046
1048
1050
1052
1054
1055 internal Node Root => _root;
1056
1057 public TValue this[TKey key]
1058 {
1059 get
1060 {
1061 Requires.NotNullAllowStructs(key, "key");
1062 if (TryGetValue(key, out var value))
1063 {
1064 return value;
1065 }
1067 }
1068 }
1069
1071 {
1072 get
1073 {
1074 return this[key];
1075 }
1076 set
1077 {
1078 throw new NotSupportedException();
1079 }
1080 }
1081
1082 bool IDictionary.IsFixedSize => true;
1083
1084 bool IDictionary.IsReadOnly => true;
1085
1087
1089
1090 object? IDictionary.this[object key]
1091 {
1092 get
1093 {
1094 return this[(TKey)key];
1095 }
1096 set
1097 {
1098 throw new NotSupportedException();
1099 }
1100 }
1101
1103 object ICollection.SyncRoot => this;
1104
1106 bool ICollection.IsSynchronized => true;
1107
1109 {
1110 _keyComparer = keyComparer ?? Comparer<TKey>.Default;
1113 }
1114
1116 {
1117 Requires.NotNull(root, "root");
1118 Requires.Range(count >= 0, "count");
1119 Requires.NotNull(keyComparer, "keyComparer");
1120 Requires.NotNull(valueComparer, "valueComparer");
1121 root.Freeze();
1122 _root = root;
1123 _count = count;
1124 _keyComparer = keyComparer;
1126 }
1127
1129 {
1130 if (!_root.IsEmpty)
1131 {
1132 return Empty.WithComparers(_keyComparer, _valueComparer);
1133 }
1134 return this;
1135 }
1136
1141
1142 public ref readonly TValue ValueRef(TKey key)
1143 {
1144 Requires.NotNullAllowStructs(key, "key");
1146 }
1147
1149 {
1150 return new Builder(this);
1151 }
1152
1154 {
1155 Requires.NotNullAllowStructs(key, "key");
1156 bool mutated;
1158 return Wrap(root, _count + 1);
1159 }
1160
1162 {
1163 Requires.NotNullAllowStructs(key, "key");
1165 bool mutated;
1167 return Wrap(root, replacedExistingValue ? _count : (_count + 1));
1168 }
1169
1171 {
1172 Requires.NotNull(items, "items");
1173 return AddRange(items, overwriteOnCollision: true, avoidToSortedMap: false);
1174 }
1175
1177 {
1178 Requires.NotNull(items, "items");
1179 return AddRange(items, overwriteOnCollision: false, avoidToSortedMap: false);
1180 }
1181
1183 {
1184 Requires.NotNullAllowStructs(value, "value");
1185 bool mutated;
1187 return Wrap(root, _count - 1);
1188 }
1189
1191 {
1192 Requires.NotNull(keys, "keys");
1193 Node node = _root;
1194 int num = _count;
1195 foreach (TKey key in keys)
1196 {
1197 bool mutated;
1199 if (mutated)
1200 {
1201 node = node2;
1202 num--;
1203 }
1204 }
1205 return Wrap(node, num);
1206 }
1207
1209 {
1210 if (keyComparer == null)
1211 {
1212 keyComparer = Comparer<TKey>.Default;
1213 }
1214 if (valueComparer == null)
1215 {
1217 }
1218 if (keyComparer == _keyComparer)
1219 {
1221 {
1222 return this;
1223 }
1225 }
1228 }
1229
1231 {
1232 return WithComparers(keyComparer, _valueComparer);
1233 }
1234
1235 public bool ContainsValue(TValue value)
1236 {
1238 }
1239
1244
1249
1254
1259
1264
1269
1270 public bool ContainsKey(TKey key)
1271 {
1272 Requires.NotNullAllowStructs(key, "key");
1274 }
1275
1280
1281 public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
1282 {
1283 Requires.NotNullAllowStructs(key, "key");
1285 }
1286
1287 public bool TryGetKey(TKey equalKey, out TKey actualKey)
1288 {
1289 Requires.NotNullAllowStructs(equalKey, "equalKey");
1291 }
1292
1294 {
1295 throw new NotSupportedException();
1296 }
1297
1299 {
1300 throw new NotSupportedException();
1301 }
1302
1307
1312
1317
1319 {
1320 Requires.NotNull(array, "array");
1321 Requires.Range(arrayIndex >= 0, "arrayIndex");
1322 Requires.Range(array.Length >= arrayIndex + Count, "arrayIndex");
1324 while (enumerator.MoveNext())
1325 {
1326 KeyValuePair<TKey, TValue> current = enumerator.Current;
1327 array[arrayIndex++] = current;
1328 }
1329 }
1330
1331 void IDictionary.Add(object key, object value)
1332 {
1333 throw new NotSupportedException();
1334 }
1335
1337 {
1338 return ContainsKey((TKey)key);
1339 }
1340
1345
1347 {
1348 throw new NotSupportedException();
1349 }
1350
1352 {
1353 throw new NotSupportedException();
1354 }
1355
1357 {
1359 }
1360
1369
1371 {
1372 return GetEnumerator();
1373 }
1374
1376 {
1377 return _root.GetEnumerator();
1378 }
1379
1381 {
1382 if (!root.IsEmpty)
1383 {
1384 return new ImmutableSortedDictionary<TKey, TValue>(root, count, keyComparer, valueComparer);
1385 }
1386 return Empty.WithComparers(keyComparer, valueComparer);
1387 }
1388
1390 {
1392 if (other != null)
1393 {
1394 return true;
1395 }
1397 {
1398 other = builder.ToImmutable();
1399 return true;
1400 }
1401 return false;
1402 }
1403
1405 {
1406 Requires.NotNull(items, "items");
1407 if (IsEmpty && !avoidToSortedMap)
1408 {
1409 return FillFromEmpty(items, overwriteOnCollision);
1410 }
1411 Node node = _root;
1412 int num = _count;
1413 foreach (KeyValuePair<TKey, TValue> item in items)
1414 {
1415 bool replacedExistingValue = false;
1416 bool mutated;
1418 if (mutated)
1419 {
1420 node = node2;
1422 {
1423 num++;
1424 }
1425 }
1426 }
1427 return Wrap(node, num);
1428 }
1429
1431 {
1432 if (_root != root)
1433 {
1434 if (!root.IsEmpty)
1435 {
1437 }
1438 return Clear();
1439 }
1440 return this;
1441 }
1442
1444 {
1445 Requires.NotNull(items, "items");
1446 if (TryCastToImmutableMap(items, out var other))
1447 {
1448 return other.WithComparers(KeyComparer, ValueComparer);
1449 }
1452 {
1454 }
1455 else
1456 {
1458 foreach (KeyValuePair<TKey, TValue> item in items)
1459 {
1460 TValue value;
1462 {
1463 sortedDictionary[item.Key] = item.Value;
1464 }
1465 else if (sortedDictionary.TryGetValue(item.Key, out value))
1466 {
1467 if (!_valueComparer.Equals(value, item.Value))
1468 {
1470 }
1471 }
1472 else
1473 {
1474 sortedDictionary.Add(item.Key, item.Value);
1475 }
1476 }
1477 }
1478 if (sortedDictionary.Count == 0)
1479 {
1480 return this;
1481 }
1484 }
1485}
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
bool ICollection< KeyValuePair< TKey, TValue > >. Remove(KeyValuePair< TKey, TValue > keyValuePair)
void CopyTo(KeyValuePair< TKey, TValue >[] array, int index)
void AddRange(IEnumerable< KeyValuePair< TKey, TValue > > collection)
bool ICollection< KeyValuePair< TKey, TValue > >. IsReadOnly
void Add(TKey key, TValue value)
void AddRange(IEnumerable< KeyValuePair< TKey, TValue > > items)
ICollection< TValue > IDictionary< TKey, TValue >. Values
ImmutableSortedDictionary< TKey, TValue >.Enumerator GetEnumerator()
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
Node RemoveRecursive(TKey key, IComparer< TKey > keyComparer, out bool mutated)
IBinaryTree< KeyValuePair< TKey, TValue > >? IBinaryTree< KeyValuePair< TKey, TValue > >. Left
void CopyTo(KeyValuePair< TKey, TValue >[] array, int arrayIndex, int dictionarySize)
bool TryGetKey(TKey equalKey, IComparer< TKey > keyComparer, out TKey actualKey)
bool Contains(KeyValuePair< TKey, TValue > pair, IComparer< TKey > keyComparer, IEqualityComparer< TValue > valueComparer)
bool ContainsValue(TValue value, IEqualityComparer< TValue > valueComparer)
Node SetItem(TKey key, TValue value, IComparer< TKey > keyComparer, IEqualityComparer< TValue > valueComparer, out bool replacedExistingValue, out bool mutated)
IBinaryTree< KeyValuePair< TKey, TValue > >? IBinaryTree< KeyValuePair< TKey, TValue > >. Right
Node(TKey key, TValue value, Node left, Node right, bool frozen=false)
static Node NodeTreeFromList(IOrderedCollection< KeyValuePair< TKey, TValue > > items, int start, int length)
static Node NodeTreeFromSortedDictionary(SortedDictionary< TKey, TValue > dictionary)
Node Remove(TKey key, IComparer< TKey > keyComparer, out bool mutated)
ref readonly TValue ValueRef(TKey key, IComparer< TKey > keyComparer)
Node SetOrAdd(TKey key, TValue value, IComparer< TKey > keyComparer, IEqualityComparer< TValue > valueComparer, bool overwriteExistingValue, out bool replacedExistingValue, out bool mutated)
Node Add(TKey key, TValue value, IComparer< TKey > keyComparer, IEqualityComparer< TValue > valueComparer, out bool mutated)
bool TryGetValue(TKey key, IComparer< TKey > keyComparer, [MaybeNullWhen(false)] out TValue value)
void CopyTo(Array array, int arrayIndex, int dictionarySize)
static ImmutableSortedDictionary< TKey, TValue >.Builder CreateBuilder< TKey, TValue >()
static ImmutableSortedDictionary< TKey, TValue > CreateRange< TKey, TValue >(IEnumerable< KeyValuePair< TKey, TValue > > items)
static ImmutableSortedDictionary< TKey, TValue > Create< TKey, TValue >()
ImmutableSortedDictionary< TKey, TValue > Remove(TKey value)
ImmutableSortedDictionary< TKey, TValue > AddRange(IEnumerable< KeyValuePair< TKey, TValue > > items)
ImmutableSortedDictionary(Node root, int count, IComparer< TKey > keyComparer, IEqualityComparer< TValue > valueComparer)
static ImmutableSortedDictionary< TKey, TValue > ToImmutableSortedDictionary< TKey, TValue >(this ImmutableSortedDictionary< TKey, TValue >.Builder builder)
static ImmutableSortedDictionary< TKey, TValue > Wrap(Node root, int count, IComparer< TKey > keyComparer, IEqualityComparer< TValue > valueComparer)
ImmutableSortedDictionary(IComparer< TKey >? keyComparer=null, IEqualityComparer< TValue >? valueComparer=null)
ImmutableSortedDictionary< TKey, TValue > Add(TKey key, TValue value)
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
ImmutableSortedDictionary< TKey, TValue > WithComparers(IComparer< TKey >? keyComparer)
ImmutableSortedDictionary< TKey, TValue > AddRange(IEnumerable< KeyValuePair< TKey, TValue > > items, bool overwriteOnCollision, bool avoidToSortedMap)
ImmutableSortedDictionary< TKey, TValue > SetItems(IEnumerable< KeyValuePair< TKey, TValue > > items)
ImmutableSortedDictionary< TKey, TValue > WithComparers(IComparer< TKey >? keyComparer, IEqualityComparer< TValue >? valueComparer)
static ImmutableSortedDictionary< TKey, TValue > ToImmutableSortedDictionary< TSource, TKey, TValue >(this IEnumerable< TSource > source, Func< TSource, TKey > keySelector, Func< TSource, TValue > elementSelector, IComparer< TKey >? keyComparer, IEqualityComparer< TValue >? valueComparer)
static bool TryCastToImmutableMap(IEnumerable< KeyValuePair< TKey, TValue > > sequence, [NotNullWhen(true)] out ImmutableSortedDictionary< TKey, TValue > other)
ImmutableSortedDictionary< TKey, TValue > SetItem(TKey key, TValue value)
ImmutableSortedDictionary< TKey, TValue > FillFromEmpty(IEnumerable< KeyValuePair< TKey, TValue > > items, bool overwriteOnCollision)
ImmutableSortedDictionary< TKey, TValue > RemoveRange(IEnumerable< TKey > keys)
ImmutableSortedDictionary< TKey, TValue > Wrap(Node root, int adjustedCountIfDifferentRoot)
static void Range(bool condition, string? parameterName, string? message=null)
Definition Requires.cs:40
static byte Max(byte val1, byte val2)
Definition Math.cs:738
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string CollectionModifiedDuringEnumeration
Definition SR.cs:26
static string DuplicateKey
Definition SR.cs:28
static string Arg_KeyNotFoundWithKey
Definition SR.cs:94
Definition SR.cs:7
static int CompareExchange(ref int location1, int value, int comparand)
void CopyTo(Array array, int index)
new IDictionaryEnumerator GetEnumerator()
void Add(object key, object? value)
new bool Equals(object? x, object? y)
static readonly SecureObjectPool< Stack< RefAsValueType< Node > >, Enumerator > s_enumeratingStacks
SecurePooledObject< Stack< RefAsValueType< Node > > > _stack