From f3b47c85e9b498d7bef4341093baf880d3891d0e Mon Sep 17 00:00:00 2001 From: neuecc Date: Wed, 1 Sep 2021 09:46:15 +0900 Subject: [PATCH] w --- .../ObservableFixedSizeRingBuffer.cs | 89 ++++++++++++++++--- .../ObservableRingBuffer.cs | 21 +++++ 2 files changed, 97 insertions(+), 13 deletions(-) diff --git a/src/ObservableCollections/ObservableFixedSizeRingBuffer.cs b/src/ObservableCollections/ObservableFixedSizeRingBuffer.cs index caf08ce..1604806 100644 --- a/src/ObservableCollections/ObservableFixedSizeRingBuffer.cs +++ b/src/ObservableCollections/ObservableFixedSizeRingBuffer.cs @@ -71,8 +71,8 @@ namespace ObservableCollections { if (capacity == buffer.Count) { - buffer.RemoveLast(); - CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(item, capacity - 1)); + var remItem = buffer.RemoveLast(); + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(remItem, capacity - 1)); } buffer.AddFirst(item); @@ -86,8 +86,8 @@ namespace ObservableCollections { if (capacity == buffer.Count) { - buffer.RemoveLast(); - CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(item, capacity - 1)); + var remItem = buffer.RemoveLast(); + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(remItem, capacity - 1)); } buffer.AddLast(item); @@ -95,20 +95,62 @@ namespace ObservableCollections } } + public T RemoveFirst() + { + lock (SyncRoot) + { + var item = buffer.RemoveFirst(); + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(item, 0)); + return item; + } + } + + public T RemoveLast() + { + lock (SyncRoot) + { + var index = buffer.Count - 1; + var item = buffer.RemoveLast(); + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(item, index)); + return item; + } + } + // AddFirstRange is not exists. public void AddLastRange(IEnumerable items) { lock (SyncRoot) { - var index = buffer.Count; using (var xs = new CloneCollection(items)) { - foreach (var item in xs.Span) + if (capacity >= buffer.Count + xs.Span.Length - 1) + { + // calc remove count + var remCount = Math.Min(capacity, buffer.Count + xs.Span.Length - 1 - capacity); + using (var ys = new ResizableArray(remCount)) + { + for (int i = 0; i < remCount; i++) + { + ys.Add(buffer.RemoveFirst()); + } + + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(ys.Span, 0)); + } + } + + var index = buffer.Count; + var span = xs.Span; + if (span.Length > capacity) + { + span = span.Slice(span.Length - capacity); + } + + foreach (var item in span) { buffer.AddLast(item); } - CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Add(xs.Span, index)); + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Add(span, index)); } } } @@ -130,12 +172,33 @@ namespace ObservableCollections { lock (SyncRoot) { - var index = buffer.Count; - foreach (var item in items) - { - buffer.AddLast(item); - } - CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Add(items, index)); + if (capacity >= buffer.Count + xs.Span.Length - 1) + { + // calc remove count + var remCount = Math.Min(capacity, buffer.Count + xs.Span.Length - 1 - capacity); + using (var ys = new ResizableArray(remCount)) + { + for (int i = 0; i < remCount; i++) + { + ys.Add(buffer.RemoveFirst()); + } + + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(ys.Span, 0)); + } + } + + var index = buffer.Count; + var span = xs.Span; + if (span.Length > capacity) + { + span = span.Slice(span.Length - capacity); + } + + foreach (var item in span) + { + buffer.AddLast(item); + } + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Add(span, index)); } } diff --git a/src/ObservableCollections/ObservableRingBuffer.cs b/src/ObservableCollections/ObservableRingBuffer.cs index 2d3c19c..c59ab83 100644 --- a/src/ObservableCollections/ObservableRingBuffer.cs +++ b/src/ObservableCollections/ObservableRingBuffer.cs @@ -72,6 +72,27 @@ namespace ObservableCollections } } + public T RemoveFirst() + { + lock (SyncRoot) + { + var item = buffer.RemoveFirst(); + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(item, 0)); + return item; + } + } + + public T RemoveLast() + { + lock (SyncRoot) + { + var index = buffer.Count - 1; + var item = buffer.RemoveLast(); + CollectionChanged?.Invoke(NotifyCollectionChangedEventArgs.Remove(item, index)); + return item; + } + } + // AddFirstRange is not exists. public void AddLastRange(IEnumerable items)