Guest User

Untitled

a guest
Nov 17th, 2018
99
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.84 KB | None | 0 0
  1. public class BigSet<T>
  2. {
  3. private const int ShiftCount = 19;
  4. private const ulong MinimumSize = 1 << ShiftCount;
  5. internal IBigEqualityComparer<T> _comparer;
  6. internal BigArray<ulong> _hashBuckets;
  7. internal BigArray<Slot> _slots;
  8. internal ulong Count;
  9. internal ulong Position;
  10. private int Resizes;
  11. internal int Version;
  12. public BigSet() : this(MinimumSize, new BigComparer<T>())
  13. {
  14. }
  15. public BigSet(ulong size) : this(size, new BigComparer<T>())
  16. {
  17. if(size < MinimumSize)
  18. size = MinimumSize;
  19. }
  20. public BigSet(ulong size, IBigEqualityComparer<T> comparer)
  21. {
  22. if(size < MinimumSize)
  23. size = MinimumSize;
  24. if(comparer == null)
  25. comparer = new BigComparer<T>();
  26. _comparer = comparer;
  27. _hashBuckets = new BigArray<ulong>(size);
  28. for(ulong i = 0; i < _hashBuckets.Length; i++)
  29. _hashBuckets[i] = ulong.MaxValue;
  30. _slots = new BigArray<Slot>(size);
  31. Count = 0;
  32. Version = 0;
  33. Position = ulong.MaxValue;
  34. }
  35. public BigArray<T> Items => ToBigArray();
  36. public T this[ulong index]
  37. {
  38. get
  39. {
  40. if(index > Count)
  41. throw new Exception($"Getter: Index out of bounds {index} must be less than {Count}");
  42. return _slots[index].value;
  43. }
  44. }
  45. public bool Add(T item)
  46. {
  47. return Insert(item, true);
  48. }
  49. public bool Contains(T item)
  50. {
  51. return Insert(item, false);
  52. }
  53. internal bool Insert(T item, bool add)
  54. {
  55. var hashCode = (ulong) _comparer.GetHashCode(item) & long.MaxValue;
  56. if(FindEntry(item, hashCode) != ulong.MaxValue)
  57. return true;
  58. if(add)
  59. {
  60. if(Count >= _slots.Length)
  61. {
  62. var newsize = _hashBuckets.Length * 2;
  63. var newhashebuckets = new BigArray<ulong>(newsize);
  64. var newslots = new BigArray<Slot>(newsize);
  65. for(var i = 0ul; i < newhashebuckets.Length; i++)
  66. newhashebuckets[i] = ulong.MaxValue;
  67. for(var i = 0ul; i < Count; i++)
  68. {
  69. var pos = _slots[i].hashCode % newsize;
  70. newslots[i] = new Slot(_slots[i].hashCode, newhashebuckets[pos], _slots[i].value);
  71. newhashebuckets[pos] = i;
  72. }
  73. _hashBuckets = newhashebuckets;
  74. _slots = newslots;
  75. Resizes++;
  76. }
  77. var hashPos = hashCode % _hashBuckets.Length;
  78. var news = new Slot(hashCode, _hashBuckets[hashPos], item);
  79. _slots[Count] = news;
  80. _hashBuckets[hashPos] = Count;
  81. Position = Count;
  82. Count++;
  83. Version++;
  84. }
  85. return false;
  86. }
  87. private ulong FindEntry(T item, ulong hashCode)
  88. {
  89. for(var position = _hashBuckets[hashCode % _hashBuckets.Length]; position != ulong.MaxValue; position = _slots[position].next)
  90. if(_slots[position].hashCode == hashCode && _comparer.Equals(_slots[position].value, item))
  91. {
  92. Position = position;
  93. return position;
  94. }
  95. return ulong.MaxValue;
  96. }
  97. public ulong FindEntry(T item)
  98. {
  99. var hashCode = (ulong) _comparer.GetHashCode(item) & long.MaxValue;
  100. for(var position = _hashBuckets[hashCode % _hashBuckets.Length]; position != ulong.MaxValue; position = _slots[position].next)
  101. if(_slots[position].hashCode == hashCode && _comparer.Equals(_slots[position].value, item))
  102. return position;
  103. return ulong.MaxValue;
  104. }
  105. public BigArray<T> ToBigArray()
  106. {
  107. var ba = new BigArray<T>(Count);
  108. for(ulong i = 0, p = 0; i < Count; i++)
  109. if(_slots[i].hashCode != ulong.MaxValue)
  110. ba[p++] = _slots[i].value;
  111. return ba;
  112. }
  113. internal struct Slot
  114. {
  115. public ulong hashCode;
  116. public ulong next;
  117. public T value;
  118. public Slot(ulong hc, ulong n, T v)
  119. {
  120. hashCode = hc;
  121. next = n;
  122. value = v;
  123. }
  124. }
  125. }
Add Comment
Please, Sign In to add comment