Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit abc934d

Browse files
committed
Fix a bunch of things in the tracking collection
See https://github.com/shana/handy-things/commits/79d3baa for a list of fixes
1 parent 13cd10e commit abc934d

File tree

2 files changed

+29
-36
lines changed

2 files changed

+29
-36
lines changed

src/GitHub.Exports.Reactive/Collections/TrackingCollection.cs

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
using System.Reactive.Linq;
1616
using System.Reactive.Subjects;
1717
using System.Threading;
18-
using System.Threading.Tasks;
1918

2019
namespace GitHub.Collections
2120
{
@@ -30,15 +29,16 @@ namespace GitHub.Collections
3029
/// </summary>
3130
/// <typeparam name="T"></typeparam>
3231
public class TrackingCollection<T> : ObservableCollection<T>, ITrackingCollection<T>, IDisposable
33-
where T : class, ICopyable<T>, IComparable<T>
32+
where T : class, ICopyable<T>
3433
{
3534
enum TheAction
3635
{
3736
None,
3837
Move,
3938
Add,
4039
Insert,
41-
Remove
40+
Remove,
41+
Ignore
4242
}
4343

4444
bool isChanging;
@@ -83,10 +83,7 @@ enum TheAction
8383
public TimeSpan ProcessingDelay
8484
{
8585
get { return requestedDelay; }
86-
set
87-
{
88-
requestedDelay = value;
89-
}
86+
set { requestedDelay = value; }
9087
}
9188

9289
bool ManualProcessing => cache.IsEmpty && originalSourceIsCompleted;
@@ -105,7 +102,7 @@ public TrackingCollection(Func<T, T, int> comparer = null, Func<T, int, IList<T>
105102
#endif
106103
this.comparer = comparer ?? Comparer<T>.Default.Compare;
107104
this.filter = filter;
108-
this.newer = newer ?? Comparer<T>.Default.Compare;
105+
this.newer = newer;
109106
}
110107

111108
public TrackingCollection(IObservable<T> source,
@@ -132,8 +129,12 @@ public IObservable<T> Listen(IObservable<T> obs)
132129

133130
Reset();
134131

132+
// ManualResetEvent uses the realtime clock for accurate <50ms delays
135133
var waitHandle = new ManualResetEventSlim();
136134

135+
// empty the source observable as fast as possible
136+
// to the cache queue, and signal that data is available
137+
// for processing
137138
dataPump = obs
138139
.Do(data =>
139140
{
@@ -147,7 +148,6 @@ public IObservable<T> Listen(IObservable<T> obs)
147148
})
148149
.Publish();
149150

150-
151151
// when both signalHaveData and signalNeedData produce a value, dataListener gets a value
152152
// this will empty the queue of items that have been cached in regular intervals according
153153
// to the requested delay
@@ -167,7 +167,8 @@ public IObservable<T> Listen(IObservable<T> obs)
167167
source = dataListener
168168
.Where(data => data.Item != null)
169169
.ObserveOn(scheduler)
170-
.Select(data => {
170+
.Select(data =>
171+
{
171172
data = ProcessItem(data, original);
172173

173174
// if we're removing an item that doesn't exist, ignore it
@@ -197,7 +198,6 @@ public IObservable<T> Listen(IObservable<T> obs)
197198
signalOriginalSourceCompletion = false;
198199
originalSourceCompleted.OnNext(Unit.Default);
199200
}
200-
201201
}
202202
else
203203
signalNeedData.OnNext(Unit.Default);
@@ -339,16 +339,6 @@ void SetAndRecalculateFilter(Func<T, int, IList<T>, bool> newFilter)
339339

340340
#region Source pipeline processing
341341

342-
ActionData CheckFilter(ActionData data)
343-
{
344-
var isIncluded = true;
345-
if (data.TheAction == TheAction.Remove)
346-
isIncluded = false;
347-
else if (filter != null)
348-
isIncluded = filter(data.Item, data.Position, this);
349-
return new ActionData(data, isIncluded);
350-
}
351-
352342
int StartQueue()
353343
{
354344
disposables.Add(cachePump.Connect());
@@ -382,11 +372,12 @@ ActionData ProcessItem(ActionData data, List<T> list)
382372
if (idx >= 0)
383373
{
384374
var old = list[idx];
385-
var isNewer = newer(item, old);
386-
387-
// the object is "older" than the one we have, ignore it
388-
if (isNewer > 0)
389-
ret = new ActionData(TheAction.None, list, item, null, idx, idx);
375+
if (newer != null)
376+
{
377+
// the object is "older" than the one we have, ignore it
378+
if (newer(item, old) > 0)
379+
return new ActionData(TheAction.Ignore, list, item, null, idx, idx);
380+
}
390381

391382
var comparison = comparer(item, old);
392383

@@ -466,10 +457,20 @@ ActionData SortedRemove(ActionData data)
466457
// unfiltered list update
467458
sortedIndexCache.Remove(data.Item);
468459
UpdateIndexCache(data.List.Count - 1, data.OldPosition, data.List, sortedIndexCache);
469-
original.Remove(data.Item);
460+
data.List.Remove(data.Item);
470461
return data;
471462
}
472463

464+
ActionData CheckFilter(ActionData data)
465+
{
466+
var isIncluded = true;
467+
if (data.TheAction == TheAction.Remove)
468+
isIncluded = false;
469+
else if (filter != null)
470+
isIncluded = filter(data.Item, data.Position, this);
471+
return new ActionData(data, isIncluded);
472+
}
473+
473474
ActionData FilteredAdd(ActionData data)
474475
{
475476
if (data.TheAction != TheAction.Add)

src/TrackingCollectionTests/TrackingCollectionTests.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public void OrderByUpdatedFilter()
7777
Observable.Never<Thing>(),
7878
OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
7979
(item, position, list) => true,
80-
OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare);
80+
OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare);
8181
col.ProcessingDelay = TimeSpan.Zero;
8282

8383
var list1 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, count - i, "Run 1")).ToList());
@@ -475,7 +475,6 @@ public void SortingTest()
475475
ITrackingCollection<Thing> col = new TrackingCollection<Thing>(
476476
source,
477477
OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare);
478-
col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
479478
col.ProcessingDelay = TimeSpan.Zero;
480479

481480
var count = 0;
@@ -671,7 +670,6 @@ public void SortingTestWithFilterTrue()
671670
source,
672671
OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare,
673672
(item, position, list) => true);
674-
col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
675673
col.ProcessingDelay = TimeSpan.Zero;
676674

677675
var count = 0;
@@ -860,7 +858,6 @@ public void SortingTestWithFilterBetween6And12()
860858
source,
861859
OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare,
862860
(item, position, list) => item.UpdatedAt.Minute >= 6 && item.UpdatedAt.Minute <= 12);
863-
col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
864861
col.ProcessingDelay = TimeSpan.Zero;
865862

866863
var count = 0;
@@ -1015,7 +1012,6 @@ public void SortingTestWithFilterPosition2to4()
10151012
source,
10161013
OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare,
10171014
(item, position, list) => position >= 2 && position <= 4);
1018-
col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
10191015
col.ProcessingDelay = TimeSpan.Zero;
10201016

10211017
var count = 0;
@@ -1163,7 +1159,6 @@ public void SortingTestWithFilterPosition1And3to4()
11631159
source,
11641160
OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare,
11651161
(item, position, list) => position == 1 || (position >= 3 && position <= 4));
1166-
col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
11671162
col.ProcessingDelay = TimeSpan.Zero;
11681163

11691164
var count = 0;
@@ -1327,7 +1322,6 @@ public void SortingTestWithFilterMoves()
13271322
source,
13281323
OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
13291324
(item, position, list) => (position >= 1 && position <= 2) || (position >= 5 && position <= 7));
1330-
col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
13311325
col.ProcessingDelay = TimeSpan.Zero;
13321326

13331327
var count = 0;
@@ -1445,7 +1439,6 @@ public void ChangingItemContentRemovesItFromFilteredList2()
14451439
source,
14461440
OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare,
14471441
(item, position, list) => item.UpdatedAt > now + TimeSpan.FromMinutes(2) && item.UpdatedAt < now + TimeSpan.FromMinutes(8));
1448-
col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
14491442
col.ProcessingDelay = TimeSpan.Zero;
14501443

14511444
var count = 0;
@@ -1760,7 +1753,6 @@ public void Removing()
17601753
source,
17611754
OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
17621755
(item, position, list) => (position > 2 && position < 5) || (position > 6 && position < 8));
1763-
col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
17641756
col.ProcessingDelay = TimeSpan.Zero;
17651757

17661758
var count = 0;

0 commit comments

Comments
 (0)