diff --git a/ICD.Common.Utils.Tests/Extensions/ListExtensionsTest.cs b/ICD.Common.Utils.Tests/Extensions/ListExtensionsTest.cs index b96facc..44aa8d1 100644 --- a/ICD.Common.Utils.Tests/Extensions/ListExtensionsTest.cs +++ b/ICD.Common.Utils.Tests/Extensions/ListExtensionsTest.cs @@ -8,14 +8,14 @@ namespace ICD.Common.Utils.Tests.Extensions public sealed class ListExtensionsTest { [Test] - public void AddSortedTest() + public void InsertSortedTest() { List testList = new List(); - Assert.AreEqual(0, testList.AddSorted(2)); - Assert.AreEqual(1, testList.AddSorted(3)); - Assert.AreEqual(0, testList.AddSorted(1)); - Assert.AreEqual(1, testList.AddSorted(2)); + Assert.AreEqual(0, testList.InsertSorted(2)); + Assert.AreEqual(1, testList.InsertSorted(3)); + Assert.AreEqual(0, testList.InsertSorted(1)); + Assert.AreEqual(1, testList.InsertSorted(2)); Assert.AreEqual(4, testList.Count); Assert.AreEqual(1, testList[0]); @@ -25,15 +25,15 @@ namespace ICD.Common.Utils.Tests.Extensions } [Test] - public void AddSortedComparerTest() + public void InsertSortedComparerTest() { List testList = new List(); IComparer comparer = new InverseComparer(); - Assert.AreEqual(0, testList.AddSorted(2, comparer)); - Assert.AreEqual(0, testList.AddSorted(3, comparer)); - Assert.AreEqual(2, testList.AddSorted(1, comparer)); - Assert.AreEqual(1, testList.AddSorted(2, comparer)); + Assert.AreEqual(0, testList.InsertSorted(2, comparer)); + Assert.AreEqual(0, testList.InsertSorted(3, comparer)); + Assert.AreEqual(2, testList.InsertSorted(1, comparer)); + Assert.AreEqual(1, testList.InsertSorted(2, comparer)); Assert.AreEqual(4, testList.Count); Assert.AreEqual(3, testList[0]); diff --git a/ICD.Common.Utils/Collections/IcdOrderedDictionary.cs b/ICD.Common.Utils/Collections/IcdOrderedDictionary.cs index 700cc54..01c88b0 100644 --- a/ICD.Common.Utils/Collections/IcdOrderedDictionary.cs +++ b/ICD.Common.Utils/Collections/IcdOrderedDictionary.cs @@ -106,7 +106,7 @@ namespace ICD.Common.Utils.Collections if (m_Dictionary.ContainsKey(key)) throw new ArgumentOutOfRangeException("key", "An item with the same key has already been added."); - int index = m_OrderedKeys.AddSorted(key, m_Comparer); + int index = m_OrderedKeys.InsertSorted(key, m_Comparer); m_ValuesOrderedByKey.Insert(index, value); m_Dictionary[key] = value; diff --git a/ICD.Common.Utils/Extensions/ListExtensions.cs b/ICD.Common.Utils/Extensions/ListExtensions.cs index e6e37a3..e66bc17 100644 --- a/ICD.Common.Utils/Extensions/ListExtensions.cs +++ b/ICD.Common.Utils/Extensions/ListExtensions.cs @@ -10,14 +10,157 @@ namespace ICD.Common.Utils.Extensions /// public static class ListExtensions { + #region Add Sorted + /// - /// Adds the items into a sorted list. + /// Attempts to add the item to the sorted list. + /// Returns false if the item already exists in the list. + /// + /// + /// + /// + /// + [PublicAPI] + public static bool AddSorted(this IList extends, T item) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + return extends.AddSorted(item, Comparer.Default); + } + + /// + /// Attempts to add the item to the sorted list. + /// Returns false if the item already exists in the list. + /// + /// + /// + /// + /// + /// + [PublicAPI] + public static bool AddSorted(this IList extends, T item, Func predicate) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + if (predicate == null) + throw new ArgumentNullException("predicate"); + + PredicateComparer comparer = new PredicateComparer(predicate); + return extends.AddSorted(item, comparer); + } + + /// + /// Attempts to add the item to the sorted list. + /// Returns false if the item already exists in the list. + /// + /// + /// + /// + /// + /// + [PublicAPI] + public static bool AddSorted(this IList extends, T item, IComparer comparer) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + if (comparer == null) + throw new ArgumentNullException("comparer"); + + int index = extends.BinarySearch(item, comparer); + if (index >= 0) + return false; + + index = ~index; + extends.Insert(index, item); + + return true; + } + + #endregion + + #region Remove Sorted + + /// + /// Attempts to remove the item from the sorted list. + /// Returns false if the item does not exist in the list. + /// + /// + /// + /// + /// + [PublicAPI] + public static bool RemoveSorted(this IList extends, T item) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + return extends.RemoveSorted(item, Comparer.Default); + } + + /// + /// Attempts to remove the item from the sorted list. + /// Returns false if the item does not exist in the list. + /// + /// + /// + /// + /// + /// + [PublicAPI] + public static bool RemoveSorted(this IList extends, T item, Func predicate) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + if (predicate == null) + throw new ArgumentNullException("predicate"); + + PredicateComparer comparer = new PredicateComparer(predicate); + return extends.RemoveSorted(item, comparer); + } + + /// + /// Attempts to remove the item from the sorted list. + /// Returns false if the item does not exist in the list. + /// + /// + /// + /// + /// + /// + [PublicAPI] + public static bool RemoveSorted(this IList extends, T item, IComparer comparer) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + if (comparer == null) + throw new ArgumentNullException("comparer"); + + int index = extends.BinarySearch(item, comparer); + if (index < 0) + return false; + + extends.RemoveAt(index); + + return true; + } + + #endregion + + #region Insert Sorted + + /// + /// Inserts the items into a sorted list. /// /// /// /// [PublicAPI] - public static void AddSorted(this IList extends, IEnumerable items) + public static void InsertSorted(this IList extends, IEnumerable items) { if (extends == null) throw new ArgumentNullException("extends"); @@ -25,18 +168,18 @@ namespace ICD.Common.Utils.Extensions if (items == null) throw new ArgumentNullException("items"); - extends.AddSorted(items, Comparer.Default); + extends.InsertSorted(items, Comparer.Default); } /// - /// Adds the items into a sorted list. + /// Inserts the items into a sorted list. /// /// /// /// /// [PublicAPI] - public static void AddSorted(this IList extends, IEnumerable items, IComparer comparer) + public static void InsertSorted(this IList extends, IEnumerable items, IComparer comparer) { if (extends == null) throw new ArgumentNullException("extends"); @@ -47,11 +190,11 @@ namespace ICD.Common.Utils.Extensions if (comparer == null) throw new ArgumentNullException("comparer"); - items.ForEach(i => extends.AddSorted(i, comparer)); + items.ForEach(i => extends.InsertSorted(i, comparer)); } /// - /// Adds the items into a sorted list. + /// Inserts the items into a sorted list. /// /// /// @@ -59,7 +202,7 @@ namespace ICD.Common.Utils.Extensions /// /// [PublicAPI] - public static void AddSorted(this IList extends, IEnumerable items, Func predicate) + public static void InsertSorted(this IList extends, IEnumerable items, Func predicate) { if (extends == null) throw new ArgumentNullException("extends"); @@ -71,33 +214,54 @@ namespace ICD.Common.Utils.Extensions throw new ArgumentNullException("predicate"); PredicateComparer comparer = new PredicateComparer(predicate); - extends.AddSorted(items, comparer); + extends.InsertSorted(items, comparer); } /// - /// Adds the item into a sorted list. + /// Inserts the item into a sorted list. /// /// /// /// [PublicAPI] - public static int AddSorted(this IList extends, T item) + public static int InsertSorted(this IList extends, T item) { if (extends == null) throw new ArgumentNullException("extends"); - return extends.AddSorted(item, Comparer.Default); + return extends.InsertSorted(item, Comparer.Default); } /// - /// Adds the item into a sorted list. + /// Inserts the item into a sorted list. + /// + /// + /// + /// + /// + /// + [PublicAPI] + public static int InsertSorted(this IList extends, T item, Func predicate) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + if (predicate == null) + throw new ArgumentNullException("predicate"); + + PredicateComparer comparer = new PredicateComparer(predicate); + return extends.InsertSorted(item, comparer); + } + + /// + /// Inserts the item into a sorted list. /// /// /// /// /// [PublicAPI] - public static int AddSorted(this IList extends, T item, IComparer comparer) + public static int InsertSorted(this IList extends, T item, IComparer comparer) { if (extends == null) throw new ArgumentNullException("extends"); @@ -114,27 +278,50 @@ namespace ICD.Common.Utils.Extensions return index; } + #endregion + + #region Contains Sorted + /// - /// Adds the item into a sorted list. + /// Returns true if the sorted list contains the given item. /// /// - /// /// /// - /// + /// [PublicAPI] - public static int AddSorted(this IList extends, T item, Func predicate) + public static bool ContainsSorted(this IList extends, T item) { if (extends == null) throw new ArgumentNullException("extends"); - if (predicate == null) - throw new ArgumentNullException("predicate"); - - PredicateComparer comparer = new PredicateComparer(predicate); - return extends.AddSorted(item, comparer); + return extends.ContainsSorted(item, Comparer.Default); } + /// + /// Returns true if the sorted list contains the given item. + /// + /// + /// + /// + /// + /// + [PublicAPI] + public static bool ContainsSorted(this IList extends, T item, IComparer comparer) + { + if (extends == null) + throw new ArgumentNullException("extends"); + + if (comparer == null) + throw new ArgumentNullException("comparer"); + + return extends.BinarySearch(item, comparer) >= 0; + } + + #endregion + + #region Binary Search + /// /// Returns the index of the item in the list. /// @@ -152,6 +339,17 @@ namespace ICD.Common.Utils.Extensions if (comparer == null) throw new ArgumentNullException("comparer"); + // Array + T[] array = extends as T[]; + if (array != null) + return Array.BinarySearch(array, 0, array.Length, item, comparer); + + // List + List list = extends as List; + if (list != null) + return list.BinarySearch(item, comparer); + + // IList int lo = 0; int hi = extends.Count - 1; @@ -171,5 +369,7 @@ namespace ICD.Common.Utils.Extensions return ~lo; } + + #endregion } } diff --git a/ICD.Common.Utils/Services/Scheduler/ActionSchedulerService.cs b/ICD.Common.Utils/Services/Scheduler/ActionSchedulerService.cs index 97bc41f..33b0b2e 100644 --- a/ICD.Common.Utils/Services/Scheduler/ActionSchedulerService.cs +++ b/ICD.Common.Utils/Services/Scheduler/ActionSchedulerService.cs @@ -39,7 +39,7 @@ namespace ICD.Common.Utils.Services.Scheduler try { Subscribe(action); - m_Actions.AddSorted(action, a => a.NextRunTime); + m_Actions.InsertSorted(action, a => a.NextRunTime); } finally { @@ -195,7 +195,7 @@ namespace ICD.Common.Utils.Services.Scheduler try { m_Actions.Remove(action); - m_Actions.AddSorted(action, a => a.NextRunTime); + m_Actions.InsertSorted(action, a => a.NextRunTime); } finally { diff --git a/ICD.Common.Utils/Timers/IcdStopwatch.cs b/ICD.Common.Utils/Timers/IcdStopwatch.cs index 0e0d84e..1b952d1 100644 --- a/ICD.Common.Utils/Timers/IcdStopwatch.cs +++ b/ICD.Common.Utils/Timers/IcdStopwatch.cs @@ -178,7 +178,7 @@ namespace ICD.Common.Utils.Timers long duration = stopwatch.ElapsedTicks; stopwatch.Stop(); - orderedMs.AddSorted(duration); + orderedMs.InsertSorted(duration); totalTicks += duration; }