internal LookupHashtable(int size, SlimGrouping <TKey, TElement>[] groupings, LookupBucket <TKey, TElement>[] buckets) { AllocatedGroupings = size; Groupings = groupings; Buckets = buckets; Container = new IndexedItemContainer <TElement>(); }
internal void SetInitial(TKey key, TElement element, ref IndexedItemContainer <TElement> elements) { Key = key; var firstIndex = elements.PlaceIn(element); UsedIndexes_SingleIndex = ((uint)firstIndex) + 1; }
public bool Contains(T value, ref IndexedItemContainer <T> container, out int valueIndex) { var hash = CommonImplementation.GetHashCode(value); var posHash = (hash & 0x7FFFFFFF); var bucketIx = posHash % Buckets.Length; if (Buckets[bucketIx].IsDefaultValue()) { valueIndex = -1; return(false); } return(Buckets[bucketIx].Contains(value, ref container.Items, out valueIndex)); }
public bool Add(T value, ref IndexedItemContainer <T> container) { var hash = CommonImplementation.GetHashCode(value); var posHash = (hash & 0x7FFFFFFF); tryAgain: var bucketIx = posHash % Buckets.Length; // three cases // #1 - bucket is empty // #2 - bucket isn't empty, and contains the value // #3 - bucket isn't empty, and doesn't contain the value if (Buckets[bucketIx].IsDefaultValue()) { // case #1 var valueIndex = container.PlaceIn(value); Buckets[bucketIx].SetInitial(valueIndex); return(true); } else { int _; if (Buckets[bucketIx].Contains(value, ref container.Items, out _)) { // case #2 return(false); } // case #3 if (TryGrow(ref container, ref Buckets)) { goto tryAgain; } var valueIndex = container.PlaceIn(value); Buckets[bucketIx].Append(valueIndex, null); return(true); } }
// creates a new GroupingEnumerable in groupings, updates the # of allocated groupings // and returns the index of the new grouping inserted into groupings // // resizes groupings if needed static int AddNewGrouping( TKey key, TElement element, ref IndexedItemContainer <TElement> container, ref SlimGrouping <TKey, TElement>[] groupings, ref int allocatedGroupings) { if (groupings.Length == allocatedGroupings) { var nextSize = CommonImplementation.NextSize(groupings.Length); Allocator.Current.ResizeArray(ref groupings, nextSize); } var ret = allocatedGroupings; groupings[allocatedGroupings].SetInitial(key, element, ref container); allocatedGroupings++; return(ret); }
internal void Add(TElement element, ref IndexedItemContainer <TElement> elements) { var nextIndex = elements.PlaceIn(element); if (ElementIndexes == null) { ElementIndexes = Allocator.Current.GetArray <int>(2); ElementIndexes[0] = (int)(UsedIndexes_SingleIndex - 1); UsedIndexes_SingleIndex = 1; } else { if (ElementIndexes.Length == UsedIndexes_SingleIndex) { Allocator.Current.ResizeArray(ref ElementIndexes, CommonImplementation.NextSize(ElementIndexes.Length)); } } ElementIndexes[UsedIndexes_SingleIndex] = nextIndex; UsedIndexes_SingleIndex++; }
static bool TryGrow(ref IndexedItemContainer <T> container, ref CompactSetBucket <T>[] buckets) { var usedValues = container.UsedItems; if (usedValues != buckets.Length) { return(false); } var oldBuckets = buckets; var newBuckets = Allocator.Current.GetArray <CompactSetBucket <T> >(CommonImplementation.NextSize(buckets.Length)); int[] reuseableArray = null; for (var i = 0; i < oldBuckets.Length; i++) { var oldBucket = oldBuckets[i]; if (oldBucket.IsDefaultValue()) { continue; } var numEntries = oldBucket.NumEntries; for (var j = 0; j < numEntries; j++) { var valueIx = oldBucket.GetEntry(j); var val = container.Items[valueIx]; var newBucketIx = (CommonImplementation.GetHashCode(val) & 0x7FFFFFFF) % newBuckets.Length; if (newBuckets[newBucketIx].IsDefaultValue()) { newBuckets[newBucketIx].SetInitial(valueIx); } else { newBuckets[newBucketIx].Append(valueIx, reuseableArray); reuseableArray = null; } } var nowAvailableArr = oldBucket.ValueIndexes; if (nowAvailableArr != null) { if (reuseableArray == null) { reuseableArray = nowAvailableArr; } else { if (nowAvailableArr.Length > reuseableArray.Length) { reuseableArray = nowAvailableArr; } } } } buckets = newBuckets; return(true); }