Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
HashSet.cs
Go to the documentation of this file.
6
8
11[DebuggerDisplay("Count = {Count}")]
12[TypeForwardedFrom("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
14{
15 private struct Entry
16 {
17 public int HashCode;
18
19 public int Next;
20
21 public T Value;
22 }
23
25 {
26 private readonly HashSet<T> _hashSet;
27
28 private readonly int _version;
29
30 private int _index;
31
32 private T _current;
33
34 public T Current => _current;
35
37 {
38 get
39 {
40 if (_index == 0 || _index == _hashSet._count + 1)
41 {
43 }
44 return _current;
45 }
46 }
47
49 {
52 _index = 0;
53 _current = default(T);
54 }
55
56 public bool MoveNext()
57 {
59 {
61 }
62 while ((uint)_index < (uint)_hashSet._count)
63 {
65 if (reference.Next >= -1)
66 {
67 _current = reference.Value;
68 return true;
69 }
70 }
72 _current = default(T);
73 return false;
74 }
75
76 public void Dispose()
77 {
78 }
79
89 }
90
91 private int[] _buckets;
92
93 private Entry[] _entries;
94
95 private ulong _fastModMultiplier;
96
97 private int _count;
98
99 private int _freeList;
100
101 private int _freeCount;
102
103 private int _version;
104
106
107 public int Count => _count - _freeCount;
108
110
112 {
113 get
114 {
115 if (typeof(T) == typeof(string))
116 {
118 }
119 return _comparer ?? EqualityComparer<T>.Default;
120 }
121 }
122
123 public HashSet()
125 {
126 }
127
143
144 public HashSet(int capacity)
146 {
147 }
148
153
155 : this(comparer)
156 {
157 if (collection == null)
158 {
160 }
162 {
164 return;
165 }
167 {
169 }
171 if (_count > 0 && _entries.Length / _count > 3)
172 {
173 TrimExcess();
174 }
175 }
176
178 : this(comparer)
179 {
180 if (capacity < 0)
181 {
183 }
184 if (capacity > 0)
185 {
187 }
188 }
189
194
196 {
197 if (source.Count == 0)
198 {
199 return;
200 }
201 int num = source._buckets.Length;
202 int num2 = HashHelpers.ExpandPrime(source.Count + 1);
203 if (num2 >= num)
204 {
205 _buckets = (int[])source._buckets.Clone();
206 _entries = (Entry[])source._entries.Clone();
207 _freeList = source._freeList;
208 _freeCount = source._freeCount;
209 _count = source._count;
210 _fastModMultiplier = source._fastModMultiplier;
211 return;
212 }
213 Initialize(source.Count);
215 for (int i = 0; i < source._count; i++)
216 {
218 if (reference.Next >= -1)
219 {
221 }
222 }
223 }
224
226 {
228 }
229
230 public void Clear()
231 {
232 int count = _count;
233 if (count > 0)
234 {
236 _count = 0;
237 _freeList = -1;
238 _freeCount = 0;
240 }
241 }
242
243 public bool Contains(T item)
244 {
245 return FindItemIndex(item) >= 0;
246 }
247
248 private int FindItemIndex(T item)
249 {
250 int[] buckets = _buckets;
251 if (buckets != null)
252 {
254 uint num = 0u;
256 if (comparer == null)
257 {
258 int num2 = item?.GetHashCode() ?? 0;
259 if (typeof(T).IsValueType)
260 {
261 int num3 = GetBucketRef(num2) - 1;
262 while (num3 >= 0)
263 {
265 if (reference.HashCode == num2 && EqualityComparer<T>.Default.Equals(reference.Value, item))
266 {
267 return num3;
268 }
269 num3 = reference.Next;
270 num++;
271 if (num > (uint)entries.Length)
272 {
274 }
275 }
276 }
277 else
278 {
279 EqualityComparer<T> @default = EqualityComparer<T>.Default;
280 int num4 = GetBucketRef(num2) - 1;
281 while (num4 >= 0)
282 {
284 if (reference2.HashCode == num2 && @default.Equals(reference2.Value, item))
285 {
286 return num4;
287 }
288 num4 = reference2.Next;
289 num++;
290 if (num > (uint)entries.Length)
291 {
293 }
294 }
295 }
296 }
297 else
298 {
299 int num5 = ((item != null) ? comparer.GetHashCode(item) : 0);
300 int num6 = GetBucketRef(num5) - 1;
301 while (num6 >= 0)
302 {
304 if (reference3.HashCode == num5 && comparer.Equals(reference3.Value, item))
305 {
306 return num6;
307 }
308 num6 = reference3.Next;
309 num++;
310 if (num > (uint)entries.Length)
311 {
313 }
314 }
315 }
316 }
317 return -1;
318 }
319
320 [MethodImpl(MethodImplOptions.AggressiveInlining)]
321 private ref int GetBucketRef(int hashCode)
322 {
323 int[] buckets = _buckets;
324 return ref buckets[HashHelpers.FastMod((uint)hashCode, (uint)buckets.Length, _fastModMultiplier)];
325 }
326
327 public bool Remove(T item)
328 {
329 if (_buckets != null)
330 {
332 uint num = 0u;
333 int num2 = -1;
334 int num3 = ((item != null) ? (_comparer?.GetHashCode(item) ?? item.GetHashCode()) : 0);
336 int num4 = bucketRef - 1;
337 while (num4 >= 0)
338 {
340 if (reference.HashCode == num3 && (_comparer?.Equals(reference.Value, item) ?? EqualityComparer<T>.Default.Equals(reference.Value, item)))
341 {
342 if (num2 < 0)
343 {
345 }
346 else
347 {
348 entries[num2].Next = reference.Next;
349 }
351 if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
352 {
353 reference.Value = default(T);
354 }
355 _freeList = num4;
356 _freeCount++;
357 return true;
358 }
359 num2 = num4;
360 num4 = reference.Next;
361 num++;
362 if (num > (uint)entries.Length)
363 {
365 }
366 }
367 }
368 return false;
369 }
370
372 {
373 return new Enumerator(this);
374 }
375
380
385
387 {
388 if (info == null)
389 {
391 }
392 info.AddValue("Version", _version);
393 info.AddValue("Comparer", Comparer, typeof(IEqualityComparer<T>));
394 info.AddValue("Capacity", (_buckets != null) ? _buckets.Length : 0);
395 if (_buckets != null)
396 {
397 T[] array = new T[Count];
398 CopyTo(array);
399 info.AddValue("Elements", array, typeof(T[]));
400 }
401 }
402
403 public virtual void OnDeserialization(object? sender)
404 {
406 if (value == null)
407 {
408 return;
409 }
410 int @int = value.GetInt32("Capacity");
412 _freeList = -1;
413 _freeCount = 0;
414 if (@int != 0)
415 {
416 _buckets = new int[@int];
417 _entries = new Entry[@int];
419 T[] array = (T[])value.GetValue("Elements", typeof(T[]));
420 if (array == null)
421 {
423 }
424 for (int i = 0; i < array.Length; i++)
425 {
427 }
428 }
429 else
430 {
431 _buckets = null;
432 }
433 _version = value.GetInt32("Version");
435 }
436
437 public bool Add(T item)
438 {
439 int location;
441 }
442
444 {
445 if (_buckets != null)
446 {
447 int num = FindItemIndex(equalValue);
448 if (num >= 0)
449 {
451 return true;
452 }
453 }
454 actualValue = default(T);
455 return false;
456 }
457
459 {
460 if (other == null)
461 {
463 }
464 foreach (T item in other)
465 {
467 }
468 }
469
471 {
472 if (other == null)
473 {
475 }
476 if (Count == 0 || other == this)
477 {
478 return;
479 }
481 {
482 if (collection.Count == 0)
483 {
484 Clear();
485 return;
486 }
488 {
490 return;
491 }
492 }
494 }
495
497 {
498 if (other == null)
499 {
501 }
502 if (Count == 0)
503 {
504 return;
505 }
506 if (other == this)
507 {
508 Clear();
509 return;
510 }
511 foreach (T item in other)
512 {
513 Remove(item);
514 }
515 }
516
518 {
519 if (other == null)
520 {
522 }
523 if (Count == 0)
524 {
526 }
527 else if (other == this)
528 {
529 Clear();
530 }
532 {
534 }
535 else
536 {
538 }
539 }
540
542 {
543 if (other == null)
544 {
546 }
547 if (Count == 0 || other == this)
548 {
549 return true;
550 }
552 {
553 if (Count > hashSet.Count)
554 {
555 return false;
556 }
558 }
560 if (num == Count)
561 {
562 return num2 >= 0;
563 }
564 return false;
565 }
566
568 {
569 if (other == null)
570 {
572 }
573 if (other == this)
574 {
575 return false;
576 }
578 {
579 if (collection.Count == 0)
580 {
581 return false;
582 }
583 if (Count == 0)
584 {
585 return collection.Count > 0;
586 }
588 {
589 if (Count >= hashSet.Count)
590 {
591 return false;
592 }
594 }
595 }
597 if (num == Count)
598 {
599 return num2 > 0;
600 }
601 return false;
602 }
603
605 {
606 if (other == null)
607 {
609 }
610 if (other == this)
611 {
612 return true;
613 }
615 {
616 if (collection.Count == 0)
617 {
618 return true;
619 }
621 {
622 return false;
623 }
624 }
626 }
627
629 {
630 if (other == null)
631 {
633 }
634 if (Count == 0 || other == this)
635 {
636 return false;
637 }
639 {
640 if (collection.Count == 0)
641 {
642 return true;
643 }
645 {
646 if (hashSet.Count >= Count)
647 {
648 return false;
649 }
651 }
652 }
654 if (num < Count)
655 {
656 return num2 == 0;
657 }
658 return false;
659 }
660
662 {
663 if (other == null)
664 {
666 }
667 if (Count == 0)
668 {
669 return false;
670 }
671 if (other == this)
672 {
673 return true;
674 }
675 foreach (T item in other)
676 {
677 if (Contains(item))
678 {
679 return true;
680 }
681 }
682 return false;
683 }
684
686 {
687 if (other == null)
688 {
690 }
691 if (other == this)
692 {
693 return true;
694 }
696 {
697 if (Count != hashSet.Count)
698 {
699 return false;
700 }
702 }
703 if (Count == 0 && other is ICollection<T> { Count: >0 })
704 {
705 return false;
706 }
708 if (num == Count)
709 {
710 return num2 == 0;
711 }
712 return false;
713 }
714
715 public void CopyTo(T[] array)
716 {
717 CopyTo(array, 0, Count);
718 }
719
720 public void CopyTo(T[] array, int arrayIndex)
721 {
723 }
724
725 public void CopyTo(T[] array, int arrayIndex, int count)
726 {
727 if (array == null)
728 {
730 }
731 if (arrayIndex < 0)
732 {
734 }
735 if (count < 0)
736 {
738 }
739 if (arrayIndex > array.Length || count > array.Length - arrayIndex)
740 {
741 ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
742 }
744 for (int i = 0; i < _count; i++)
745 {
746 if (count == 0)
747 {
748 break;
749 }
751 if (reference.Next >= -1)
752 {
753 array[arrayIndex++] = reference.Value;
754 count--;
755 }
756 }
757 }
758
760 {
761 if (match == null)
762 {
764 }
766 int num = 0;
767 for (int i = 0; i < _count; i++)
768 {
770 if (reference.Next >= -1)
771 {
772 T value = reference.Value;
773 if (match(value) && Remove(value))
774 {
775 num++;
776 }
777 }
778 }
779 return num;
780 }
781
782 public int EnsureCapacity(int capacity)
783 {
784 if (capacity < 0)
785 {
787 }
788 int num = ((_entries != null) ? _entries.Length : 0);
789 if (num >= capacity)
790 {
791 return num;
792 }
793 if (_buckets == null)
794 {
795 return Initialize(capacity);
796 }
799 return prime;
800 }
801
802 private void Resize()
803 {
805 }
806
807 private void Resize(int newSize, bool forceNewHashCodes)
808 {
809 Entry[] array = new Entry[newSize];
810 int count = _count;
812 if (!typeof(T).IsValueType && forceNewHashCodes)
813 {
815 for (int i = 0; i < count; i++)
816 {
818 if (reference.Next >= -1)
819 {
821 }
822 }
824 {
825 _comparer = null;
826 }
827 }
828 _buckets = new int[newSize];
830 for (int j = 0; j < count; j++)
831 {
833 if (reference2.Next >= -1)
834 {
835 ref int bucketRef = ref GetBucketRef(reference2.HashCode);
837 bucketRef = j + 1;
838 }
839 }
840 _entries = array;
841 }
842
843 public void TrimExcess()
844 {
845 int count = Count;
848 int num = ((entries != null) ? entries.Length : 0);
849 if (prime >= num)
850 {
851 return;
852 }
853 int count2 = _count;
854 _version++;
857 int num2 = 0;
858 for (int i = 0; i < count2; i++)
859 {
860 int hashCode = entries[i].HashCode;
861 if (entries[i].Next >= -1)
862 {
864 reference = entries[i];
865 ref int bucketRef = ref GetBucketRef(hashCode);
867 bucketRef = num2 + 1;
868 num2++;
869 }
870 }
871 _count = count;
872 _freeCount = 0;
873 }
874
876 {
877 return new HashSetEqualityComparer<T>();
878 }
879
880 private int Initialize(int capacity)
881 {
883 int[] buckets = new int[prime];
884 Entry[] entries = new Entry[prime];
885 _freeList = -1;
886 _buckets = buckets;
889 return prime;
890 }
891
892 private bool AddIfNotPresent(T value, out int location)
893 {
894 if (_buckets == null)
895 {
896 Initialize(0);
897 }
900 uint num = 0u;
901 ref int reference = ref Unsafe.NullRef<int>();
902 int num2;
903 if (comparer == null)
904 {
905 num2 = value?.GetHashCode() ?? 0;
907 int num3 = reference - 1;
908 if (typeof(T).IsValueType)
909 {
910 while (num3 >= 0)
911 {
913 if (reference2.HashCode == num2 && EqualityComparer<T>.Default.Equals(reference2.Value, value))
914 {
915 location = num3;
916 return false;
917 }
918 num3 = reference2.Next;
919 num++;
920 if (num > (uint)entries.Length)
921 {
923 }
924 }
925 }
926 else
927 {
928 EqualityComparer<T> @default = EqualityComparer<T>.Default;
929 while (num3 >= 0)
930 {
932 if (reference3.HashCode == num2 && @default.Equals(reference3.Value, value))
933 {
934 location = num3;
935 return false;
936 }
937 num3 = reference3.Next;
938 num++;
939 if (num > (uint)entries.Length)
940 {
942 }
943 }
944 }
945 }
946 else
947 {
948 num2 = ((value != null) ? comparer.GetHashCode(value) : 0);
950 int num4 = reference - 1;
951 while (num4 >= 0)
952 {
954 if (reference4.HashCode == num2 && comparer.Equals(reference4.Value, value))
955 {
956 location = num4;
957 return false;
958 }
959 num4 = reference4.Next;
960 num++;
961 if (num > (uint)entries.Length)
962 {
964 }
965 }
966 }
967 int num5;
968 if (_freeCount > 0)
969 {
970 num5 = _freeList;
971 _freeCount--;
972 _freeList = -3 - entries[_freeList].Next;
973 }
974 else
975 {
976 int count = _count;
977 if (count == entries.Length)
978 {
979 Resize();
981 }
982 num5 = count;
983 _count = count + 1;
985 }
990 reference = num5 + 1;
991 _version++;
992 location = num5;
993 if (!typeof(T).IsValueType && num > 100 && comparer is NonRandomizedStringEqualityComparer)
994 {
995 Resize(entries.Length, forceNewHashCodes: true);
997 }
998 return true;
999 }
1000
1002 {
1003 foreach (T item in other)
1004 {
1005 if (!Contains(item))
1006 {
1007 return false;
1008 }
1009 }
1010 return true;
1011 }
1012
1014 {
1016 {
1017 while (enumerator.MoveNext())
1018 {
1019 T current = enumerator.Current;
1020 if (!other.Contains(current))
1021 {
1022 return false;
1023 }
1024 }
1025 }
1026 return true;
1027 }
1028
1030 {
1032 for (int i = 0; i < _count; i++)
1033 {
1035 if (reference.Next >= -1)
1036 {
1037 T value = reference.Value;
1038 if (!other.Contains(value))
1039 {
1040 Remove(value);
1041 }
1042 }
1043 }
1044 }
1045
1047 {
1048 int count = _count;
1049 int num = BitHelper.ToIntArrayLength(count);
1050 Span<int> span = stackalloc int[100];
1051 BitHelper bitHelper = ((num <= 100) ? new BitHelper(span.Slice(0, num), clear: true) : new BitHelper(new int[num], clear: false));
1052 foreach (T item in other)
1053 {
1054 int num2 = FindItemIndex(item);
1055 if (num2 >= 0)
1056 {
1057 bitHelper.MarkBit(num2);
1058 }
1059 }
1060 for (int i = 0; i < count; i++)
1061 {
1063 if (reference.Next >= -1 && !bitHelper.IsMarked(i))
1064 {
1065 Remove(reference.Value);
1066 }
1067 }
1068 }
1069
1071 {
1072 foreach (T item in other)
1073 {
1074 if (!Remove(item))
1075 {
1077 }
1078 }
1079 }
1080
1082 {
1083 int count = _count;
1084 int num = BitHelper.ToIntArrayLength(count);
1085 Span<int> span = stackalloc int[50];
1086 BitHelper bitHelper = ((num <= 50) ? new BitHelper(span.Slice(0, num), clear: true) : new BitHelper(new int[num], clear: false));
1087 Span<int> span2 = stackalloc int[50];
1088 BitHelper bitHelper2 = ((num <= 50) ? new BitHelper(span2.Slice(0, num), clear: true) : new BitHelper(new int[num], clear: false));
1089 foreach (T item in other)
1090 {
1092 {
1093 bitHelper2.MarkBit(location);
1094 }
1095 else if (location < count && !bitHelper2.IsMarked(location))
1096 {
1097 bitHelper.MarkBit(location);
1098 }
1099 }
1100 for (int i = 0; i < count; i++)
1101 {
1102 if (bitHelper.IsMarked(i))
1103 {
1104 Remove(_entries[i].Value);
1105 }
1106 }
1107 }
1108
1110 {
1111 if (_count == 0)
1112 {
1113 int num = 0;
1115 {
1116 if (enumerator.MoveNext())
1117 {
1118 T current = enumerator.Current;
1119 num++;
1120 }
1121 }
1122 return (UniqueCount: 0, UnfoundCount: num);
1123 }
1124 int count = _count;
1126 Span<int> span = stackalloc int[100];
1127 BitHelper bitHelper = ((num2 <= 100) ? new BitHelper(span.Slice(0, num2), clear: true) : new BitHelper(new int[num2], clear: false));
1128 int num3 = 0;
1129 int num4 = 0;
1130 foreach (T item in other)
1131 {
1132 int num5 = FindItemIndex(item);
1133 if (num5 >= 0)
1134 {
1135 if (!bitHelper.IsMarked(num5))
1136 {
1137 bitHelper.MarkBit(num5);
1138 num4++;
1139 }
1140 }
1141 else
1142 {
1143 num3++;
1144 if (returnIfUnfound)
1145 {
1146 break;
1147 }
1148 }
1149 }
1150 return (UniqueCount: num4, UnfoundCount: num3);
1151 }
1152
1154 {
1156 }
1157}
static unsafe void Clear(Array array)
Definition Array.cs:755
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
IEqualityComparer< TKey > Comparer
bool ICollection< KeyValuePair< TKey, TValue > >. IsReadOnly
void Add(TKey key, TValue value)
void IntersectWithEnumerable(IEnumerable< T > other)
Definition HashSet.cs:1046
bool IsSubsetOf(IEnumerable< T > other)
Definition HashSet.cs:541
HashSet(int capacity, IEqualityComparer< T >? comparer)
Definition HashSet.cs:177
void IntersectWithHashSetWithSameComparer(HashSet< T > other)
Definition HashSet.cs:1029
static IEqualityComparer< HashSet< T > > CreateSetComparer()
Definition HashSet.cs:875
bool Overlaps(IEnumerable< T > other)
Definition HashSet.cs:661
bool ContainsAllElements(IEnumerable< T > other)
Definition HashSet.cs:1001
void SymmetricExceptWithEnumerable(IEnumerable< T > other)
Definition HashSet.cs:1081
void UnionWith(IEnumerable< T > other)
Definition HashSet.cs:458
void IntersectWith(IEnumerable< T > other)
Definition HashSet.cs:470
bool IsProperSubsetOf(IEnumerable< T > other)
Definition HashSet.cs:567
HashSet(IEnumerable< T > collection, IEqualityComparer< T >? comparer)
Definition HashSet.cs:154
IEqualityComparer< T > _comparer
Definition HashSet.cs:105
bool IsSubsetOfHashSetWithSameComparer(HashSet< T > other)
Definition HashSet.cs:1013
ref int GetBucketRef(int hashCode)
Definition HashSet.cs:321
int EnsureCapacity(int capacity)
Definition HashSet.cs:782
void ExceptWith(IEnumerable< T > other)
Definition HashSet.cs:496
void SymmetricExceptWith(IEnumerable< T > other)
Definition HashSet.cs:517
int RemoveWhere(Predicate< T > match)
Definition HashSet.cs:759
virtual void OnDeserialization(object? sender)
Definition HashSet.cs:403
virtual void GetObjectData(SerializationInfo info, StreamingContext context)
Definition HashSet.cs:386
bool TryGetValue(T equalValue, [MaybeNullWhen(false)] out T actualValue)
Definition HashSet.cs:443
void SymmetricExceptWithUniqueHashSet(HashSet< T > other)
Definition HashSet.cs:1070
bool AddIfNotPresent(T value, out int location)
Definition HashSet.cs:892
void CopyTo(T[] array, int arrayIndex, int count)
Definition HashSet.cs:725
void CopyTo(T[] array, int arrayIndex)
Definition HashSet.cs:720
bool SetEquals(IEnumerable< T > other)
Definition HashSet.cs:685
static bool EqualityComparersAreEqual(HashSet< T > set1, HashSet< T > set2)
Definition HashSet.cs:1153
bool IsProperSupersetOf(IEnumerable< T > other)
Definition HashSet.cs:628
int int UnfoundCount CheckUniqueAndUnfoundElements(IEnumerable< T > other, bool returnIfUnfound)
Definition HashSet.cs:1109
HashSet(IEnumerable< T > collection)
Definition HashSet.cs:149
HashSet(IEqualityComparer< T >? comparer)
Definition HashSet.cs:128
bool IsSupersetOf(IEnumerable< T > other)
Definition HashSet.cs:604
void ConstructFrom(HashSet< T > source)
Definition HashSet.cs:195
HashSet(SerializationInfo info, StreamingContext context)
Definition HashSet.cs:190
void Resize(int newSize, bool forceNewHashCodes)
Definition HashSet.cs:807
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 string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
Definition SR.cs:7
static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen()
static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
static void ThrowArgumentNullException(string name)
static void ThrowSerializationException(ExceptionResource resource)
static void ThrowArgumentException(ExceptionResource resource)
static void ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion()
static void ThrowInvalidOperationException_ConcurrentOperationsNotSupported()
new IEnumerator< T > GetEnumerator()
IEqualityComparer< string > GetUnderlyingEqualityComparer()
new bool Equals(object? x, object? y)