コード例 #1
0
        /// <summary>
        /// Moves unique entries to the front of the list.
        /// </summary>
        private int MoveUniqueEntriesToFront(List <OrderByPropertyEntry> sortedData, OrderByPropertyComparer comparer)
        {
            // If we have sorted data then we know we have at least one unique item
            int uniqueCount = sortedData.Count > 0 ? 1 : 0;

            // Move the first of each unique entry to the front of the list
            for (int uniqueItemIndex = 0, nextUniqueItemIndex = 1; uniqueItemIndex < sortedData.Count && uniqueCount != Top; uniqueItemIndex++, nextUniqueItemIndex++)
            {
                // Identify the index of the next unique item
                while (nextUniqueItemIndex < sortedData.Count && comparer.Compare(sortedData[uniqueItemIndex], sortedData[nextUniqueItemIndex]) == 0)
                {
                    nextUniqueItemIndex++;
                }

                // If there are no more unique items, break
                if (nextUniqueItemIndex == sortedData.Count)
                {
                    break;
                }

                // Move the next unique item forward and increment the unique item counter
                sortedData[uniqueItemIndex + 1] = sortedData[nextUniqueItemIndex];
                uniqueCount++;
            }

            return(uniqueCount);
        }
コード例 #2
0
 private static int FindInObjectGroups(List <GroupInfo> groups, OrderByPropertyEntry target, OrderByPropertyComparer comparer)
 {
     for (int i = 0; i < groups.Count; i++)
     {
         if (comparer.Compare(groups[i].GroupValue, target) == 0)
         {
             return(i);
         }
     }
     return(-1);
 }
コード例 #3
0
        /// <summary>
        /// Utility function called by Group-Object to create Groups.
        /// </summary>
        /// <param name="currentObjectEntry">Input object that needs to be grouped.</param>
        /// <param name="noElement">True if we are not accumulating objects.</param>
        /// <param name="groups">List containing Groups.</param>
        /// <param name="groupInfoDictionary">Dictionary used to keep track of the groups with hash of the property values being the key.</param>
        /// <param name="orderByPropertyComparer">The Comparer to be used while comparing to check if new group has to be created.</param>
        private static void DoOrderedGrouping(
            OrderByPropertyEntry currentObjectEntry,
            bool noElement,
            List <GroupInfo> groups,
            Dictionary <object, GroupInfo> groupInfoDictionary,
            OrderByPropertyComparer orderByPropertyComparer)
        {
            var currentObjectOrderValues = currentObjectEntry.orderValues;

            if (currentObjectOrderValues != null && currentObjectOrderValues.Count > 0)
            {
                object currentTupleObject = PSTuple.ArrayToTuple(currentObjectOrderValues);

                if (groupInfoDictionary.TryGetValue(currentTupleObject, out var currentGroupInfo))
                {
                    // add this inputObject to an existing group
                    currentGroupInfo.Add(currentObjectEntry.inputObject);
                }
                else
                {
                    bool isCurrentItemGrouped = false;

                    if (groups.Count > 0)
                    {
                        var lastGroup = groups[groups.Count - 1];

                        // Check if the current input object can be converted to one of the already known types
                        // by looking up in the type to GroupInfo mapping.
                        if (orderByPropertyComparer.Compare(lastGroup.GroupValue, currentObjectEntry) == 0)
                        {
                            lastGroup.Add(currentObjectEntry.inputObject);
                            isCurrentItemGrouped = true;
                        }
                    }

                    if (!isCurrentItemGrouped)
                    {
                        // create a new group
                        s_tracer.WriteLine("Create a new group: {0}", currentObjectOrderValues);
                        GroupInfo newObjGrp = noElement
                            ? new GroupInfoNoElement(currentObjectEntry)
                            : new GroupInfo(currentObjectEntry);

                        groups.Add(newObjGrp);

                        groupInfoDictionary.Add(currentTupleObject, newObjGrp);
                    }
                }
            }
        }
コード例 #4
0
        /// <summary>
        /// Utility function called by Group-Object to create Groups.
        /// </summary>
        /// <param name="currentObjectEntry">Input object that needs to be grouped.</param>
        /// <param name="noElement">true if we are not accumulating objects</param>
        /// <param name="groups">List containing Groups.</param>
        /// <param name="groupInfoDictionary">Dictionary used to keep track of the groups with hash of the property values being the key.</param>
        /// <param name="orderByPropertyComparer">The Comparer to be used while comparing to check if new group has to be created.</param>
        internal static void DoGrouping(OrderByPropertyEntry currentObjectEntry, bool noElement, List <GroupInfo> groups, Dictionary <object, GroupInfo> groupInfoDictionary,
                                        OrderByPropertyComparer orderByPropertyComparer)
        {
            if (currentObjectEntry != null && currentObjectEntry.orderValues != null && currentObjectEntry.orderValues.Count > 0)
            {
                object currentTupleObject = PSTuple.ArrayToTuple(currentObjectEntry.orderValues.ToArray());

                GroupInfo currentGroupInfo = null;
                if (groupInfoDictionary.TryGetValue(currentTupleObject, out currentGroupInfo))
                {
                    if (currentGroupInfo != null)
                    {
                        //add this inputObject to an existing group
                        currentGroupInfo.Add(currentObjectEntry.inputObject);
                    }
                }
                else
                {
                    bool isCurrentItemGrouped = false;

                    for (int groupsIndex = 0; groupsIndex < groups.Count; groupsIndex++)
                    {
                        // Check if the current input object can be converted to one of the already known types
                        // by looking up in the type to GroupInfo mapping.
                        if (orderByPropertyComparer.Compare(groups[groupsIndex].GroupValue, currentObjectEntry) == 0)
                        {
                            groups[groupsIndex].Add(currentObjectEntry.inputObject);
                            isCurrentItemGrouped = true;
                            break;
                        }
                    }

                    if (!isCurrentItemGrouped)
                    {
                        // create a new group
                        s_tracer.WriteLine("Create a new group: {0}", currentObjectEntry.orderValues);
                        GroupInfo newObjGrp = noElement ? new GroupInfoNoElement(currentObjectEntry) : new GroupInfo(currentObjectEntry);
                        groups.Add(newObjGrp);

                        groupInfoDictionary.Add(currentTupleObject, newObjGrp);
                    }
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// The following is the matching algorithm:
        /// Retrieve the incoming object (differenceEntry) if any
        /// Retrieve the next reference object (referenceEntry) if any
        /// If differenceEntry matches referenceEntry
        ///   Emit referenceEntry as a match
        ///   Return
        /// If differenceEntry matches any entry in referenceEntryBacklog
        ///   Emit the backlog entry as a match
        ///   Remove the backlog entry from referenceEntryBacklog
        ///   Clear differenceEntry
        /// If referenceEntry (if any) matches any entry in differenceEntryBacklog
        ///   Emit referenceEntry as a match
        ///   Remove the backlog entry from differenceEntryBacklog
        ///   Clear referenceEntry
        /// If differenceEntry is still present
        ///   If SyncWindow is 0
        ///     Emit differenceEntry as unmatched
        ///   Else
        ///     While there is no space in differenceEntryBacklog
        ///       Emit oldest entry in differenceEntryBacklog as unmatched
        ///       Remove oldest entry from differenceEntryBacklog
        ///     Add differenceEntry to differenceEntryBacklog
        /// If referenceEntry is still present
        ///   If SyncWindow is 0
        ///     Emit referenceEntry as unmatched
        ///   Else
        ///     While there is no space in referenceEntryBacklog
        ///       Emit oldest entry in referenceEntryBacklog as unmatched
        ///       Remove oldest entry from referenceEntryBacklog
        ///     Add referenceEntry to referenceEntryBacklog.
        /// </summary>
        /// <param name="differenceEntry"></param>
        private void Process(OrderByPropertyEntry differenceEntry)
        {
            Diagnostics.Assert(_referenceEntries != null, "null referenceEntries");

            // Retrieve the next reference object (referenceEntry) if any
            OrderByPropertyEntry referenceEntry = null;

            if (_referenceObjectIndex < _referenceEntries.Count)
            {
                referenceEntry = _referenceEntries[_referenceObjectIndex++];
            }

            // If differenceEntry matches referenceEntry
            //   Emit referenceEntry as a match
            //   Return
            // 2005/07/19 Switched order of referenceEntry and differenceEntry
            //   so that we cast differenceEntry to the type of referenceEntry.
            if (referenceEntry != null && differenceEntry != null &&
                0 == _comparer.Compare(referenceEntry, differenceEntry))
            {
                EmitMatch(referenceEntry);
                return;
            }

            // If differenceEntry matches any entry in referenceEntryBacklog
            //   Emit the backlog entry as a match
            //   Remove the backlog entry from referenceEntryBacklog
            //   Clear differenceEntry
            OrderByPropertyEntry matchingEntry =
                MatchAndRemove(differenceEntry, _referenceEntryBacklog);

            if (matchingEntry != null)
            {
                EmitMatch(matchingEntry);
                differenceEntry = null;
            }

            // If referenceEntry (if any) matches any entry in differenceEntryBacklog
            //   Emit referenceEntry as a match
            //   Remove the backlog entry from differenceEntryBacklog
            //   Clear referenceEntry
            matchingEntry =
                MatchAndRemove(referenceEntry, _differenceEntryBacklog);
            if (matchingEntry != null)
            {
                EmitMatch(referenceEntry);
                referenceEntry = null;
            }

            // If differenceEntry is still present
            //   If SyncWindow is 0
            //     Emit differenceEntry as unmatched
            //   Else
            //     While there is no space in differenceEntryBacklog
            //       Emit oldest entry in differenceEntryBacklog as unmatched
            //       Remove oldest entry from differenceEntryBacklog
            //     Add differenceEntry to differenceEntryBacklog
            if (differenceEntry != null)
            {
                if (0 < SyncWindow)
                {
                    while (_differenceEntryBacklog.Count >= SyncWindow)
                    {
                        EmitDifferenceOnly(_differenceEntryBacklog[0]);
                        _differenceEntryBacklog.RemoveAt(0);
                    }

                    _differenceEntryBacklog.Add(differenceEntry);
                }
                else
                {
                    EmitDifferenceOnly(differenceEntry);
                }
            }

            // If referenceEntry is still present
            //   If SyncWindow is 0
            //     Emit referenceEntry as unmatched
            //   Else
            //     While there is no space in referenceEntryBacklog
            //       Emit oldest entry in referenceEntryBacklog as unmatched
            //       Remove oldest entry from referenceEntryBacklog
            //     Add referenceEntry to referenceEntryBacklog
            if (referenceEntry != null)
            {
                if (0 < SyncWindow)
                {
                    while (_referenceEntryBacklog.Count >= SyncWindow)
                    {
                        EmitReferenceOnly(_referenceEntryBacklog[0]);
                        _referenceEntryBacklog.RemoveAt(0);
                    }

                    _referenceEntryBacklog.Add(referenceEntry);
                }
                else
                {
                    EmitReferenceOnly(referenceEntry);
                }
            }
        }