Esempio n. 1
0
 internal LookupHashtable(int size, SlimGrouping <TKey, TElement>[] groupings, LookupBucket <TKey, TElement>[] buckets)
 {
     AllocatedGroupings = size;
     Groupings          = groupings;
     Buckets            = buckets;
     Container          = new IndexedItemContainer <TElement>();
 }
Esempio n. 2
0
        internal void SetInitial(TKey key, TElement element, ref IndexedItemContainer <TElement> elements)
        {
            Key = key;
            var firstIndex = elements.PlaceIn(element);

            UsedIndexes_SingleIndex = ((uint)firstIndex) + 1;
        }
Esempio n. 3
0
        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));
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        // 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);
        }
Esempio n. 6
0
        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++;
        }
Esempio n. 7
0
        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);
        }