Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Dictionary.cs
Go to the documentation of this file.
6
8
11[DebuggerDisplay("Count = {Count}")]
12[TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
13public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary, ICollection, IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, ISerializable, IDeserializationCallback where TKey : notnull
14{
15 internal static class CollectionsMarshalHelper
16 {
18 {
19 if (key == null)
20 {
22 }
23 if (dictionary._buckets == null)
24 {
25 dictionary.Initialize(0);
26 }
29 uint num = (uint)(comparer?.GetHashCode(key) ?? key.GetHashCode());
30 uint num2 = 0u;
31 ref int bucket = ref dictionary.GetBucket(num);
32 int num3 = bucket - 1;
33 if (comparer == null)
34 {
35 if (typeof(TKey).IsValueType)
36 {
37 while ((uint)num3 < (uint)entries.Length)
38 {
39 if (entries[num3].hashCode == num && EqualityComparer<TKey>.Default.Equals(entries[num3].key, key))
40 {
41 exists = true;
42 return ref entries[num3].value;
43 }
44 num3 = entries[num3].next;
45 num2++;
46 if (num2 > (uint)entries.Length)
47 {
49 }
50 }
51 }
52 else
53 {
55 while ((uint)num3 < (uint)entries.Length)
56 {
57 if (entries[num3].hashCode == num && @default.Equals(entries[num3].key, key))
58 {
59 exists = true;
60 return ref entries[num3].value;
61 }
62 num3 = entries[num3].next;
63 num2++;
64 if (num2 > (uint)entries.Length)
65 {
67 }
68 }
69 }
70 }
71 else
72 {
73 while ((uint)num3 < (uint)entries.Length)
74 {
75 if (entries[num3].hashCode == num && comparer.Equals(entries[num3].key, key))
76 {
77 exists = true;
78 return ref entries[num3].value;
79 }
80 num3 = entries[num3].next;
81 num2++;
82 if (num2 > (uint)entries.Length)
83 {
85 }
86 }
87 }
88 int num4;
89 if (dictionary._freeCount > 0)
90 {
92 dictionary._freeList = -3 - entries[dictionary._freeList].next;
94 }
95 else
96 {
97 int count = dictionary._count;
98 if (count == entries.Length)
99 {
100 dictionary.Resize();
101 bucket = ref dictionary.GetBucket(num);
102 }
103 num4 = count;
106 }
108 reference.hashCode = num;
109 reference.next = bucket - 1;
111 reference.value = default(TValue);
112 bucket = num4 + 1;
114 if (!typeof(TKey).IsValueType && num2 > 100 && comparer is NonRandomizedStringEqualityComparer)
115 {
116 dictionary.Resize(entries.Length, forceNewHashCodes: true);
117 exists = false;
118 return ref dictionary.FindValue(key);
119 }
120 exists = false;
121 return ref reference.value;
122 }
123 }
124
125 private struct Entry
126 {
127 public uint hashCode;
128
129 public int next;
130
131 public TKey key;
132
133 public TValue value;
134 }
135
136 public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, IEnumerator, IDictionaryEnumerator
137 {
139
140 private readonly int _version;
141
142 private int _index;
143
145
146 private readonly int _getEnumeratorRetType;
147
149
151 {
152 get
153 {
154 if (_index == 0 || _index == _dictionary._count + 1)
155 {
157 }
158 if (_getEnumeratorRetType == 1)
159 {
160 return new DictionaryEntry(_current.Key, _current.Value);
161 }
162 return new KeyValuePair<TKey, TValue>(_current.Key, _current.Value);
163 }
164 }
165
167 {
168 get
169 {
170 if (_index == 0 || _index == _dictionary._count + 1)
171 {
173 }
174 return new DictionaryEntry(_current.Key, _current.Value);
175 }
176 }
177
179 {
180 get
181 {
182 if (_index == 0 || _index == _dictionary._count + 1)
183 {
185 }
186 return _current.Key;
187 }
188 }
189
191 {
192 get
193 {
194 if (_index == 0 || _index == _dictionary._count + 1)
195 {
197 }
198 return _current.Value;
199 }
200 }
201
210
211 public bool MoveNext()
212 {
213 if (_version != _dictionary._version)
214 {
216 }
217 while ((uint)_index < (uint)_dictionary._count)
218 {
219 ref Entry reference = ref _dictionary._entries[_index++];
220 if (reference.next >= -1)
221 {
223 return true;
224 }
225 }
228 return false;
229 }
230
231 public void Dispose()
232 {
233 }
234
244 }
245
247 [DebuggerDisplay("Count = {Count}")]
249 {
251 {
253
254 private int _index;
255
256 private readonly int _version;
257
258 private TKey _currentKey;
259
260 public TKey Current => _currentKey;
261
263 {
264 get
265 {
266 if (_index == 0 || _index == _dictionary._count + 1)
267 {
269 }
270 return _currentKey;
271 }
272 }
273
275 {
277 _version = dictionary._version;
278 _index = 0;
279 _currentKey = default(TKey);
280 }
281
282 public void Dispose()
283 {
284 }
285
286 public bool MoveNext()
287 {
288 if (_version != _dictionary._version)
289 {
291 }
292 while ((uint)_index < (uint)_dictionary._count)
293 {
294 ref Entry reference = ref _dictionary._entries[_index++];
295 if (reference.next >= -1)
296 {
298 return true;
299 }
300 }
302 _currentKey = default(TKey);
303 return false;
304 }
305
307 {
308 if (_version != _dictionary._version)
309 {
311 }
312 _index = 0;
313 _currentKey = default(TKey);
314 }
315 }
316
318
319 public int Count => _dictionary.Count;
320
322
324
326
335
337 {
338 return new Enumerator(_dictionary);
339 }
340
341 public void CopyTo(TKey[] array, int index)
342 {
343 if (array == null)
344 {
346 }
347 if (index < 0 || index > array.Length)
348 {
350 }
351 if (array.Length - index < _dictionary.Count)
352 {
353 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
354 }
355 int count = _dictionary._count;
356 Entry[] entries = _dictionary._entries;
357 for (int i = 0; i < count; i++)
358 {
359 if (entries[i].next >= -1)
360 {
361 array[index++] = entries[i].key;
362 }
363 }
364 }
365
367 {
368 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
369 }
370
372 {
373 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
374 }
375
377 {
378 return _dictionary.ContainsKey(item);
379 }
380
382 {
383 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_KeyCollectionSet);
384 return false;
385 }
386
391
396
398 {
399 if (array == null)
400 {
402 }
403 if (array.Rank != 1)
404 {
405 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
406 }
407 if (array.GetLowerBound(0) != 0)
408 {
410 }
411 if ((uint)index > (uint)array.Length)
412 {
414 }
415 if (array.Length - index < _dictionary.Count)
416 {
417 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
418 }
419 if (array is TKey[] array2)
420 {
422 return;
423 }
424 object[] array3 = array as object[];
425 if (array3 == null)
426 {
428 }
429 int count = _dictionary._count;
430 Entry[] entries = _dictionary._entries;
431 try
432 {
433 for (int i = 0; i < count; i++)
434 {
435 if (entries[i].next >= -1)
436 {
437 array3[index++] = entries[i].key;
438 }
439 }
440 }
442 {
444 }
445 }
446 }
447
449 [DebuggerDisplay("Count = {Count}")]
450 public sealed class ValueCollection : ICollection<TValue>, IEnumerable<TValue>, IEnumerable, ICollection, IReadOnlyCollection<TValue>
451 {
453 {
455
456 private int _index;
457
458 private readonly int _version;
459
460 private TValue _currentValue;
461
462 public TValue Current => _currentValue;
463
465 {
466 get
467 {
468 if (_index == 0 || _index == _dictionary._count + 1)
469 {
471 }
472 return _currentValue;
473 }
474 }
475
477 {
479 _version = dictionary._version;
480 _index = 0;
481 _currentValue = default(TValue);
482 }
483
484 public void Dispose()
485 {
486 }
487
488 public bool MoveNext()
489 {
490 if (_version != _dictionary._version)
491 {
493 }
494 while ((uint)_index < (uint)_dictionary._count)
495 {
496 ref Entry reference = ref _dictionary._entries[_index++];
497 if (reference.next >= -1)
498 {
499 _currentValue = reference.value;
500 return true;
501 }
502 }
504 _currentValue = default(TValue);
505 return false;
506 }
507
509 {
510 if (_version != _dictionary._version)
511 {
513 }
514 _index = 0;
515 _currentValue = default(TValue);
516 }
517 }
518
520
521 public int Count => _dictionary.Count;
522
524
526
528
537
539 {
540 return new Enumerator(_dictionary);
541 }
542
543 public void CopyTo(TValue[] array, int index)
544 {
545 if (array == null)
546 {
548 }
549 if ((uint)index > array.Length)
550 {
552 }
553 if (array.Length - index < _dictionary.Count)
554 {
555 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
556 }
557 int count = _dictionary._count;
558 Entry[] entries = _dictionary._entries;
559 for (int i = 0; i < count; i++)
560 {
561 if (entries[i].next >= -1)
562 {
563 array[index++] = entries[i].value;
564 }
565 }
566 }
567
569 {
570 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
571 }
572
574 {
575 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
576 return false;
577 }
578
580 {
581 ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ValueCollectionSet);
582 }
583
585 {
586 return _dictionary.ContainsValue(item);
587 }
588
593
598
600 {
601 if (array == null)
602 {
604 }
605 if (array.Rank != 1)
606 {
607 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
608 }
609 if (array.GetLowerBound(0) != 0)
610 {
612 }
613 if ((uint)index > (uint)array.Length)
614 {
616 }
617 if (array.Length - index < _dictionary.Count)
618 {
619 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
620 }
621 if (array is TValue[] array2)
622 {
624 return;
625 }
626 object[] array3 = array as object[];
627 if (array3 == null)
628 {
630 }
631 int count = _dictionary._count;
632 Entry[] entries = _dictionary._entries;
633 try
634 {
635 for (int i = 0; i < count; i++)
636 {
637 if (entries[i].next >= -1)
638 {
639 array3[index++] = entries[i].value;
640 }
641 }
642 }
644 {
646 }
647 }
648 }
649
650 private int[] _buckets;
651
652 private Entry[] _entries;
653
654 private ulong _fastModMultiplier;
655
656 private int _count;
657
658 private int _freeList;
659
660 private int _freeCount;
661
662 private int _version;
663
665
667
669
681
682 public int Count => _count - _freeCount;
683
684 public KeyCollection Keys => _keys ?? (_keys = new KeyCollection(this));
685
687
689
691
693
695
696 public TValue this[TKey key]
697 {
698 get
699 {
700 ref TValue reference = ref FindValue(key);
701 if (!Unsafe.IsNullRef(ref reference))
702 {
703 return reference;
704 }
705 ThrowHelper.ThrowKeyNotFoundException(key);
706 return default(TValue);
707 }
708 set
709 {
710 bool flag = TryInsert(key, value, InsertionBehavior.OverwriteExisting);
711 }
712 }
713
715
717
718 object ICollection.SyncRoot => this;
719
721
723
725
727
728 object? IDictionary.this[object key]
729 {
730 get
731 {
732 if (IsCompatibleKey(key))
733 {
734 ref TValue reference = ref FindValue((TKey)key);
735 if (!Unsafe.IsNullRef(ref reference))
736 {
737 return reference;
738 }
739 }
740 return null;
741 }
742 set
743 {
744 if (key == null)
745 {
747 }
748 ThrowHelper.IfNullAndNullsAreIllegalThenThrow<TValue>(value, ExceptionArgument.value);
749 try
750 {
751 TKey key2 = (TKey)key;
752 try
753 {
754 this[key2] = (TValue)value;
755 }
757 {
758 ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
759 }
760 }
762 {
763 ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
764 }
765 }
766 }
767
768 public Dictionary()
769 : this(0, (IEqualityComparer<TKey>?)null)
770 {
771 }
772
775 {
776 }
777
782
806
811
821
826
836
838 {
840 {
842 if (dictionary.Count == 0)
843 {
844 return;
845 }
847 if (dictionary._comparer == _comparer)
848 {
850 return;
851 }
852 int count = dictionary._count;
853 for (int i = 0; i < count; i++)
854 {
855 if (entries[i].next >= -1)
856 {
857 Add(entries[i].key, entries[i].value);
858 }
859 }
860 return;
861 }
863 {
864 Add(item.Key, item.Value);
865 }
866 }
867
872
873 public void Add(TKey key, TValue value)
874 {
875 bool flag = TryInsert(key, value, InsertionBehavior.ThrowOnExisting);
876 }
877
882
884 {
885 ref TValue reference = ref FindValue(keyValuePair.Key);
886 if (!Unsafe.IsNullRef(ref reference) && EqualityComparer<TValue>.Default.Equals(reference, keyValuePair.Value))
887 {
888 return true;
889 }
890 return false;
891 }
892
894 {
895 ref TValue reference = ref FindValue(keyValuePair.Key);
896 if (!Unsafe.IsNullRef(ref reference) && EqualityComparer<TValue>.Default.Equals(reference, keyValuePair.Value))
897 {
898 Remove(keyValuePair.Key);
899 return true;
900 }
901 return false;
902 }
903
904 public void Clear()
905 {
906 int count = _count;
907 if (count > 0)
908 {
910 _count = 0;
911 _freeList = -1;
912 _freeCount = 0;
914 }
915 }
916
917 public bool ContainsKey(TKey key)
918 {
919 return !Unsafe.IsNullRef(ref FindValue(key));
920 }
921
922 public bool ContainsValue(TValue value)
923 {
925 if (value == null)
926 {
927 for (int i = 0; i < _count; i++)
928 {
929 if (entries[i].next >= -1 && entries[i].value == null)
930 {
931 return true;
932 }
933 }
934 }
935 else if (typeof(TValue).IsValueType)
936 {
937 for (int j = 0; j < _count; j++)
938 {
939 if (entries[j].next >= -1 && EqualityComparer<TValue>.Default.Equals(entries[j].value, value))
940 {
941 return true;
942 }
943 }
944 }
945 else
946 {
948 for (int k = 0; k < _count; k++)
949 {
950 if (entries[k].next >= -1 && @default.Equals(entries[k].value, value))
951 {
952 return true;
953 }
954 }
955 }
956 return false;
957 }
958
960 {
961 if (array == null)
962 {
964 }
965 if ((uint)index > (uint)array.Length)
966 {
968 }
969 if (array.Length - index < Count)
970 {
971 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
972 }
973 int count = _count;
975 for (int i = 0; i < count; i++)
976 {
977 if (entries[i].next >= -1)
978 {
980 }
981 }
982 }
983
985 {
986 return new Enumerator(this, 2);
987 }
988
993
995 {
996 if (info == null)
997 {
999 }
1000 info.AddValue("Version", _version);
1001 info.AddValue("Comparer", Comparer, typeof(IEqualityComparer<TKey>));
1002 info.AddValue("HashSize", (_buckets != null) ? _buckets.Length : 0);
1003 if (_buckets != null)
1004 {
1006 CopyTo(array, 0);
1007 info.AddValue("KeyValuePairs", array, typeof(KeyValuePair<TKey, TValue>[]));
1008 }
1009 }
1010
1011 internal ref TValue FindValue(TKey key)
1012 {
1013 if (key == null)
1014 {
1016 }
1017 ref Entry reference = ref Unsafe.NullRef<Entry>();
1018 if (_buckets != null)
1019 {
1021 if (comparer == null)
1022 {
1023 uint hashCode = (uint)key.GetHashCode();
1024 int bucket = GetBucket(hashCode);
1026 uint num = 0u;
1027 if (typeof(TKey).IsValueType)
1028 {
1029 bucket--;
1030 while ((uint)bucket < (uint)entries.Length)
1031 {
1032 reference = ref entries[bucket];
1033 if (reference.hashCode != hashCode || !EqualityComparer<TKey>.Default.Equals(reference.key, key))
1034 {
1035 bucket = reference.next;
1036 num++;
1037 if (num <= (uint)entries.Length)
1038 {
1039 continue;
1040 }
1041 goto IL_0171;
1042 }
1043 goto IL_0176;
1044 }
1045 }
1046 else
1047 {
1049 bucket--;
1050 while ((uint)bucket < (uint)entries.Length)
1051 {
1052 reference = ref entries[bucket];
1053 if (reference.hashCode != hashCode || !@default.Equals(reference.key, key))
1054 {
1055 bucket = reference.next;
1056 num++;
1057 if (num <= (uint)entries.Length)
1058 {
1059 continue;
1060 }
1061 goto IL_0171;
1062 }
1063 goto IL_0176;
1064 }
1065 }
1066 }
1067 else
1068 {
1069 uint hashCode2 = (uint)comparer.GetHashCode(key);
1072 uint num2 = 0u;
1073 bucket2--;
1074 while ((uint)bucket2 < (uint)entries2.Length)
1075 {
1077 if (reference.hashCode != hashCode2 || !comparer.Equals(reference.key, key))
1078 {
1079 bucket2 = reference.next;
1080 num2++;
1081 if (num2 <= (uint)entries2.Length)
1082 {
1083 continue;
1084 }
1085 goto IL_0171;
1086 }
1087 goto IL_0176;
1088 }
1089 }
1090 }
1091 return ref Unsafe.NullRef<TValue>();
1092 IL_0171:
1094 goto IL_0176;
1095 IL_0176:
1096 return ref reference.value;
1097 }
1098
1099 private int Initialize(int capacity)
1100 {
1102 int[] buckets = new int[prime];
1103 Entry[] entries = new Entry[prime];
1104 _freeList = -1;
1106 _buckets = buckets;
1107 _entries = entries;
1108 return prime;
1109 }
1110
1111 private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
1112 {
1113 if (key == null)
1114 {
1116 }
1117 if (_buckets == null)
1118 {
1119 Initialize(0);
1120 }
1123 uint num = (uint)(comparer?.GetHashCode(key) ?? key.GetHashCode());
1124 uint num2 = 0u;
1125 ref int bucket = ref GetBucket(num);
1126 int num3 = bucket - 1;
1127 if (comparer == null)
1128 {
1129 if (typeof(TKey).IsValueType)
1130 {
1131 while ((uint)num3 < (uint)entries.Length)
1132 {
1133 if (entries[num3].hashCode == num && EqualityComparer<TKey>.Default.Equals(entries[num3].key, key))
1134 {
1135 switch (behavior)
1136 {
1137 case InsertionBehavior.OverwriteExisting:
1138 entries[num3].value = value;
1139 return true;
1140 case InsertionBehavior.ThrowOnExisting:
1141 ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
1142 break;
1143 }
1144 return false;
1145 }
1146 num3 = entries[num3].next;
1147 num2++;
1148 if (num2 > (uint)entries.Length)
1149 {
1151 }
1152 }
1153 }
1154 else
1155 {
1157 while ((uint)num3 < (uint)entries.Length)
1158 {
1159 if (entries[num3].hashCode == num && @default.Equals(entries[num3].key, key))
1160 {
1161 switch (behavior)
1162 {
1163 case InsertionBehavior.OverwriteExisting:
1164 entries[num3].value = value;
1165 return true;
1166 case InsertionBehavior.ThrowOnExisting:
1167 ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
1168 break;
1169 }
1170 return false;
1171 }
1172 num3 = entries[num3].next;
1173 num2++;
1174 if (num2 > (uint)entries.Length)
1175 {
1177 }
1178 }
1179 }
1180 }
1181 else
1182 {
1183 while ((uint)num3 < (uint)entries.Length)
1184 {
1185 if (entries[num3].hashCode == num && comparer.Equals(entries[num3].key, key))
1186 {
1187 switch (behavior)
1188 {
1189 case InsertionBehavior.OverwriteExisting:
1190 entries[num3].value = value;
1191 return true;
1192 case InsertionBehavior.ThrowOnExisting:
1193 ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(key);
1194 break;
1195 }
1196 return false;
1197 }
1198 num3 = entries[num3].next;
1199 num2++;
1200 if (num2 > (uint)entries.Length)
1201 {
1203 }
1204 }
1205 }
1206 int num4;
1207 if (_freeCount > 0)
1208 {
1209 num4 = _freeList;
1210 _freeList = -3 - entries[_freeList].next;
1211 _freeCount--;
1212 }
1213 else
1214 {
1215 int count = _count;
1216 if (count == entries.Length)
1217 {
1218 Resize();
1219 bucket = ref GetBucket(num);
1220 }
1221 num4 = count;
1222 _count = count + 1;
1223 entries = _entries;
1224 }
1226 reference.hashCode = num;
1227 reference.next = bucket - 1;
1230 bucket = num4 + 1;
1231 _version++;
1232 if (!typeof(TKey).IsValueType && num2 > 100 && comparer is NonRandomizedStringEqualityComparer)
1233 {
1234 Resize(entries.Length, forceNewHashCodes: true);
1235 }
1236 return true;
1237 }
1238
1239 public virtual void OnDeserialization(object? sender)
1240 {
1241 HashHelpers.SerializationInfoTable.TryGetValue(this, out var value);
1242 if (value == null)
1243 {
1244 return;
1245 }
1246 int @int = value.GetInt32("Version");
1247 int int2 = value.GetInt32("HashSize");
1249 if (int2 != 0)
1250 {
1253 if (array == null)
1254 {
1256 }
1257 for (int i = 0; i < array.Length; i++)
1258 {
1259 if (array[i].Key == null)
1260 {
1262 }
1263 Add(array[i].Key, array[i].Value);
1264 }
1265 }
1266 else
1267 {
1268 _buckets = null;
1269 }
1270 _version = @int;
1272 }
1273
1274 private void Resize()
1275 {
1277 }
1278
1279 private void Resize(int newSize, bool forceNewHashCodes)
1280 {
1281 Entry[] array = new Entry[newSize];
1282 int count = _count;
1284 if (!typeof(TKey).IsValueType && forceNewHashCodes)
1285 {
1287 for (int i = 0; i < count; i++)
1288 {
1289 if (array[i].next >= -1)
1290 {
1291 array[i].hashCode = (uint)_comparer.GetHashCode(array[i].key);
1292 }
1293 }
1295 {
1296 _comparer = null;
1297 }
1298 }
1299 _buckets = new int[newSize];
1301 for (int j = 0; j < count; j++)
1302 {
1303 if (array[j].next >= -1)
1304 {
1305 ref int bucket = ref GetBucket(array[j].hashCode);
1306 array[j].next = bucket - 1;
1307 bucket = j + 1;
1308 }
1309 }
1310 _entries = array;
1311 }
1312
1313 public bool Remove(TKey key)
1314 {
1315 if (key == null)
1316 {
1318 }
1319 if (_buckets != null)
1320 {
1321 uint num = 0u;
1322 uint num2 = (uint)(_comparer?.GetHashCode(key) ?? key.GetHashCode());
1323 ref int bucket = ref GetBucket(num2);
1325 int num3 = -1;
1326 int num4 = bucket - 1;
1327 while (num4 >= 0)
1328 {
1330 if (reference.hashCode == num2 && (_comparer?.Equals(reference.key, key) ?? EqualityComparer<TKey>.Default.Equals(reference.key, key)))
1331 {
1332 if (num3 < 0)
1333 {
1334 bucket = reference.next + 1;
1335 }
1336 else
1337 {
1338 entries[num3].next = reference.next;
1339 }
1341 if (RuntimeHelpers.IsReferenceOrContainsReferences<TKey>())
1342 {
1343 reference.key = default(TKey);
1344 }
1345 if (RuntimeHelpers.IsReferenceOrContainsReferences<TValue>())
1346 {
1347 reference.value = default(TValue);
1348 }
1349 _freeList = num4;
1350 _freeCount++;
1351 return true;
1352 }
1353 num3 = num4;
1354 num4 = reference.next;
1355 num++;
1356 if (num > (uint)entries.Length)
1357 {
1359 }
1360 }
1361 }
1362 return false;
1363 }
1364
1365 public bool Remove(TKey key, [MaybeNullWhen(false)] out TValue value)
1366 {
1367 if (key == null)
1368 {
1370 }
1371 if (_buckets != null)
1372 {
1373 uint num = 0u;
1374 uint num2 = (uint)(_comparer?.GetHashCode(key) ?? key.GetHashCode());
1375 ref int bucket = ref GetBucket(num2);
1377 int num3 = -1;
1378 int num4 = bucket - 1;
1379 while (num4 >= 0)
1380 {
1382 if (reference.hashCode == num2 && (_comparer?.Equals(reference.key, key) ?? EqualityComparer<TKey>.Default.Equals(reference.key, key)))
1383 {
1384 if (num3 < 0)
1385 {
1386 bucket = reference.next + 1;
1387 }
1388 else
1389 {
1390 entries[num3].next = reference.next;
1391 }
1392 value = reference.value;
1394 if (RuntimeHelpers.IsReferenceOrContainsReferences<TKey>())
1395 {
1396 reference.key = default(TKey);
1397 }
1398 if (RuntimeHelpers.IsReferenceOrContainsReferences<TValue>())
1399 {
1400 reference.value = default(TValue);
1401 }
1402 _freeList = num4;
1403 _freeCount++;
1404 return true;
1405 }
1406 num3 = num4;
1407 num4 = reference.next;
1408 num++;
1409 if (num > (uint)entries.Length)
1410 {
1412 }
1413 }
1414 }
1415 value = default(TValue);
1416 return false;
1417 }
1418
1419 public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
1420 {
1421 ref TValue reference = ref FindValue(key);
1422 if (!Unsafe.IsNullRef(ref reference))
1423 {
1424 value = reference;
1425 return true;
1426 }
1427 value = default(TValue);
1428 return false;
1429 }
1430
1431 public bool TryAdd(TKey key, TValue value)
1432 {
1433 return TryInsert(key, value, InsertionBehavior.None);
1434 }
1435
1440
1442 {
1443 if (array == null)
1444 {
1446 }
1447 if (array.Rank != 1)
1448 {
1449 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
1450 }
1451 if (array.GetLowerBound(0) != 0)
1452 {
1454 }
1455 if ((uint)index > (uint)array.Length)
1456 {
1458 }
1459 if (array.Length - index < Count)
1460 {
1461 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
1462 }
1464 {
1466 return;
1467 }
1469 {
1471 for (int i = 0; i < _count; i++)
1472 {
1473 if (entries[i].next >= -1)
1474 {
1476 }
1477 }
1478 return;
1479 }
1480 object[] array4 = array as object[];
1481 if (array4 == null)
1482 {
1484 }
1485 try
1486 {
1487 int count = _count;
1489 for (int j = 0; j < count; j++)
1490 {
1491 if (entries2[j].next >= -1)
1492 {
1494 }
1495 }
1496 }
1498 {
1500 }
1501 }
1502
1504 {
1505 return new Enumerator(this, 2);
1506 }
1507
1508 public int EnsureCapacity(int capacity)
1509 {
1510 if (capacity < 0)
1511 {
1513 }
1514 int num = ((_entries != null) ? _entries.Length : 0);
1515 if (num >= capacity)
1516 {
1517 return num;
1518 }
1519 _version++;
1520 if (_buckets == null)
1521 {
1522 return Initialize(capacity);
1523 }
1526 return prime;
1527 }
1528
1529 public void TrimExcess()
1530 {
1532 }
1533
1534 public void TrimExcess(int capacity)
1535 {
1536 if (capacity < Count)
1537 {
1539 }
1542 int num = ((entries != null) ? entries.Length : 0);
1543 if (prime < num)
1544 {
1545 int count = _count;
1546 _version++;
1549 }
1550 }
1551
1552 private void CopyEntries(Entry[] entries, int count)
1553 {
1555 int num = 0;
1556 for (int i = 0; i < count; i++)
1557 {
1558 uint hashCode = entries[i].hashCode;
1559 if (entries[i].next >= -1)
1560 {
1562 reference = entries[i];
1563 ref int bucket = ref GetBucket(hashCode);
1564 reference.next = bucket - 1;
1565 bucket = num + 1;
1566 num++;
1567 }
1568 }
1569 _count = num;
1570 _freeCount = 0;
1571 }
1572
1573 private static bool IsCompatibleKey(object key)
1574 {
1575 if (key == null)
1576 {
1578 }
1579 return key is TKey;
1580 }
1581
1582 void IDictionary.Add(object key, object value)
1583 {
1584 if (key == null)
1585 {
1587 }
1588 ThrowHelper.IfNullAndNullsAreIllegalThenThrow<TValue>(value, ExceptionArgument.value);
1589 try
1590 {
1591 TKey key2 = (TKey)key;
1592 try
1593 {
1594 Add(key2, (TValue)value);
1595 }
1596 catch (InvalidCastException)
1597 {
1598 ThrowHelper.ThrowWrongValueTypeArgumentException(value, typeof(TValue));
1599 }
1600 }
1601 catch (InvalidCastException)
1602 {
1603 ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey));
1604 }
1605 }
1606
1608 {
1609 if (IsCompatibleKey(key))
1610 {
1611 return ContainsKey((TKey)key);
1612 }
1613 return false;
1614 }
1615
1617 {
1618 return new Enumerator(this, 1);
1619 }
1620
1622 {
1623 if (IsCompatibleKey(key))
1624 {
1625 Remove((TKey)key);
1626 }
1627 }
1628
1629 [MethodImpl(MethodImplOptions.AggressiveInlining)]
1630 private ref int GetBucket(uint hashCode)
1631 {
1632 int[] buckets = _buckets;
1633 return ref buckets[HashHelpers.FastMod(hashCode, (uint)buckets.Length, _fastModMultiplier)];
1634 }
1635}
static unsafe void Clear(Array array)
Definition Array.cs:755
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
static ref TValue GetValueRefOrAddDefault(Dictionary< TKey, TValue > dictionary, TKey key, out bool exists)
Definition Dictionary.cs:17
KeyCollection(Dictionary< TKey, TValue > dictionary)
readonly Dictionary< TKey, TValue > _dictionary
ValueCollection(Dictionary< TKey, TValue > dictionary)
readonly Dictionary< TKey, TValue > _dictionary
ICollection< TValue > IDictionary< TKey, TValue >. Values
bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
ICollection IDictionary. Keys
Dictionary(IEnumerable< KeyValuePair< TKey, TValue > > collection, IEqualityComparer< TKey >? comparer)
IEqualityComparer< TKey > _comparer
void CopyEntries(Entry[] entries, int count)
IEnumerable< TKey > IReadOnlyDictionary< TKey, TValue >. Keys
virtual void OnDeserialization(object? sender)
bool ICollection< KeyValuePair< TKey, TValue > >. Remove(KeyValuePair< TKey, TValue > keyValuePair)
void CopyTo(KeyValuePair< TKey, TValue >[] array, int index)
Dictionary(int capacity, IEqualityComparer< TKey >? comparer)
Dictionary(IEqualityComparer< TKey >? comparer)
bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
ICollection IDictionary. Values
Dictionary(IEnumerable< KeyValuePair< TKey, TValue > > collection)
static bool IsCompatibleKey(object key)
bool ICollection< KeyValuePair< TKey, TValue > >. Contains(KeyValuePair< TKey, TValue > keyValuePair)
bool Remove(TKey key, [MaybeNullWhen(false)] out TValue value)
Dictionary(SerializationInfo info, StreamingContext context)
void Resize(int newSize, bool forceNewHashCodes)
IEnumerable< TValue > IReadOnlyDictionary< TKey, TValue >. Values
ICollection< TKey > IDictionary< TKey, TValue >. Keys
void AddRange(IEnumerable< KeyValuePair< TKey, TValue > > collection)
bool ICollection< KeyValuePair< TKey, TValue > >. IsReadOnly
bool TryAdd(TKey key, TValue value)
virtual void GetObjectData(SerializationInfo info, StreamingContext context)
Dictionary(IDictionary< TKey, TValue > dictionary)
Dictionary(IDictionary< TKey, TValue > dictionary, IEqualityComparer< TKey >? comparer)
void Add(TKey key, TValue value)
static ? IEqualityComparer< string > GetStringComparer(object? comparer)
static int GetPrime(int min)
static uint FastMod(uint value, uint divisor, ulong multiplier)
static int ExpandPrime(int oldSize)
static ulong GetFastModMultiplier(uint divisor)
Definition HashHelpers.cs:7
static ConditionalWeakTable< object, SerializationInfo > SerializationInfoTable
static void ThrowNotSupportedException(ExceptionResource resource)
static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen()
static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
static void ThrowArgumentException_Argument_InvalidArrayType()
static void ThrowArgumentNullException(string name)
static void ThrowSerializationException(ExceptionResource resource)
static void ThrowArgumentException(ExceptionResource resource)
static void ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion()
static void ThrowIndexArgumentOutOfRange_NeedNonNegNumException()
static void ThrowInvalidOperationException_ConcurrentOperationsNotSupported()
void CopyTo(T[] array, int arrayIndex)
void Add(TKey key, TValue value)
new IEnumerator< T > GetEnumerator()
IEqualityComparer< string > GetUnderlyingEqualityComparer()
new bool Equals(object? x, object? y)
readonly Dictionary< TKey, TValue > _dictionary
Enumerator(Dictionary< TKey, TValue > dictionary, int getEnumeratorRetType)
Enumerator(Dictionary< TKey, TValue > dictionary)