Ejemplo n.º 1
0
        private IEnumerable <MergeRecord> Reorder(List <T> remainings, IEnumerable <int> existingInOthers)
        {
            var items = remainings.ToList();

            remainings.Clear();
            var indexes  = existingInOthers.ToList();
            var maxIndex = 0;
            var count    = items.Count;
            var result   = new List <MergeRecord>();

            for (var k = 0; k < count; k++)
            {
                var localMax = int.MinValue;
                for (var i = 0; i < indexes.Count; i++)
                {
                    if (indexes[i] > localMax)
                    {
                        maxIndex = i;
                        localMax = indexes[i];
                    }
                }
                result.Add(MergeRecord.ForMove(items[maxIndex], remainings.Count + maxIndex, 0));
                remainings.Insert(0, items[maxIndex]);
                items.RemoveAt(maxIndex);
                indexes.RemoveAt(maxIndex);
            }
            return(result);
        }
Ejemplo n.º 2
0
 private MergeRecord GetOrCreate(string name)
 {
     if (!records.TryGetValue(name, out MergeRecord record))
     {
         record = new MergeRecord(name);
         records.Add(name, record);
     }
     return(record);
 }
Ejemplo n.º 3
0
            public static MergeRecord ForMove(object item, int oldIndex, int newIndex)
            {
                var result = new MergeRecord();

                result.Items.Add(item);
                result.IsMove     = true;
                result.StartIndex = oldIndex;
                result.NewIndex   = newIndex;
                return(result);
            }
Ejemplo n.º 4
0
        /// <summary>
        /// Combines all the records in the specified Record Holder with
        /// the current combination formulas in this object.
        /// </summary>
        /// <param name="holder">The collection of records which hsould be merged.</param>
        /// <returns>A new <see cref="IRecordHolder"/> which contains the aggregated
        /// data of all the previous records.</returns>
        public IRecordHolder Merge(IRecordHolder holder)
        {
            if (holder == null)
            {
                throw new ArgumentNullException(nameof(holder));
            }

            // Combines all the records in a merge record.
            foreach (Record record in holder)
            {
                string      group = mergeClass(record);
                MergeRecord merge = GetOrCreate(group);
                foreach ((string measureName, object measureValue) in record.Measures)
                {
                    merge.AddMeasure(measureName, measureValue);
                }
            }

            DirectRecordHolder recordHolder = new DirectRecordHolder();

            // Aggregates all the data in a merge record into a single value.
            foreach (string measureName in holder.MeasureNames)
            {
                recordHolder.AddMeasureName(measureName);
            }
            Parallel.ForEach(records, recordPair => {
                string name       = recordPair.Key;
                MergeRecord merge = recordPair.Value;

                foreach (KeyValuePair <string, MergeMeasures> cPair in classMeasures)
                {
                    merge.AddMergeFunction(cPair.Key, cPair.Value);
                }
                foreach (KeyValuePair <Type, MergeMeasures> tPair in typeMeasures)
                {
                    merge.AddMergeFunction(tPair.Key, tPair.Value);
                }

                merge.Merge();
                recordHolder.AddRecord(merge);
            });

            return(recordHolder);
        }
Ejemplo n.º 5
0
        private static List <MergeRecord> RemoveOldValues(List <T> remainings, List <T> others, out List <int> existingPositions)
        {
            var result     = new List <MergeRecord>();
            var i          = 0;
            var dictionary = others.SafeToDictionary(item => item, item => i++);
            var othersSet  = others.ToHashSet();

            existingPositions = new List <int>();
            MergeRecord currentMergeRecord = null;
            var         index = 0;
            var         array = remainings.ToArray();

            remainings.Clear();
            foreach (var item in array)
            {
                if (!othersSet.Contains(item))
                {
                    if (currentMergeRecord == null)
                    {
                        currentMergeRecord = new MergeRecord();
                        currentMergeRecord.Update(item, false, index++);
                        result.Add(currentMergeRecord);
                    }
                    else
                    {
                        currentMergeRecord.Update(item);
                        index++;
                    }
                }
                else
                {
                    existingPositions.Add(dictionary[item]);
                    remainings.Add(item);
                    index++;
                    if (currentMergeRecord != null)
                    {
                        index -= currentMergeRecord.Items.Count;
                        currentMergeRecord = null;
                    }
                }
            }
            return(result);
        }
Ejemplo n.º 6
0
        protected override IEnumerable <MergeRecord> UpdateOverride(IEnumerable <T> others)
        {
            if (others == null)
            {
                Clear();
                return(Enumerable.Empty <MergeRecord>());
            }

            var myEnumerator    = GetEnumerator();
            var othersArray     = others as T[] ?? others.ToArray();
            var otherEnumerator = othersArray.GetEnumerator();
            var thisHas         = myEnumerator.MoveNext();
            var otherHas        = otherEnumerator.MoveNext();

            if (!thisHas && otherHas)
            {
                ViewArray = (T[])othersArray.Clone();
                return(new List <MergeRecord> {
                    new MergeRecord {
                        StartIndex = 0, IsAdd = true, Items = ViewArray
                    }
                });
            }
            if (thisHas && !otherHas)
            {
                var oldItems = ViewArray;
                ViewArray = new T[0];
                return(new List <MergeRecord> {
                    new MergeRecord {
                        StartIndex = 0, IsAdd = false, Items = oldItems
                    }
                });
            }
            var         newArray      = new T[othersArray.Count()];
            var         index         = 0;
            MergeRecord currentRecord = null;
            var         result        = new List <MergeRecord>();

            while (thisHas && otherHas)
            {
                var myItem        = myEnumerator.Current;
                var otherItem     = (T)otherEnumerator.Current;
                var compareResult = Comparison(myItem, otherItem);
                if (compareResult < 0)
                {
                    if (currentRecord == null || currentRecord.IsAdd)
                    {
                        var isAdd = currentRecord != null;
                        currentRecord = new MergeRecord();
                        result.Add(currentRecord);
                        currentRecord.Update(myItem, false, index + (isAdd ? 1 : 0));
                    }
                    else
                    {
                        currentRecord.Update(myItem);
                    }

                    thisHas = myEnumerator.MoveNext();
                }
                else if (compareResult > 0)
                {
                    if (currentRecord == null || !currentRecord.IsAdd)
                    {
                        currentRecord = new MergeRecord();
                        result.Add(currentRecord);
                        currentRecord.Update(otherItem, true, index);
                    }
                    else
                    {
                        currentRecord.Update(otherItem);
                    }

                    newArray[index++] = otherItem;
                    otherHas          = otherEnumerator.MoveNext();
                }
                else
                {
                    if (!Equals(myItem, otherItem))
                    {
                        if (currentRecord == null || !currentRecord.IsReplace)
                        {
                            currentRecord = new MergeRecord();
                            result.Add(currentRecord);
                            currentRecord.UpdateReplace(myItem, otherItem, index);
                        }
                        else
                        {
                            currentRecord.UpdateReplace(myItem, otherItem);
                        }
                        newArray[index++] = otherItem;
                    }
                    else
                    {
                        currentRecord   = null;
                        newArray[index] = otherItem;
                        index++;
                    }
                    thisHas  = myEnumerator.MoveNext();
                    otherHas = otherEnumerator.MoveNext();
                }
            }
            // Se acabó el primero pero le queda al segundo
            if (otherHas)
            {
                if (currentRecord == null || currentRecord.IsReplace || !currentRecord.IsAdd)
                {
                    currentRecord = new MergeRecord {
                        IsAdd = true, StartIndex = index
                    };
                    result.Add(currentRecord);
                }
                while (otherHas)
                {
                    var current = (T)otherEnumerator.Current;
                    newArray[index++] = current;
                    currentRecord.Update(current);
                    otherHas = otherEnumerator.MoveNext();
                }
            }
            // Se acabó el segundo pero le queda al primero
            if (thisHas)
            {
                if (currentRecord == null || currentRecord.IsReplace || currentRecord.IsAdd)
                {
                    currentRecord = new MergeRecord {
                        IsAdd = false, StartIndex = index
                    };
                    result.Add(currentRecord);
                }
                while (thisHas)
                {
                    currentRecord.Update(myEnumerator.Current);
                    thisHas = myEnumerator.MoveNext();
                }
            }
            ViewArray = newArray;
            return(result);
        }