-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSlabArray.cs
More file actions
82 lines (65 loc) · 2.59 KB
/
SlabArray.cs
File metadata and controls
82 lines (65 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MurrayGrant.MassiveSort
{
public sealed class SlabArray : IDisposable
{
readonly List<IMemoryOwner<byte>> _Slabs = new List<IMemoryOwner<byte>>();
readonly List<ReadOnlyMemory<byte>> _Memories = new List<ReadOnlyMemory<byte>>();
public ushort SlabCount => (ushort)_Slabs.Count;
public long Length => _Slabs.Sum(x => (long)x.Memory.Length);
public void AddSlab(IMemoryOwner<byte> slab)
{
_Slabs.Add(slab);
_Memories.Add(slab.Memory);
}
public ReadOnlySpan<byte> GetSpan(SlabIndex idx)
=> _Memories[idx.SlabNumber].Span.Slice(idx.Offset, idx.Length);
public ReadOnlyMemory<byte> GetMemory(SlabIndex idx)
=> _Memories[idx.SlabNumber].Slice(idx.Offset, idx.Length);
public void Dispose()
{
_Memories.Clear();
foreach (var s in _Slabs)
s.Dispose();
_Slabs.Clear();
}
}
public readonly struct SlabIndex : IEquatable<SlabIndex>
{
public SlabIndex(ushort slabNumber, int offset, int length)
{
if (length > 0x0001_ffff)
throw new ArgumentException(nameof(length), "Length must be less than or equal to 131071, but was " + length);
_SlabNumber = slabNumber;
_Length = (ushort)length;
_Offset = (uint)offset + (((uint)length & 0x0001_0000u) << 15);
}
public static SlabIndex Empty => new(0, 0, 0);
readonly UInt16 _SlabNumber;
// Top bit of Offset is added to Length. So there are 17 bits of Length and 31 bits of Offset.
readonly UInt16 _Length;
readonly UInt32 _Offset;
public ushort SlabNumber => _SlabNumber;
public int Length
=> (int)(_Length | ((_Offset & 0x8000_0000u) >> 15));
public int Offset
=> (int)(_Offset & 0x7fff_ffffu);
public override bool Equals([NotNullWhen(true)] object obj)
=> obj is SlabIndex x
&& Equals(x);
public bool Equals(SlabIndex other)
=> other._SlabNumber == _SlabNumber
&& other._Offset == _Offset
&& other._Length == _Length;
public override int GetHashCode()
=> HashCode.Combine(_SlabNumber, _Offset, _Length);
public override string ToString()
=> $"Slab# {SlabNumber}, Offset: {Offset}, Length: {Length}";
}
}