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); }
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); }