示例#1
0
        //---------------------------------------------------------------------------------------
        // MoveNext will invoke the entire query sub-tree, accumulating results into a hash-
        // table, upon the first call. Then for the first call and all subsequent calls, we will
        // just enumerate the key-set from the hash-table, retrieving groupings of key-elements.
        //

        internal override bool MoveNext(ref IGrouping <TGroupKey, TElement> currentElement, ref TOrderKey currentKey)
        {
            Debug.Assert(_source != null);
            Debug.Assert(_keySelector != null);

            // Lazy-init the mutable state. This also means we haven't yet built our lookup of
            // groupings, so we can go ahead and do that too.
            Mutables mutables = _mutables;

            if (mutables == null)
            {
                mutables = _mutables = new Mutables();

                // Build the hash lookup and start enumerating the lookup at the beginning.
                mutables._hashLookup = BuildHashLookup();
                Debug.Assert(mutables._hashLookup != null);
                mutables._hashLookupIndex = -1;
            }

            // Now, with a hash lookup in hand, we just enumerate the keys. So long
            // as the key-value lookup has elements, we have elements.
            if (++mutables._hashLookupIndex < mutables._hashLookup.Count)
            {
                GroupKeyData value = mutables._hashLookup[mutables._hashLookupIndex].Value;
                currentElement = value._grouping;
                currentKey     = value._orderKey;
                return(true);
            }

            return(false);
        }
        //-----------------------------------------------------------------------------------
        // Builds the hash lookup, transforming from TSource to TElement through whatever means is appropriate.
        //

        protected override HashLookup <Wrapper <TGroupKey>, GroupKeyData> BuildHashLookup()
        {
            HashLookup <Wrapper <TGroupKey>, GroupKeyData> hashLookup = new HashLookup <Wrapper <TGroupKey>, GroupKeyData>(
                new WrapperEqualityComparer <TGroupKey>(_keyComparer));

            Pair <TSource, TGroupKey> sourceElement = default(Pair <TSource, TGroupKey>);
            TOrderKey sourceOrderKey = default(TOrderKey) !;
            int       i = 0;

            while (_source.MoveNext(ref sourceElement, ref sourceOrderKey))
            {
                if ((i++ & CancellationState.POLL_INTERVAL) == 0)
                {
                    _cancellationToken.ThrowIfCancellationRequested();
                }
                ;

                // Generate a key and place it into the hashtable.
                Wrapper <TGroupKey> key = new Wrapper <TGroupKey>(sourceElement.Second);

                // If the key already exists, we just append it to the existing list --
                // otherwise we will create a new one and add it to that instead.
                GroupKeyData?currentValue = null;
                if (hashLookup.TryGetValue(key, ref currentValue))
                {
                    if (_orderComparer.Compare(sourceOrderKey, currentValue._orderKey) < 0)
                    {
                        currentValue._orderKey = sourceOrderKey;
                    }
                }
                else
                {
                    currentValue = new GroupKeyData(sourceOrderKey, key.Value, _orderComparer);

                    hashLookup.Add(key, currentValue);
                }

                Debug.Assert(currentValue != null);

                // Call to the base class to yield the current value.
                currentValue._grouping.Add(_elementSelector(sourceElement.First), sourceOrderKey);
            }

            // Sort the elements within each group
            for (int j = 0; j < hashLookup.Count; j++)
            {
                hashLookup[j].Value._grouping.DoneAdding();
            }

            return(hashLookup);
        }
示例#3
0
        internal override bool MoveNext(ref IGrouping <TGroupKey, TElement> currentElement, ref TOrderKey currentKey)
        {
            Mutables <TSource, TGroupKey, TElement, TOrderKey> mutables = this.m_mutables;

            if (mutables == null)
            {
                mutables = this.m_mutables = new Mutables <TSource, TGroupKey, TElement, TOrderKey>();
                mutables.m_hashLookup      = this.BuildHashLookup();
                mutables.m_hashLookupIndex = -1;
            }
            if (++mutables.m_hashLookupIndex < mutables.m_hashLookup.Count)
            {
                KeyValuePair <Wrapper <TGroupKey>, GroupKeyData <TSource, TGroupKey, TElement, TOrderKey> > pair = mutables.m_hashLookup[mutables.m_hashLookupIndex];
                GroupKeyData <TSource, TGroupKey, TElement, TOrderKey> data = pair.Value;
                currentElement = data.m_grouping;
                currentKey     = data.m_orderKey;
                return(true);
            }
            return(false);
        }
            public bool Add(THashKey hashKey, TElement element, TOrderKey orderKey)
            {
                bool hasCollision = true;

                GroupKeyData?currentValue = default(GroupKeyData);

                if (!_base.TryGetValue(hashKey, ref currentValue))
                {
                    currentValue = new GroupKeyData(orderKey, hashKey, _orderKeyComparer);
                    _base.Add(hashKey, currentValue);
                    hasCollision = false;
                }

                currentValue._grouping.Add(element, orderKey);
                if (_orderKeyComparer.Compare(orderKey, currentValue._orderKey) < 0)
                {
                    currentValue._orderKey = orderKey;
                }

                return(hasCollision);
            }
 protected override Pair <IEnumerable <TElement>, Pair <bool, TOrderKey> > CreateValuePair(GroupKeyData baseValue)
 {
     return(new Pair <IEnumerable <TElement>, Pair <bool, TOrderKey> >(baseValue._grouping, Wrap(baseValue._orderKey)));
 }