< Summary

Information
Class: SwitchBlade.Core.ObservableCollectionSync
Assembly: SwitchBlade
File(s): D:\a\switchblade\switchblade\Core\ObservableCollectionSync.cs
Tag: 203_23722840422
Line coverage
100%
Covered lines: 35
Uncovered lines: 0
Coverable lines: 35
Total lines: 64
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Sync(...)100%1616100%

File(s)

D:\a\switchblade\switchblade\Core\ObservableCollectionSync.cs

#LineLine coverage
 1using System.Collections.Generic;
 2using System.Collections.ObjectModel;
 3
 4namespace SwitchBlade.Core
 5{
 6    /// <summary>
 7    /// Synchronizes an <see cref="ObservableCollection{T}"/> with a source list in-place,
 8    /// preserving object identity and minimizing UI change notifications.
 9    /// Uses a two-pointer algorithm for O(N) complexity.
 10    /// </summary>
 11    public static class ObservableCollectionSync
 12    {
 13        /// <summary>
 14        /// Synchronizes <paramref name="collection"/> to match <paramref name="source"/>
 15        /// while preserving existing object references and minimizing move/insert/remove operations.
 16        /// </summary>
 17        /// <typeparam name="T">Element type.</typeparam>
 18        /// <param name="collection">The observable collection to sync (mutated in-place).</param>
 19        /// <param name="source">The authoritative source list defining the desired order and content.</param>
 20        public static void Sync<T>(ObservableCollection<T> collection, IList<T> source)
 4021        {
 22            // Phase 1: Remove items not in source
 4023            var sourceSet = new HashSet<T>(source);
 14624            for (int i = collection.Count - 1; i >= 0; i--)
 3425            {
 3426                if (!sourceSet.Contains(collection[i]))
 1027                    collection.RemoveAt(i);
 3428            }
 29
 30            // Phase 2: Two-pointer sync for ordering and insertion
 3931            int ptr = 0;
 19832            for (int i = 0; i < source.Count; i++)
 6033            {
 6034                var item = source[i];
 6035                if (ptr < collection.Count && EqualityComparer<T>.Default.Equals(collection[ptr], item))
 1936                {
 1937                    ptr++;
 1938                }
 39                else
 4140                {
 4141                    int foundAt = -1;
 8442                    for (int j = ptr + 1; j < collection.Count; j++)
 643                    {
 644                        if (EqualityComparer<T>.Default.Equals(collection[j], item))
 545                        {
 546                            foundAt = j;
 547                            break;
 48                        }
 149                    }
 50
 4151                    if (foundAt != -1)
 552                    {
 553                        collection.Move(foundAt, ptr);
 554                    }
 55                    else
 3656                    {
 3657                        collection.Insert(ptr, item);
 3658                    }
 4159                    ptr++;
 4160                }
 6061            }
 3962        }
 63    }
 64}