Skip to content

Commit 841613b

Browse files
committed
add SwissTable-style mirroring, compaction scopes, and probe-safe APIs
Implemented mirrored control-byte padding to allow SIMD probing across table boundaries without branches. Normalized all slot addressing using power-of-two masking to prevent out-of-bounds entry access. Rewrote Insert, InsertOrUpdate, Get, Update, Remove, Contains, and GetValueRefOrAddDefault to be mirror-safe and slot-normalized. Added in-place table Rehash() to compact tombstones without resizing. Added automatic rehash trigger based on tombstone pressure. Introduced rehash suppression scopes (BeginRehashScope / EndRehashScope) for O(n) bulk deletes without rebuild thrashing. Fixed enumeration (Entries, Keys, Values) to avoid mirrored tail duplication. Hardened probe logic to preserve SwissTable invariants under wrap-around SIMD reads. This change set brings DenseMap’s internal behavior in line with Abseil SwissTable while maintaining API stability.
1 parent ff6e83f commit 841613b

22 files changed

+787
-779
lines changed

.github/workflows/dotnet.yml

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflow will build a .NET project
2-
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net
3-
41
name: .NET
52

63
on:
@@ -11,24 +8,21 @@ on:
118

129
jobs:
1310
build:
14-
1511
runs-on: ubuntu-latest
1612

1713
steps:
18-
- uses: actions/checkout@v4
19-
- name: Setup .NET
20-
uses: actions/setup-dotnet@v4
21-
with:
22-
dotnet-version: 9.0.x
14+
- uses: actions/checkout@v4
2315

24-
- name: Restore dependencies
25-
run: dotnet restore Faster.Map.sln
16+
- name: Setup .NET
17+
uses: actions/setup-dotnet@v4
18+
with:
19+
dotnet-version: 10.0.x
2620

27-
- name: Restore nuget packages
28-
run: nuget restore Faster.Map.sln
21+
- name: Restore
22+
run: dotnet restore Faster.Map.sln
2923

30-
- name: Build
31-
run: dotnet build --no-restore
24+
- name: Build
25+
run: dotnet build Faster.Map.sln --configuration Release --no-restore
3226

33-
- name: Test
34-
run: dotnet test --no-build --verbosity normal
27+
- name: Test
28+
run: dotnet test Faster.Map.sln --configuration Release --no-build --verbosity normal

Faster.Map.sln

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio Version 17
4-
VisualStudioVersion = 17.0.31825.309
3+
# Visual Studio Version 18
4+
VisualStudioVersion = 18.3.11222.16 d18.3
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Faster.Map.Benchmark", "benchmarks\Faster.Map.Benchmark\Faster.Map.Benchmark.csproj", "{1643EE6A-F080-49DE-817E-C0698BDCA3C6}"
77
EndProject
@@ -27,6 +27,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Faster.Map.Hash.Tests", "un
2727
EndProject
2828
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Faster.Map.BlitzMap.Tests", "unittests\Faster.Map.BlitzMap.Tests\Faster.Map.BlitzMap.Tests.csproj", "{E35C4248-3003-9067-9112-A58F11053905}"
2929
EndProject
30+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B57801ED-1345-4B7E-AC0E-845643C09CBC}"
31+
ProjectSection(SolutionItems) = preProject
32+
.github\workflows\dotnet.yml = .github\workflows\dotnet.yml
33+
EndProjectSection
34+
EndProject
3035
Global
3136
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3237
Debug|Any CPU = Debug|Any CPU

benchmarks/Faster.Map.Benchmark/AddAndResizeBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public void DenseMap()
6363
{
6464
foreach (var key in keys)
6565
{
66-
_denseMap.Emplace(key, key);
66+
_denseMap.InsertOrUpdate(key, key);
6767
}
6868
}
6969

benchmarks/Faster.Map.Benchmark/AddBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public void DenseMap()
8585
for (int i = 0; i < keys.Length; i++)
8686
{
8787
var key = keys[i];
88-
_dense.Emplace(key, key);
88+
_dense.InsertOrUpdate(key, key);
8989
}
9090
}
9191

benchmarks/Faster.Map.Benchmark/EnumerableBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public void Setup()
6666
foreach (var key in keys)
6767
{
6868
_dictionary.Add(key, key);
69-
_denseMap.Emplace(key, key);
69+
_denseMap.InsertOrUpdate(key, key);
7070
_blitz.Insert(key, key);
7171
_robinHoodMap.Emplace(key, key);
7272
}

benchmarks/Faster.Map.Benchmark/GetBenchmark.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,21 @@ public void Setup()
6565
foreach (var key in keys)
6666
{
6767
_dictionary.Add(key, key);
68-
_denseMap.Emplace(key, key);
68+
_denseMap.InsertOrUpdate(key, key);
6969
_blitz.Insert(key, key);
7070
_robinHoodMap.Emplace(key, key);
7171
}
7272
}
7373

74-
[Benchmark]
75-
public void BlitzMap()
76-
{
77-
for (int i = 0; i < keys.Length; i++)
78-
{
79-
var key = keys[i];
80-
_blitz.Get(key, out var _);
81-
}
82-
}
74+
//[Benchmark]
75+
//public void BlitzMap()
76+
//{
77+
// for (int i = 0; i < keys.Length; i++)
78+
// {
79+
// var key = keys[i];
80+
// _blitz.Get(key, out var _);
81+
// }
82+
//}
8383

8484
[Benchmark]
8585
public void DenseMap()

benchmarks/Faster.Map.Benchmark/LargeStringBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public void Setup()
7373
{
7474
var key = keys[i];
7575
_dictionary.Add(key, key);
76-
_dense.Emplace(key, key);
76+
_dense.InsertOrUpdate(key, key);
7777
_robinhoodMap.Emplace(key, key);
7878
_blitzMap.Insert(key, key);
7979
}

benchmarks/Faster.Map.Benchmark/RemoveBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public void IterationSetupX(BenchmarkCase benchmarkCase)
9191
_blitz.Insert(key, key);
9292
break;
9393
case nameof(DenseMap):
94-
_denseMap.Emplace(key, key);
94+
_denseMap.InsertOrUpdate(key, key);
9595
break;
9696
case nameof(RobinhoodMap):
9797
_robinHoodMap.Emplace(key, key);

benchmarks/Faster.Map.Benchmark/StringBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void Setup()
6565
{
6666
var key = keys[i];
6767
_dictionary.Add(key, key);
68-
_dense.Emplace(key, key);
68+
_dense.InsertOrUpdate(key, key);
6969
_robinhoodMap.Emplace(key, key);
7070
_blitzMap.Insert(key, key);
7171
}

benchmarks/Faster.Map.Benchmark/UpdateBenchmark.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public void Setup()
6767
foreach (var key in keys)
6868
{
6969
_dictionary.Add(key, key);
70-
_denseMap.Emplace(key, key);
70+
_denseMap.InsertOrUpdate(key, key);
7171
_blitz.Insert(key, key);
7272
_robinHoodMap.Emplace(key, key);
7373
}

0 commit comments

Comments
 (0)