diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/NotifyCollectionChangedEventArgs.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/NotifyCollectionChangedEventArgs.cs index a98194b..bb6b6c7 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/NotifyCollectionChangedEventArgs.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/NotifyCollectionChangedEventArgs.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Specialized; +using System.Runtime.InteropServices; namespace ObservableCollections { @@ -17,6 +18,7 @@ namespace ObservableCollections /// Action.Reset /// - /// + [StructLayout(LayoutKind.Auto)] public readonly ref struct NotifyCollectionChangedEventArgs { public readonly NotifyCollectionChangedAction Action; diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.cs index 4bd8c81..3415f62 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/ObservableRingBuffer.cs @@ -193,6 +193,30 @@ namespace ObservableCollections } } + public T[] ToArray() + { + lock (SyncRoot) + { + return buffer.ToArray(); + } + } + + public int BinarySearch(T item) + { + lock (SyncRoot) + { + return buffer.BinarySearch(item); + } + } + + public int BinarySearch(T item, IComparer comparer) + { + lock (SyncRoot) + { + return buffer.BinarySearch(item, comparer); + } + } + public IEnumerator GetEnumerator() { lock (SyncRoot) diff --git a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/RingBuffer.cs b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/RingBuffer.cs index 4adeb8d..2b71878 100644 --- a/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/RingBuffer.cs +++ b/src/ObservableCollections.Unity/Assets/Plugins/ObservableCollections/Runtime/RingBuffer.cs @@ -270,6 +270,35 @@ namespace ObservableCollections return result; } + public int BinarySearch(T item) + { + return BinarySearch(item, Comparer.Default); + } + + public int BinarySearch(T item, IComparer comparer) + { + var lo = 0; + var hi = count - 1; + + while (lo <= hi) + { + var mid = (int)(((uint)hi + (uint)lo) >> 1); + var found = comparer.Compare(this[mid], item); + + if (found == 0) return mid; + if (found < 0) + { + lo = mid + 1; + } + else + { + hi = mid - 1; + } + } + + return ~lo; + } + void IList.Insert(int index, T item) { throw new NotSupportedException(); diff --git a/src/ObservableCollections/NotifyCollectionChangedEventArgs.cs b/src/ObservableCollections/NotifyCollectionChangedEventArgs.cs index 8353c81..9be0f6d 100644 --- a/src/ObservableCollections/NotifyCollectionChangedEventArgs.cs +++ b/src/ObservableCollections/NotifyCollectionChangedEventArgs.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Specialized; +using System.Runtime.InteropServices; namespace ObservableCollections { @@ -17,6 +18,7 @@ namespace ObservableCollections /// Action.Reset /// - /// + [StructLayout(LayoutKind.Auto)] public readonly ref struct NotifyCollectionChangedEventArgs { public readonly NotifyCollectionChangedAction Action; diff --git a/src/ObservableCollections/ObservableRingBuffer.cs b/src/ObservableCollections/ObservableRingBuffer.cs index fe4c8a4..3a92de2 100644 --- a/src/ObservableCollections/ObservableRingBuffer.cs +++ b/src/ObservableCollections/ObservableRingBuffer.cs @@ -193,6 +193,30 @@ namespace ObservableCollections } } + public T[] ToArray() + { + lock (SyncRoot) + { + return buffer.ToArray(); + } + } + + public int BinarySearch(T item) + { + lock (SyncRoot) + { + return buffer.BinarySearch(item); + } + } + + public int BinarySearch(T item, IComparer comparer) + { + lock (SyncRoot) + { + return buffer.BinarySearch(item, comparer); + } + } + public IEnumerator GetEnumerator() { lock (SyncRoot) diff --git a/src/ObservableCollections/RingBuffer.cs b/src/ObservableCollections/RingBuffer.cs index a4d24dd..f8ac262 100644 --- a/src/ObservableCollections/RingBuffer.cs +++ b/src/ObservableCollections/RingBuffer.cs @@ -270,6 +270,35 @@ namespace ObservableCollections return result; } + public int BinarySearch(T item) + { + return BinarySearch(item, Comparer.Default); + } + + public int BinarySearch(T item, IComparer comparer) + { + var lo = 0; + var hi = count - 1; + + while (lo <= hi) + { + var mid = (int)(((uint)hi + (uint)lo) >> 1); + var found = comparer.Compare(this[mid], item); + + if (found == 0) return mid; + if (found < 0) + { + lo = mid + 1; + } + else + { + hi = mid - 1; + } + } + + return ~lo; + } + void IList.Insert(int index, T item) { throw new NotSupportedException(); diff --git a/tests/ObservableCollections.Tests/RingBufferTest.cs b/tests/ObservableCollections.Tests/RingBufferTest.cs index f8c4e52..7b137f2 100644 --- a/tests/ObservableCollections.Tests/RingBufferTest.cs +++ b/tests/ObservableCollections.Tests/RingBufferTest.cs @@ -124,6 +124,42 @@ namespace ObservableCollections.Tests newArray.Should().Equal(0, 0, 199, 9, 999, 7, 6, 5, 1099, 4, 3, 888, 299, 0, 0); } + } + + // TODO: need more test. + [Fact] + public void BinarySearchTest() + { + var empty = new RingBuffer(new int[] { }); + var single = new RingBuffer(new[] { 10 }); + var buffer = new RingBuffer(new[] + { + 1, 4, 5, 6, 10, 14, 15,17, 20, 33 + }); + + empty.BinarySearch(99).Should().BeLessThan(0); + + { + single.BinarySearch(10).Should().Be(0); + var x1 = single.BinarySearch(4); + x1.Should().BeLessThan(0); + (~x1).Should().Be(0); + + var x2 = single.BinarySearch(40); + x2.Should().BeLessThan(0); + (~x2).Should().Be(1); + } + + { + buffer.BinarySearch(0); + + + } + + + + + } } }