Skip to content

Commit

Permalink
DataCenterKeysTableReader: Read the table eagerly.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexrp committed Jan 6, 2024
1 parent fac1b05 commit c8ed19a
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 39 deletions.
3 changes: 3 additions & 0 deletions src/formats/Data/Serialization/Readers/DataCenterReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ public Task<DataCenterNode> ReadAsync(Stream stream, CancellationToken cancellat
await _nodes.ReadAsync(strict, reader, cancellationToken).ConfigureAwait(false);
await _values.ReadAsync(strict, reader, cancellationToken).ConfigureAwait(false);
await _names.ReadAsync(strict, reader, cancellationToken).ConfigureAwait(false);

_keys.Populate();

await _footer.ReadAsync(strict, reader, cancellationToken).ConfigureAwait(false);

Check.Data(
Expand Down
52 changes: 26 additions & 26 deletions src/formats/Data/Serialization/Tables/DataCenterKeysTableReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal sealed class DataCenterKeysTableReader
{
private readonly DataCenterSimpleRegion<DataCenterRawKeys> _keys = new(false);

private readonly ConcurrentDictionary<int, DataCenterKeys> _cache = new();
private readonly List<DataCenterKeys> _byIndex = new(ushort.MaxValue);

private readonly DataCenterStringTableReader _names;

Expand All @@ -22,39 +22,39 @@ public async ValueTask ReadAsync(StreamBinaryReader reader, CancellationToken ca
await _keys.ReadAsync(reader, cancellationToken).ConfigureAwait(false);
}

public DataCenterKeys GetKeys(int index)
public void Populate()
{
Check.Data(
index < _keys.Elements.Count, $"Keys table index {index} is out of bounds (0..{_keys.Elements.Count}).");
// This has to happen after the names string table has been read.

return _cache.GetOrAdd(
index,
static (i, @this) =>
for (var i = 0; i < _keys.Elements.Count; i++)
{
string? GetName(int index)
{
string? GetName(int index)
{
var nameIdx = index - 1;
var nameIdx = index - 1;

if (nameIdx == -1)
return null;

var name = _names.GetString(nameIdx);

if (nameIdx == -1)
return null;
Check.Data(
name != DataCenterConstants.ValueAttributeName,
$"Key entry refers to illegal attribute name '{name}'.");

var name = @this._names.GetString(nameIdx);
return name;
}

Check.Data(
name != DataCenterConstants.ValueAttributeName,
$"Key entry refers to illegal attribute name '{name}'.");
var raw = _keys.Elements[i];

return name;
}
_byIndex[i] = new(
GetName(raw.NameIndex1), GetName(raw.NameIndex2), GetName(raw.NameIndex3), GetName(raw.NameIndex4));
}
}

var raw = @this._keys.Elements[i];
public DataCenterKeys GetKeys(int index)
{
Check.Data(index < _byIndex.Count, $"Keys table index {index} is out of bounds (0..{_byIndex.Count}).");

return new(
GetName(raw.NameIndex1),
GetName(raw.NameIndex2),
GetName(raw.NameIndex3),
GetName(raw.NameIndex4));
},
this);
return _byIndex[index];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal sealed class DataCenterKeysTableWriter
{
private readonly DataCenterSimpleRegion<DataCenterRawKeys> _keys = new(false);

private readonly Dictionary<(string?, string?, string?, string?), int> _cache = new(ushort.MaxValue);
private readonly Dictionary<(string?, string?, string?, string?), int> _indexes = new(ushort.MaxValue);

private readonly DataCenterStringTableWriter _names;

Expand All @@ -26,7 +26,7 @@ public int AddKeys(string? attributeName1, string? attributeName2, string? attri
{
var tup = (attributeName1, attributeName2, attributeName3, attributeName4);

ref var index = ref CollectionsMarshal.GetValueRefOrAddDefault(_cache, tup, out var exists);
ref var index = ref CollectionsMarshal.GetValueRefOrAddDefault(_indexes, tup, out var exists);

if (!exists)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ internal sealed class DataCenterStringTableReader

private readonly DataCenterSimpleRegion<DataCenterRawAddress> _addresses = new(true);

private readonly Dictionary<DataCenterAddress, string> _addressCache = new(ushort.MaxValue);
private readonly Dictionary<DataCenterAddress, string> _byAddress = new(ushort.MaxValue);

private readonly List<string> _indexCache = new(ushort.MaxValue);
private readonly List<string> _byIndex = new(ushort.MaxValue);

public DataCenterStringTableReader(int count)
{
Expand Down Expand Up @@ -86,26 +86,25 @@ public async ValueTask ReadAsync(bool strict, StreamBinaryReader reader, Cancell
Check.Data(i == bucket, $"String bucket {i} does not match expected bucket {bucket}.");
}

Check.Data(_addressCache.TryAdd(addr, value), $"String address {addr} already recorded earlier.");
Check.Data(_byAddress.TryAdd(addr, value), $"String address {addr} already recorded earlier.");

cache.Add((index, value));
}
}

foreach (var (_, val) in cache.OrderBy(static tup => tup.Index))
_indexCache.Add(val);
_byIndex.AddRange(cache.OrderBy(static tup => tup.Index).Select(static tup => tup.Value));
}

public string GetString(int index)
{
Check.Data(index < _indexCache.Count, $"String table index {index} is invalid.");
Check.Data(index < _byIndex.Count, $"String table index {index} is out of bounds (0..{_byIndex.Count}).");

return _indexCache[index];
return _byIndex[index];
}

public string GetString(DataCenterAddress address)
{
Check.Data(_addressCache.TryGetValue(address, out var str), $"String table address {address} is invalid.");
Check.Data(_byAddress.TryGetValue(address, out var str), $"String table address {address} is invalid.");

return str;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ internal sealed class DataCenterStringTableWriter

private readonly DataCenterSimpleRegion<DataCenterRawAddress> _addresses = new(true);

private readonly Dictionary<string, DataCenterRawString> _cache = new(ushort.MaxValue);
private readonly Dictionary<string, DataCenterRawString> _entries = new(ushort.MaxValue);

private readonly bool _limit;

Expand All @@ -35,7 +35,7 @@ public async ValueTask WriteAsync(StreamBinaryWriter writer, CancellationToken c

public DataCenterRawString AddString(string value)
{
ref var raw = ref CollectionsMarshal.GetValueRefOrAddDefault(_cache, value, out var exists);
ref var raw = ref CollectionsMarshal.GetValueRefOrAddDefault(_entries, value, out var exists);

if (!exists)
{
Expand Down Expand Up @@ -108,6 +108,6 @@ public DataCenterRawString AddString(string value)

public DataCenterRawString GetString(string value)
{
return _cache[value];
return _entries[value];
}
}

0 comments on commit c8ed19a

Please sign in to comment.