Skip to content

Commit a38e93a

Browse files
committed
set up logical operations for indexset
1 parent 269365e commit a38e93a

File tree

3 files changed

+166
-89
lines changed

3 files changed

+166
-89
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using NUnit.Framework;
2+
3+
namespace FrameworkTests.Utils
4+
{
5+
[TestFixture]
6+
public class RunLengthEncodingLogicalTests
7+
{
8+
[Test]
9+
public void Overlap()
10+
{
11+
var setA = new IndexSet([1, 2, 3, 4, 5, 11, 14]);
12+
var setB = new IndexSet([3, 4, 5, 6, 7, 11, 12, 13]);
13+
var expectedSet = new IndexSet([3, 4, 5, 11]);
14+
15+
var set = setA.Overlap(setB);
16+
17+
Assert.That(set, Is.EqualTo(expectedSet));
18+
}
19+
20+
[Test]
21+
public void Merge()
22+
{
23+
var setA = new IndexSet([1, 2, 3, 4, 5, 11, 14]);
24+
var setB = new IndexSet([3, 4, 5, 6, 7, 11, 12, 13]);
25+
var expectedSet = new IndexSet([1, 2, 3, 4, 5, 6, 7, 11, 12, 13, 14]);
26+
27+
var set = setA.Merge(setB);
28+
29+
Assert.That(set, Is.EqualTo(expectedSet));
30+
}
31+
32+
[Test]
33+
public void Without()
34+
{
35+
var setA = new IndexSet([1, 2, 3, 4, 5, 11, 14]);
36+
var setB = new IndexSet([3, 4, 5, 6, 7, 11, 12, 13]);
37+
var expectedSet = new IndexSet([1, 2, 14]);
38+
39+
var set = setA.Without(setB);
40+
41+
Assert.That(set, Is.EqualTo(expectedSet));
42+
}
43+
}
44+
45+
public partial class IndexSet
46+
{
47+
public IndexSet Overlap(IndexSet other)
48+
{
49+
return this;
50+
}
51+
52+
public IndexSet Merge(IndexSet other)
53+
{
54+
return this;
55+
}
56+
57+
public IndexSet Without(IndexSet other)
58+
{
59+
return this;
60+
}
61+
62+
public override bool Equals(object? obj)
63+
{
64+
return obj is IndexSet set &&
65+
EqualityComparer<SortedList<int, Run>>.Default.Equals(runs, set.runs);
66+
}
67+
68+
public override int GetHashCode()
69+
{
70+
return HashCode.Combine(runs);
71+
}
72+
}
73+
}

Tests/FrameworkTests/Utils/RunLengthEncodingRunTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using NUnit.Framework;
2-
using NUnit.Framework.Interfaces;
3-
using static FrameworkTests.Utils.RunLengthEncodingTests;
42

53
namespace FrameworkTests.Utils
64
{

Tests/FrameworkTests/Utils/RunLengthEncodingTests.cs

Lines changed: 93 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
using Logging;
2-
using Microsoft.VisualStudio.TestPlatform.Common;
3-
using NuGet.Frameworks;
4-
using NUnit.Framework;
5-
using System.Collections.Concurrent;
6-
using System.Numerics;
1+
using NUnit.Framework;
72
using Utils;
83

94
namespace FrameworkTests.Utils
@@ -201,119 +196,130 @@ private int[] GenerateRandomIndices()
201196
all.Sort();
202197
return all.ToArray();
203198
}
199+
}
200+
201+
public partial class IndexSet
202+
{
203+
private readonly SortedList<int, Run> runs = new SortedList<int, Run>();
204204

205-
public class IndexSet
205+
public IndexSet()
206206
{
207-
private readonly SortedList<int, Run> runs = new SortedList<int, Run>();
207+
}
208208

209-
public IndexSet()
210-
{
211-
}
209+
public IndexSet(int[] indices)
210+
{
211+
foreach (var i in indices) Set(i);
212+
}
212213

213-
public IndexSet(int[] indices)
214+
public static IndexSet FromRunLengthEncoded(int[] rle)
215+
{
216+
var set = new IndexSet();
217+
for (var i = 0; i < rle.Length; i += 2)
214218
{
215-
foreach (var i in indices) Set(i);
219+
var start = rle[i];
220+
var length = rle[i + 1];
221+
set.runs.Add(start, new Run(start, length));
216222
}
217223

218-
public static IndexSet FromRunLengthEncoded(int[] rle)
219-
{
220-
var set = new IndexSet();
221-
for (var i = 0; i < rle.Length; i += 2)
222-
{
223-
var start = rle[i];
224-
var length = rle[i + 1];
225-
set.runs.Add(start, new Run(start, length));
226-
}
227-
228-
return set;
229-
}
224+
return set;
225+
}
230226

231-
public bool IsSet(int index)
232-
{
233-
if (runs.ContainsKey(index)) return true;
227+
public bool IsSet(int index)
228+
{
229+
if (runs.ContainsKey(index)) return true;
234230

235-
var run = GetRunBefore(index);
236-
if (run == null) return false;
231+
var run = GetRunBefore(index);
232+
if (run == null) return false;
237233

238-
return run.Includes(index);
239-
}
234+
return run.Includes(index);
235+
}
240236

241-
public void Set(int index)
242-
{
243-
if (runs.ContainsKey(index)) return;
237+
public void Set(int index)
238+
{
239+
if (runs.ContainsKey(index)) return;
244240

245-
var run = GetRunBefore(index);
246-
if (run == null || !run.ExpandToInclude(index))
247-
{
248-
CreateNewRun(index);
249-
}
241+
var run = GetRunBefore(index);
242+
if (run == null || !run.ExpandToInclude(index))
243+
{
244+
CreateNewRun(index);
250245
}
246+
}
251247

252-
public void Unset(int index)
248+
public void Unset(int index)
249+
{
250+
if (runs.ContainsKey(index))
253251
{
254-
if (runs.ContainsKey(index))
255-
{
256-
HandleUpdate(runs[index].Unset(index));
257-
}
258-
else
259-
{
260-
var run = GetRunBefore(index);
261-
if (run == null) return;
262-
HandleUpdate(run.Unset(index));
263-
}
252+
HandleUpdate(runs[index].Unset(index));
264253
}
265-
266-
public void Iterate(Action<int> onIndex)
254+
else
267255
{
268-
foreach (var run in runs.Values)
269-
{
270-
run.Iterate(onIndex);
271-
}
256+
var run = GetRunBefore(index);
257+
if (run == null) return;
258+
HandleUpdate(run.Unset(index));
272259
}
260+
}
273261

274-
public int[] RunLengthEncoded()
262+
public void Iterate(Action<int> onIndex)
263+
{
264+
foreach (var run in runs.Values)
275265
{
276-
return Encode().ToArray();
266+
run.Iterate(onIndex);
277267
}
268+
}
278269

279-
private IEnumerable<int> Encode()
270+
public int[] RunLengthEncoded()
271+
{
272+
return Encode().ToArray();
273+
}
274+
275+
public override string ToString()
276+
{
277+
var result = "";
278+
var encoded = RunLengthEncoded();
279+
foreach (var pair in runs)
280280
{
281-
foreach (var pair in runs)
282-
{
283-
yield return pair.Value.Start;
284-
yield return pair.Value.Length;
285-
}
281+
result += $"[{pair.Value.Start},{pair.Value.Length}]]";
286282
}
283+
return result;
284+
}
287285

288-
private Run? GetRunBefore(int index)
286+
private IEnumerable<int> Encode()
287+
{
288+
foreach (var pair in runs)
289289
{
290-
Run? result = null;
291-
foreach (var pair in runs)
292-
{
293-
if (pair.Key < index) result = pair.Value;
294-
else return result;
295-
}
296-
return result;
290+
yield return pair.Value.Start;
291+
yield return pair.Value.Length;
297292
}
293+
}
298294

299-
private void HandleUpdate(RunUpdate runUpdate)
295+
private Run? GetRunBefore(int index)
296+
{
297+
Run? result = null;
298+
foreach (var pair in runs)
300299
{
301-
foreach (var newRun in runUpdate.NewRuns) runs.Add(newRun.Start, newRun);
302-
foreach (var removeRun in runUpdate.RemoveRuns) runs.Remove(removeRun.Start);
300+
if (pair.Key < index) result = pair.Value;
301+
else return result;
303302
}
303+
return result;
304+
}
304305

305-
private void CreateNewRun(int index)
306+
private void HandleUpdate(RunUpdate runUpdate)
307+
{
308+
foreach (var newRun in runUpdate.NewRuns) runs.Add(newRun.Start, newRun);
309+
foreach (var removeRun in runUpdate.RemoveRuns) runs.Remove(removeRun.Start);
310+
}
311+
312+
private void CreateNewRun(int index)
313+
{
314+
if (runs.ContainsKey(index + 1))
315+
{
316+
var length = runs[index + 1].Length + 1;
317+
runs.Add(index, new Run(index, length));
318+
runs.Remove(index + 1);
319+
}
320+
else
306321
{
307-
if (runs.ContainsKey(index + 1))
308-
{
309-
var length = runs[index + 1].Length + 1;
310-
runs.Add(index, new Run(index, length));
311-
runs.Remove(index + 1);
312-
}
313-
else
314-
{
315-
runs.Add(index, new Run(index, 1));
316-
}
322+
runs.Add(index, new Run(index, 1));
317323
}
318324
}
319325
}

0 commit comments

Comments
 (0)