Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class BigSet<T>
- {
- private const int ShiftCount = 19;
- private const ulong MinimumSize = 1 << ShiftCount;
- internal IBigEqualityComparer<T> _comparer;
- internal BigArray<ulong> _hashBuckets;
- internal BigArray<Slot> _slots;
- internal ulong Count;
- internal ulong Position;
- private int Resizes;
- internal int Version;
- public BigSet() : this(MinimumSize, new BigComparer<T>())
- {
- }
- public BigSet(ulong size) : this(size, new BigComparer<T>())
- {
- if(size < MinimumSize)
- size = MinimumSize;
- }
- public BigSet(ulong size, IBigEqualityComparer<T> comparer)
- {
- if(size < MinimumSize)
- size = MinimumSize;
- if(comparer == null)
- comparer = new BigComparer<T>();
- _comparer = comparer;
- _hashBuckets = new BigArray<ulong>(size);
- for(ulong i = 0; i < _hashBuckets.Length; i++)
- _hashBuckets[i] = ulong.MaxValue;
- _slots = new BigArray<Slot>(size);
- Count = 0;
- Version = 0;
- Position = ulong.MaxValue;
- }
- public BigArray<T> Items => ToBigArray();
- public T this[ulong index]
- {
- get
- {
- if(index > Count)
- throw new Exception($"Getter: Index out of bounds {index} must be less than {Count}");
- return _slots[index].value;
- }
- }
- public bool Add(T item)
- {
- return Insert(item, true);
- }
- public bool Contains(T item)
- {
- return Insert(item, false);
- }
- internal bool Insert(T item, bool add)
- {
- var hashCode = (ulong) _comparer.GetHashCode(item) & long.MaxValue;
- if(FindEntry(item, hashCode) != ulong.MaxValue)
- return true;
- if(add)
- {
- if(Count >= _slots.Length)
- {
- var newsize = _hashBuckets.Length * 2;
- var newhashebuckets = new BigArray<ulong>(newsize);
- var newslots = new BigArray<Slot>(newsize);
- for(var i = 0ul; i < newhashebuckets.Length; i++)
- newhashebuckets[i] = ulong.MaxValue;
- for(var i = 0ul; i < Count; i++)
- {
- var pos = _slots[i].hashCode % newsize;
- newslots[i] = new Slot(_slots[i].hashCode, newhashebuckets[pos], _slots[i].value);
- newhashebuckets[pos] = i;
- }
- _hashBuckets = newhashebuckets;
- _slots = newslots;
- Resizes++;
- }
- var hashPos = hashCode % _hashBuckets.Length;
- var news = new Slot(hashCode, _hashBuckets[hashPos], item);
- _slots[Count] = news;
- _hashBuckets[hashPos] = Count;
- Position = Count;
- Count++;
- Version++;
- }
- return false;
- }
- private ulong FindEntry(T item, ulong hashCode)
- {
- for(var position = _hashBuckets[hashCode % _hashBuckets.Length]; position != ulong.MaxValue; position = _slots[position].next)
- if(_slots[position].hashCode == hashCode && _comparer.Equals(_slots[position].value, item))
- {
- Position = position;
- return position;
- }
- return ulong.MaxValue;
- }
- public ulong FindEntry(T item)
- {
- var hashCode = (ulong) _comparer.GetHashCode(item) & long.MaxValue;
- for(var position = _hashBuckets[hashCode % _hashBuckets.Length]; position != ulong.MaxValue; position = _slots[position].next)
- if(_slots[position].hashCode == hashCode && _comparer.Equals(_slots[position].value, item))
- return position;
- return ulong.MaxValue;
- }
- public BigArray<T> ToBigArray()
- {
- var ba = new BigArray<T>(Count);
- for(ulong i = 0, p = 0; i < Count; i++)
- if(_slots[i].hashCode != ulong.MaxValue)
- ba[p++] = _slots[i].value;
- return ba;
- }
- internal struct Slot
- {
- public ulong hashCode;
- public ulong next;
- public T value;
- public Slot(ulong hc, ulong n, T v)
- {
- hashCode = hc;
- next = n;
- value = v;
- }
- }
- }
Add Comment
Please, Sign In to add comment