78 Commits

Author SHA1 Message Date
5a132799a4 Add cycles_total
Some checks failed
Tests / Clang total: 2840, passed: 2840
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 2838, passed: 2838
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-08-15 15:13:00 -07:00
72469ebb6e Erase along left spine. Not faster 2024-08-15 15:07:44 -07:00
6c79847a42 Add instructions_total for linux 2024-08-15 15:06:53 -07:00
405a2ca161 Fix typo 2024-08-15 13:52:51 -07:00
f93466316a Pass in-tree reference to mergeWithChild 2024-08-15 13:52:06 -07:00
5626cd09d9 Add to corpus 2024-08-15 11:50:04 -07:00
41840220c3 Optimize version handling in mergeWithChild 2024-08-15 11:49:13 -07:00
7ff00e7846 Extract mergeWithChild to function 2024-08-15 11:40:52 -07:00
6242f40d48 Require that eraseBetween leave at least one child or entryPresent 2024-08-15 11:37:36 -07:00
403d70a1d3 Prefer not copying node in eraseBetween
If numChildren + entryPresent is enough, we don't have to copy even if
it would fit in a smaller node.

If we have to copy, we might as well use the smallest acceptable node
type.
2024-08-15 11:33:16 -07:00
9763452713 Separate beginIsPrefix path and simplify slightly 2024-08-15 11:29:15 -07:00
73d0593fca Remove separate prefix write codepath for now 2024-08-14 21:29:43 -07:00
23c2a3e1c6 SIMD for eraseBetween (Node16)
Some checks failed
Tests / Clang total: 2688, passed: 2688
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 2686, passed: 2686
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-08-14 18:12:46 -07:00
a64e792964 Remove unused function 2024-08-14 17:40:04 -07:00
5e362d5330 Add to corpus 2024-08-14 17:37:18 -07:00
cc526cb6ba Call eraseBetween on useAsRoot in addWriteRange 2024-08-14 17:08:55 -07:00
7e49888bec More eraseBetween optimizations 2024-08-14 16:40:29 -07:00
e64ebabced eraseBetween optimizations 2024-08-14 16:13:37 -07:00
1e34951a77 Fix use-of-uninit in eraseBetween (Node256) 2024-08-14 15:25:10 -07:00
baf64520d6 Have eraseBetween take in-tree node by reference 2024-08-14 15:04:11 -07:00
3499626127 Fix potential strict aliasing issues 2024-08-14 15:01:34 -07:00
b7f9084694 destroyTree -> eraseTree. Use freelist 2024-08-14 14:47:22 -07:00
4b82502946 Accept node by ref for eraseBetween again 2024-08-14 14:43:19 -07:00
68bbacb69a Use getInTree in eraseBetween 2024-08-14 14:43:19 -07:00
3078845673 Fix nodes_released accounting 2024-08-14 14:43:19 -07:00
43f6126cc4 Add a missing assert, call to removeNode 2024-08-14 14:43:19 -07:00
b911d87d55 eraseBetween bug fixes 2024-08-14 14:43:19 -07:00
0c65a82b78 Separate codepath for prefix writes
Uses the newly-added eraseBetween
2024-08-14 14:43:19 -07:00
e024cb8291 Track entriesErased in destroyTree 2024-08-14 14:43:19 -07:00
0740dcad43 Strengthen checkMemoryBoundInvariants check for Node0
I think this is probably checked elsewhere, but let's check here too for
consistency
2024-08-14 14:28:28 -07:00
176df61321 Simplify handling of beginNode invalidation if begin is prefix of end 2024-08-14 14:26:13 -07:00
0a850f22e9 Update README benchmarks
All checks were successful
Tests / Clang total: 2264, passed: 2264
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 2262, passed: 2262
Tests / SIMD fallback total: 2264, passed: 2264
Tests / Release [gcc] total: 2264, passed: 2264
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1690, passed: 1690
Tests / Coverage total: 1700, passed: 1700
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.34% (1809/1821) * Branch Coverage: 67.61% (1476/2183) * Complexity Density: 0.00 * Lines of Code: 1821 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
2024-08-12 17:33:45 -07:00
479b39d055 Add to corpus
Some checks reported errors
Tests / Clang total: 2264, passed: 2264
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 2262, passed: 2262
Tests / SIMD fallback total: 2264, passed: 2264
Tests / Release [gcc] total: 2264, passed: 2264
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1690, passed: 1690
Tests / Coverage total: 1700, passed: 1700
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.34% (1809/1821) * Branch Coverage: 67.61% (1476/2183) * Complexity Density: 0.00 * Lines of Code: 1821 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head Something is wrong with the build of this commit
2024-08-12 17:28:19 -07:00
482408d725 Add GCOVR_EXCL_LINE to __builtin_unreachable 2024-08-12 17:07:55 -07:00
45995e3307 Update comments 2024-08-12 17:05:21 -07:00
359b0b29ff Avoid function call if no partial key 2024-08-12 16:33:03 -07:00
54e47ebd40 Simplify insert loop 2024-08-12 16:25:12 -07:00
1c9dda68a6 Call consumePartialKey from getOrCreateChild 2024-08-12 16:24:05 -07:00
142455dd28 Move consumePartialKey, and allow empty partial key 2024-08-12 16:18:58 -07:00
567d385fbd WIP create child in getOrCreateChild 2024-08-12 16:11:16 -07:00
8a44055533 Consume first byte in insert iteration 2024-08-12 15:39:09 -07:00
62516825d1 Try specifying filter multiple times
Some checks failed
Tests / Clang total: 2096, failed: 520, passed: 1576
Tests / Debug total: 2094, failed: 520, passed: 1574
Tests / SIMD fallback total: 2096, passed: 2096
Tests / Release [gcc] total: 2096, passed: 2096
Tests / Release [gcc,aarch64] total: 1564, passed: 1564
Tests / Coverage total: 1574, passed: 1574
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-08-12 15:26:36 -07:00
3d592bd6a9 Move longestCommonPrefix to its own file
Some checks failed
Tests / Clang total: 2096, failed: 520, passed: 1576
Tests / Debug total: 2094, failed: 520, passed: 1574
Tests / SIMD fallback total: 2096, passed: 2096
Tests / Release [gcc] total: 2096, passed: 2096
Tests / Release [gcc,aarch64] total: 1564, passed: 1564
Tests / Coverage total: 1574, passed: 1574
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-08-12 15:10:05 -07:00
f5f5fb620b Run gc at 200%
150% pessimized the "real data" benchmark
2024-08-12 10:48:24 -07:00
e3d1b2e842 Add to corpus
All checks were successful
Tests / Clang total: 2096, passed: 2096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 2094, passed: 2094
Tests / SIMD fallback total: 2096, passed: 2096
Tests / Release [gcc] total: 2096, passed: 2096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1564, passed: 1564
Tests / Coverage total: 1574, passed: 1574
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.34% (1803/1815) * Branch Coverage: 67.55% (1486/2200) * Complexity Density: 0.00 * Lines of Code: 1815 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
After a bunch of fuzzing on "udon" (my new zen4 machine)
2024-08-09 19:48:22 -07:00
9f8800af16 Add more to corpus (from fuzzing on osx)
Some checks reported errors
Tests / Clang total: 1784, passed: 1784
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1782, passed: 1782
Tests / SIMD fallback total: 1784, passed: 1784
Tests / Release [gcc] total: 1784, passed: 1784
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1330, passed: 1330
Tests / Coverage total: 1340, passed: 1340
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.12% (1799/1815) * Branch Coverage: 67.50% (1485/2200) * Complexity Density: 0.00 * Lines of Code: 1815 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head Something is wrong with the build of this commit
Maybe we should just accumulate the corpus instead of replacing it? That
should be easier on git right?
2024-08-09 18:06:54 -07:00
182c065c8e Insert common prefix in addWriteRange
Some checks failed
Tests / Clang total: 1420, passed: 1420
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1418, passed: 1418
Tests / SIMD fallback total: 1420, passed: 1420
Tests / Release [gcc] total: 1420, passed: 1420
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1057, passed: 1057
Tests / Coverage total: 1067, passed: 1067
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.12% (1799/1815) * Branch Coverage: 67.50% (1485/2200) * Complexity Density: 0.00 * Lines of Code: 1815 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head There was a failure building this commit
This allows us to use our optimized implementation for setting max
version along the search path instead of a one-off loop
2024-08-09 14:57:04 -07:00
2dba0d5be3 Have insert return a pointer to the in-tree pointer 2024-08-09 13:58:31 -07:00
a1dfdf355c Use metrics to count change in entry count
This lets us run gc slower safely
2024-08-09 13:44:49 -07:00
15919cb1c4 Add range writes to server_bench 2024-08-09 13:43:24 -07:00
5ed9003a83 Bump version
All checks were successful
Tests / Clang total: 1420, passed: 1420
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1418, passed: 1418
Tests / SIMD fallback total: 1420, passed: 1420
Tests / Release [gcc] total: 1420, passed: 1420
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1057, passed: 1057
Tests / Coverage total: 1067, passed: 1067
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.34% (1817/1829) * Branch Coverage: 67.49% (1503/2227) * Complexity Density: 0.00 * Lines of Code: 1829 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
2024-08-08 12:09:26 -07:00
84c6a2bfc2 Disable debug symbols and frame pointer for macos
All checks were successful
Tests / Clang total: 1420, passed: 1420
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1418, passed: 1418
Tests / SIMD fallback total: 1420, passed: 1420
Tests / Release [gcc] total: 1420, passed: 1420
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1057, passed: 1057
Tests / Coverage total: 1067, passed: 1067
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.34% (1817/1829) * Branch Coverage: 67.49% (1503/2227) * Complexity Density: 0.00 * Lines of Code: 1829 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
This causes some versions of clang to crash
2024-08-08 11:51:13 -07:00
b5772a6aa0 Revert "Use homebrew clang for packaging for macos"
This reverts commit c20c08f112.
2024-08-08 11:50:13 -07:00
e6c39981b9 Bump version
All checks were successful
Tests / Clang total: 1420, passed: 1420
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1418, passed: 1418
Tests / SIMD fallback total: 1420, passed: 1420
Tests / Release [gcc] total: 1420, passed: 1420
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1057, passed: 1057
Tests / Coverage total: 1067, passed: 1067
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.34% (1817/1829) * Branch Coverage: 67.49% (1503/2227) * Complexity Density: 0.00 * Lines of Code: 1829 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
2024-08-08 11:26:49 -07:00
c20c08f112 Use homebrew clang for packaging for macos
All checks were successful
Tests / Clang total: 1420, passed: 1420
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1418, passed: 1418
Tests / SIMD fallback total: 1420, passed: 1420
Tests / Release [gcc] total: 1420, passed: 1420
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1057, passed: 1057
Tests / Coverage total: 1067, passed: 1067
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.34% (1817/1829) * Branch Coverage: 67.49% (1503/2227) * Complexity Density: 0.00 * Lines of Code: 1829 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
The default segfaults now for some reason
2024-08-08 11:06:26 -07:00
ac98d4a443 Remove always_inline attribute - it wasn't affecting codegen
Some checks failed
Tests / Clang total: 1420, passed: 1420
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1418, passed: 1418
Tests / SIMD fallback total: 1420, passed: 1420
Tests / Release [gcc] total: 1420, passed: 1420
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1057, passed: 1057
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-08-08 10:44:54 -07:00
1d9e8ab68b Add missing test coverage for fixupMaxVersion for Node256
All checks were successful
Tests / Clang total: 1420, passed: 1420
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1418, passed: 1418
Tests / SIMD fallback total: 1420, passed: 1420
Tests / Release [gcc] total: 1420, passed: 1420
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1057, passed: 1057
Tests / Coverage total: 1067, passed: 1067
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.34% (1816/1828) * Branch Coverage: 65.33% (1528/2339) * Complexity Density: 0.00 * Lines of Code: 1828 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
2024-08-07 17:02:19 -07:00
7d86beb14c Revert 29c05187fb
We're already doing this in checkRangeStartsWith
2024-08-07 16:51:23 -07:00
2fa954ed36 Fix compiler warning 2024-08-07 16:25:49 -07:00
ded6e7fc2c Require entry present for fixupMaxVersion 2024-08-06 17:59:38 -07:00
781ba15cae Enforce that root does not have a partial key 2024-08-06 17:55:33 -07:00
9b56a74b2f Update corpus 2024-08-06 17:43:48 -07:00
6da9cbdec9 Update benchmarks
Some checks failed
Tests / Clang total: 1479, passed: 1479
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1477, passed: 1477
Tests / SIMD fallback total: 1479, passed: 1479
Tests / Release [gcc] total: 1479, passed: 1479
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1102, passed: 1102
Tests / Coverage total: 1111, passed: 1111
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 98.00% (1812/1849) * Branch Coverage: 64.20% (1521/2369) * Complexity Density: 0.00 * Lines of Code: 1849 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-08-06 16:07:16 -07:00
29c05187fb Early return if common prefix isn't a prefix of an entry
Some checks failed
Tests / Clang total: 1479, passed: 1479
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1477, passed: 1477
Tests / SIMD fallback total: 1479, passed: 1479
Tests / Release [gcc] total: 1479, passed: 1479
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1102, passed: 1102
Tests / Coverage total: 1111, passed: 1111
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 98.00% (1812/1849) * Branch Coverage: 64.20% (1521/2369) * Complexity Density: 0.00 * Lines of Code: 1849 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head There was a failure building this commit
For range reads
2024-08-06 15:32:44 -07:00
d89028dd2f Inline SearchStepWise into checkRangeRead
This improves clang codegen
2024-08-06 14:45:52 -07:00
09cf807747 Avoid some branches on node type while inserting
Some checks failed
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-08-06 13:51:49 -07:00
051eb5919d Extract consumePartialKey to its own function 2024-08-06 13:20:44 -07:00
ed5589e4ed Specialize partial key split for newly created Node3 2024-08-06 13:04:19 -07:00
a7b3d8fe4c Clarify insert documentation 2024-08-06 11:29:33 -07:00
c3a047fdf8 Handle newly-created node partial key immediately 2024-08-06 09:22:21 -07:00
b4b469a175 Use maxOfMax in fixupMaxVersion
Some checks failed
Tests / Clang total: 1479, passed: 1479
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1477, passed: 1477
Tests / SIMD fallback total: 1479, passed: 1479
Tests / Release [gcc] total: 1479, passed: 1479
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1102, passed: 1102
Tests / Coverage total: 1111, passed: 1111
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 98.83% (1776/1797) * Branch Coverage: 64.91% (1506/2320) * Complexity Density: 0.00 * Lines of Code: 1797 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-08-05 21:41:49 -07:00
0201e27498 Remove redundant setMaxVersion calls 2024-08-05 19:29:38 -07:00
2010920a2c Correct comment 2024-08-05 19:28:24 -07:00
19af8da65c Fix endNode's max version after the fact
This sets us up to unconditionally update the max version along the
search path for inserts, and avoid dispatching on type twice per
iteration.
2024-08-05 17:50:26 -07:00
80785e3c3b Avoid switch on parent type for max version during search 2024-08-05 16:40:58 -07:00
4580ee44b4 Add range reads to ServerBench
All checks were successful
Tests / Clang total: 1479, passed: 1479
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 1477, passed: 1477
Tests / SIMD fallback total: 1479, passed: 1479
Tests / Release [gcc] total: 1479, passed: 1479
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1102, passed: 1102
Tests / Coverage total: 1111, passed: 1111
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.60% (1739/1746) * Branch Coverage: 64.95% (1492/2297) * Complexity Density: 0.00 * Lines of Code: 1746 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good
2024-08-05 15:44:13 -07:00
2d3985ca40 Add a simple point read/write workload to ServerBench 2024-08-05 14:37:00 -07:00
c8be68db40 Add ServerBench.cpp 2024-08-05 12:20:38 -07:00
1082 changed files with 1498 additions and 574 deletions

View File

@@ -361,7 +361,21 @@ void benchWorstCaseForRadixRangeRead() {
void benchCreateAndDestroy() {
ankerl::nanobench::Bench bench;
bench.run("create and destroy", [&]() { ConflictSet cs{0}; });
bench.run("create and destroy", [&]() {
ConflictSet cs{0};
ConflictSet::WriteRange w;
uint8_t b[9];
b[8] = 0;
for (int64_t i = 0; i < 1000; i += 7) {
auto x = __builtin_bswap64(i);
memcpy(b, &x, 8);
w.begin.p = b;
w.begin.len = 8;
w.end.len = 0;
w.end.p = b;
cs.addWrites(&w, 1, 1);
}
});
}
int main(void) {

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.18)
project(
conflict-set
VERSION 0.0.10
VERSION 0.0.12
DESCRIPTION
"A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys."
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/conflict-set"
@@ -31,14 +31,12 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
"MinSizeRel" "RelWithDebInfo")
endif()
add_compile_options(
-fdata-sections
-ffunction-sections
-Wswitch-enum
-Werror=switch-enum
-fPIC
-g
-fno-omit-frame-pointer)
add_compile_options(-fdata-sections -ffunction-sections -Wswitch-enum
-Werror=switch-enum -fPIC)
if(NOT APPLE)
# This causes some versions of clang to crash on macos
add_compile_options(-g -fno-omit-frame-pointer)
endif()
set(full_relro_flags "-pie;LINKER:-z,relro,-z,now,-z,noexecstack")
cmake_push_check_state()
@@ -342,6 +340,11 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND BUILD_TESTING)
add_executable(driver_perf TestDriver.cpp)
target_compile_definitions(driver_perf PRIVATE PERF_TEST=1)
target_link_libraries(driver_perf PRIVATE ${PROJECT_NAME})
# server bench
add_executable(server_bench ServerBench.cpp)
target_link_libraries(server_bench PRIVATE ${PROJECT_NAME})
set_target_properties(server_bench PROPERTIES SKIP_BUILD_RPATH ON)
endif()
# packaging

File diff suppressed because it is too large Load Diff

View File

@@ -273,6 +273,16 @@ template <class T> struct Vector {
size_ += slice.size();
}
// Caller must write to the returned slice
std::span<T> unsafePrepareAppend(int appendSize) {
if (size_ + appendSize > capacity) {
grow(std::max<int>(size_ + appendSize, capacity * 2));
}
auto result = std::span<T>(t + size_, appendSize);
size_ += appendSize;
return result;
}
void push_back(const T &t) { append(std::span<const T>(&t, 1)); }
T *begin() { return t; }

17
Jenkinsfile vendored
View File

@@ -117,15 +117,18 @@ pipeline {
}
}
steps {
script {
filter_args = "-f ConflictSet.cpp -f LongestCommonPrefix.h"
}
CleanBuildAndTest("-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_C_FLAGS=--coverage -DCMAKE_CXX_FLAGS=--coverage -DCMAKE_BUILD_TYPE=Debug -DDISABLE_TSAN=ON")
sh '''
gcovr -f ConflictSet.cpp --cobertura > build/coverage.xml
'''
sh """
gcovr ${filter_args} --cobertura > build/coverage.xml
"""
recordCoverage qualityGates: [[criticality: 'NOTE', metric: 'MODULE']], tools: [[parser: 'COBERTURA', pattern: 'build/coverage.xml']]
sh '''
gcovr -f ConflictSet.cpp
gcovr -f ConflictSet.cpp --fail-under-line 100 > /dev/null
'''
sh """
gcovr ${filter_args}
gcovr ${filter_args} --fail-under-line 100 > /dev/null
"""
}
}
}

185
LongestCommonPrefix.h Normal file
View File

@@ -0,0 +1,185 @@
#pragma once
#include <assert.h>
#include <bit>
#include <stdint.h>
#include <string.h>
#ifdef HAS_AVX
#include <immintrin.h>
#elif HAS_ARM_NEON
#include <arm_neon.h>
#endif
#ifndef __SANITIZE_THREAD__
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
#define __SANITIZE_THREAD__
#endif
#endif
#endif
#if defined(HAS_AVX) || defined(HAS_ARM_NEON)
constexpr int kStride = 64;
#else
constexpr int kStride = 16;
#endif
constexpr int kUnrollFactor = 4;
inline bool compareStride(const uint8_t *ap, const uint8_t *bp) {
#if defined(HAS_ARM_NEON)
static_assert(kStride == 64);
uint8x16_t x[4]; // GCOVR_EXCL_LINE
for (int i = 0; i < 4; ++i) {
x[i] = vceqq_u8(vld1q_u8(ap + i * 16), vld1q_u8(bp + i * 16));
}
auto results = vreinterpretq_u16_u8(
vandq_u8(vandq_u8(x[0], x[1]), vandq_u8(x[2], x[3])));
bool eq = vget_lane_u64(vreinterpret_u64_u8(vshrn_n_u16(results, 4)), 0) ==
uint64_t(-1);
#elif defined(HAS_AVX)
static_assert(kStride == 64);
__m128i x[4]; // GCOVR_EXCL_LINE
for (int i = 0; i < 4; ++i) {
x[i] = _mm_cmpeq_epi8(_mm_loadu_si128((__m128i *)(ap + i * 16)),
_mm_loadu_si128((__m128i *)(bp + i * 16)));
}
auto eq =
_mm_movemask_epi8(_mm_and_si128(_mm_and_si128(x[0], x[1]),
_mm_and_si128(x[2], x[3]))) == 0xffff;
#else
// Hope it gets vectorized
auto eq = memcmp(ap, bp, kStride) == 0;
#endif
return eq;
}
// Precondition: ap[:kStride] != bp[:kStride]
inline int firstNeqStride(const uint8_t *ap, const uint8_t *bp) {
#if defined(HAS_AVX)
static_assert(kStride == 64);
uint64_t c[kStride / 16]; // GCOVR_EXCL_LINE
for (int i = 0; i < kStride; i += 16) {
const auto a = _mm_loadu_si128((__m128i *)(ap + i));
const auto b = _mm_loadu_si128((__m128i *)(bp + i));
const auto compared = _mm_cmpeq_epi8(a, b);
c[i / 16] = _mm_movemask_epi8(compared) & 0xffff;
}
return std::countr_zero(~(c[0] | c[1] << 16 | c[2] << 32 | c[3] << 48));
#elif defined(HAS_ARM_NEON)
static_assert(kStride == 64);
for (int i = 0; i < kStride; i += 16) {
// 0xff for each match
uint16x8_t results =
vreinterpretq_u16_u8(vceqq_u8(vld1q_u8(ap + i), vld1q_u8(bp + i)));
// 0xf for each mismatch
uint64_t bitfield =
~vget_lane_u64(vreinterpret_u64_u8(vshrn_n_u16(results, 4)), 0);
if (bitfield) {
return i + (std::countr_zero(bitfield) >> 2);
}
}
__builtin_unreachable(); // GCOVR_EXCL_LINE
#else
int i = 0;
for (; i < kStride - 1; ++i) {
if (*ap++ != *bp++) {
break;
}
}
return i;
#endif
}
// This gets covered in local development
// GCOVR_EXCL_START
#if defined(HAS_AVX) && !defined(__SANITIZE_THREAD__)
__attribute__((target("avx512f,avx512bw"))) inline int
longestCommonPrefix(const uint8_t *ap, const uint8_t *bp, int cl) {
int i = 0;
int end = cl & ~63;
while (i < end) {
const uint64_t eq =
_mm512_cmpeq_epi8_mask(_mm512_loadu_epi8(ap), _mm512_loadu_epi8(bp));
if (eq != uint64_t(-1)) {
return i + std::countr_one(eq);
}
i += 64;
ap += 64;
bp += 64;
}
if (i < cl) {
const uint64_t mask = (uint64_t(1) << (cl - i)) - 1;
const uint64_t eq = _mm512_cmpeq_epi8_mask(
_mm512_maskz_loadu_epi8(mask, ap), _mm512_maskz_loadu_epi8(mask, bp));
return i + std::countr_one(eq & mask);
}
assert(i == cl);
return i;
}
__attribute__((target("default")))
#endif
// GCOVR_EXCL_STOP
inline int
longestCommonPrefix(const uint8_t *ap, const uint8_t *bp, int cl) {
if (!(cl >= 0)) {
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
int i = 0;
int end;
// kStride * kUnrollCount at a time
end = cl & ~(kStride * kUnrollFactor - 1);
while (i < end) {
for (int j = 0; j < kUnrollFactor; ++j) {
if (!compareStride(ap, bp)) {
return i + firstNeqStride(ap, bp);
}
i += kStride;
ap += kStride;
bp += kStride;
}
}
// kStride at a time
end = cl & ~(kStride - 1);
while (i < end) {
if (!compareStride(ap, bp)) {
return i + firstNeqStride(ap, bp);
}
i += kStride;
ap += kStride;
bp += kStride;
}
// word at a time
end = cl & ~(sizeof(uint64_t) - 1);
while (i < end) {
uint64_t a; // GCOVR_EXCL_LINE
uint64_t b; // GCOVR_EXCL_LINE
memcpy(&a, ap, 8);
memcpy(&b, bp, 8);
const auto mismatched = a ^ b;
if (mismatched) {
return i + std::countr_zero(mismatched) / 8;
}
i += 8;
ap += 8;
bp += 8;
}
// byte at a time
while (i < cl) {
if (*ap != *bp) {
break;
}
++ap;
++bp;
++i;
}
return i;
}

View File

@@ -24,15 +24,16 @@ Hardware for all benchmarks is an AMD Ryzen 9 7900 with (2x32GB) 5600MT/s CL28-3
| ns/op | op/s | err% | ins/op | cyc/op | IPC | bra/op | miss% | total | benchmark
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
| 17.03 | 58,732,967.93 | 0.6% | 276.28 | 87.96 | 3.141 | 52.15 | 0.4% | 0.01 | `point reads`
| 19.52 | 51,239,158.04 | 0.3% | 367.16 | 101.50 | 3.617 | 61.92 | 0.3% | 0.01 | `prefix reads`
| 47.74 | 20,947,676.63 | 0.5% | 998.16 | 247.43 | 4.034 | 161.64 | 0.2% | 0.01 | `range reads`
| 23.14 | 43,207,824.89 | 0.4% | 408.18 | 121.64 | 3.356 | 70.20 | 0.3% | 0.01 | `point writes`
| 38.02 | 26,302,115.66 | 0.1% | 709.72 | 199.70 | 3.554 | 134.26 | 0.3% | 0.01 | `prefix writes`
| 44.28 | 22,583,559.17 | 0.9% | 825.19 | 233.10 | 3.540 | 141.48 | 0.2% | 0.01 | `range writes`
| 85.50 | 11,695,990.63 | 0.5% | 1,488.16 | 455.68 | 3.266 | 289.22 | 0.1% | 0.01 | `monotonic increasing point writes`
| 338,388.50 | 2,955.18 | 3.3% | 4,097,087.00 | 1,809,996.00 | 2.264 | 759,645.00 | 0.0% | 0.01 | `worst case for radix tree`
| 84.84 | 11,787,313.59 | 1.4% | 1,716.02 | 440.50 | 3.896 | 271.00 | 0.0% | 0.01 | `create and destroy`
| 10.80 | 92,600,541.52 | 0.6% | 180.38 | 54.49 | 3.310 | 41.51 | 0.4% | 0.01 | `point reads`
| 15.00 | 66,687,691.68 | 0.4% | 278.44 | 76.44 | 3.642 | 55.56 | 0.3% | 0.01 | `prefix reads`
| 36.81 | 27,163,394.61 | 0.4% | 795.06 | 187.91 | 4.231 | 142.67 | 0.2% | 0.01 | `range reads`
| 18.14 | 55,137,674.01 | 1.2% | 338.19 | 92.86 | 3.642 | 42.81 | 0.4% | 0.01 | `point writes`
| 33.19 | 30,127,119.71 | 0.1% | 681.03 | 170.05 | 4.005 | 98.68 | 0.2% | 0.01 | `prefix writes`
| 37.37 | 26,759,432.70 | 1.9% | 779.70 | 195.45 | 3.989 | 114.21 | 0.0% | 0.01 | `range writes`
| 74.36 | 13,448,582.47 | 1.9% | 1,425.68 | 389.08 | 3.664 | 258.88 | 0.1% | 0.01 | `monotonic increasing point writes`
| 316,928.00 | 3,155.29 | 1.5% | 3,992,986.00 | 1,699,813.00 | 2.349 | 806,226.50 | 0.0% | 0.01 | `worst case for radix tree`
| 75.26 | 13,286,517.16 | 0.5% | 1,590.01 | 386.67 | 4.112 | 258.00 | 0.0% | 0.01 | `create and destroy`
# "Real data" test
@@ -47,7 +48,7 @@ Check: 4.47891 seconds, 364.05 MB/s, Add: 4.55599 seconds, 123.058 MB/s, Gc rati
## radix tree
```
Check: 1.05813 seconds, 1540.97 MB/s, Add: 1.32071 seconds, 424.508 MB/s, Gc ratio: 42.2067%
Check: 0.910234 seconds, 1791.35 MB/s, Add: 1.25908 seconds, 445.287 MB/s, Gc ratio: 44.0415%
```
## hash table

310
ServerBench.cpp Normal file
View File

@@ -0,0 +1,310 @@
#include <atomic>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <string_view>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <thread>
#include <unistd.h>
#include "ConflictSet.h"
#include "third_party/nadeau.h"
std::atomic<int64_t> transactions;
constexpr int kBaseSearchDepth = 32;
constexpr int kWindowSize = 10000000;
std::basic_string<uint8_t> numToKey(int64_t num) {
std::basic_string<uint8_t> result;
result.resize(kBaseSearchDepth + sizeof(int64_t));
memset(result.data(), 0, kBaseSearchDepth);
int64_t be = __builtin_bswap64(num);
memcpy(result.data() + kBaseSearchDepth, &be, sizeof(int64_t));
return result;
}
void workload(weaselab::ConflictSet *cs) {
int64_t version = kWindowSize;
cs->addWrites(nullptr, 0, version);
for (;; transactions.fetch_add(1, std::memory_order_relaxed)) {
// Reads
{
auto beginK = numToKey(version - kWindowSize);
auto endK = numToKey(version - 1);
auto pointRv = version - kWindowSize + rand() % kWindowSize + 1;
auto pointK = numToKey(pointRv);
weaselab::ConflictSet::ReadRange reads[] = {
{
{pointK.data(), int(pointK.size())},
{nullptr, 0},
pointRv,
},
{
{beginK.data(), int(beginK.size())},
{endK.data(), int(endK.size())},
version - 2,
},
};
weaselab::ConflictSet::Result result[sizeof(reads) / sizeof(reads[0])];
cs->check(reads, result, sizeof(reads) / sizeof(reads[0]));
// for (int i = 0; i < sizeof(reads) / sizeof(reads[0]); ++i) {
// if (result[i] != weaselab::ConflictSet::Commit) {
// fprintf(stderr, "Unexpected conflict: [%s, %s) @ %" PRId64 "\n",
// printable(reads[i].begin).c_str(),
// printable(reads[i].end).c_str(), reads[i].readVersion);
// abort();
// }
// }
}
// Writes
{
weaselab::ConflictSet::WriteRange w;
auto k = numToKey(version);
w.begin.p = k.data();
w.end.len = 0;
if (version % (kWindowSize / 2) == 0) {
for (int l = 0; l <= k.size(); ++l) {
w.begin.len = l;
cs->addWrites(&w, 1, version);
}
} else {
w.begin.len = k.size();
cs->addWrites(&w, 1, version);
int64_t beginN = version - kWindowSize + rand() % kWindowSize;
auto b = numToKey(beginN);
auto e = numToKey(beginN + 1000);
w.begin.p = b.data();
w.begin.len = b.size();
w.end.p = e.data();
w.end.len = e.size();
cs->addWrites(&w, 1, version);
}
}
// GC
cs->setOldestVersion(version - kWindowSize);
++version;
}
}
// Adapted from getaddrinfo man page
int getListenFd(const char *node, const char *service) {
struct addrinfo hints;
struct addrinfo *result, *rp;
int sfd, s;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* stream socket */
hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = nullptr;
hints.ai_addr = nullptr;
hints.ai_next = nullptr;
s = getaddrinfo(node, service, &hints, &result);
if (s != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
abort();
}
/* getaddrinfo() returns a list of address structures.
Try each address until we successfully bind(2).
If socket(2) (or bind(2)) fails, we (close the socket
and) try the next address. */
for (rp = result; rp != nullptr; rp = rp->ai_next) {
sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
if (sfd == -1) {
continue;
}
int val = 1;
setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) {
break; /* Success */
}
close(sfd);
}
freeaddrinfo(result); /* No longer needed */
if (rp == nullptr) { /* No address succeeded */
fprintf(stderr, "Could not bind\n");
abort();
}
int rv = listen(sfd, SOMAXCONN);
if (rv) {
perror("listen()");
abort();
}
return sfd;
}
// HTTP response
//
std::string_view part1 =
"HTTP/1.1 200 OK \r\nContent-type: text/plain; version=0.0.4; "
"charset=utf-8; escaping=values\r\nContent-Length: ";
// Decimal content length
std::string_view part2 = "\r\n\r\n";
// Body
double toSeconds(timeval t) {
return double(t.tv_sec) + double(t.tv_usec) * 1e-6;
}
#include <linux/perf_event.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef __linux__
struct PerfCounter {
explicit PerfCounter(int event) {
struct perf_event_attr pe;
memset(&pe, 0, sizeof(pe));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(pe);
pe.config = event;
pe.inherit = 1;
pe.exclude_kernel = 1;
pe.exclude_hv = 1;
fd = perf_event_open(&pe, 0, -1, -1, 0);
if (fd == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
}
int64_t total() {
int64_t count;
if (read(fd, &count, sizeof(count)) != sizeof(count)) {
perror("read instructions from perf");
abort();
}
return count;
}
~PerfCounter() { close(fd); }
private:
int fd;
static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags) {
int ret;
ret = syscall(SYS_perf_event_open, hw_event, pid, cpu, group_fd, flags);
return ret;
}
};
#else
struct PerfCounter {
explicit PerPerfCounter(int) {}
int64_t total() { return 0; }
};
#endif
int main(int argc, char **argv) {
if (argc != 3) {
goto fail;
}
{
int listenFd = getListenFd(argv[1], argv[2]);
weaselab::ConflictSet cs{0};
weaselab::ConflictSet::MetricsV1 *metrics;
int metricsCount;
cs.getMetricsV1(&metrics, &metricsCount);
PerfCounter instructions{PERF_COUNT_HW_INSTRUCTIONS};
PerfCounter cycles{PERF_COUNT_HW_CPU_CYCLES};
auto w = std::thread{workload, &cs};
for (;;) {
struct sockaddr_storage peer_addr = {};
socklen_t peer_addr_len = sizeof(peer_addr);
const int connfd =
accept(listenFd, (struct sockaddr *)&peer_addr, &peer_addr_len);
std::string body;
rusage r;
getrusage(RUSAGE_SELF, &r);
body += "# HELP process_cpu_seconds_total Total user and system CPU time "
"spent in seconds.\n# TYPE process_cpu_seconds_total counter\n"
"process_cpu_seconds_total ";
body += std::to_string(toSeconds(r.ru_utime) + toSeconds(r.ru_stime));
body += "\n";
body += "# HELP process_resident_memory_bytes Resident memory size in "
"bytes.\n# TYPE process_resident_memory_bytes gauge\n"
"process_resident_memory_bytes ";
body += std::to_string(getCurrentRSS());
body += "\n";
body += "# HELP transactions_total Total number of transactions\n"
"# TYPE transactions_total counter\n"
"transactions_total ";
body += std::to_string(transactions.load(std::memory_order_relaxed));
body += "\n";
body += "# HELP instructions_total Total number of instructions\n"
"# TYPE instructions_total counter\n"
"instructions_total ";
body += std::to_string(instructions.total());
body += "\n";
body += "# HELP cycles_total Total number of cycles\n"
"# TYPE cycles_total counter\n"
"cycles_total ";
body += std::to_string(cycles.total());
body += "\n";
for (int i = 0; i < metricsCount; ++i) {
body += "# HELP ";
body += metrics[i].name;
body += " ";
body += metrics[i].help;
body += "\n";
body += "# TYPE ";
body += metrics[i].name;
body += " ";
body += metrics[i].type == metrics[i].Counter ? "counter" : "gauge";
body += "\n";
body += metrics[i].name;
body += " ";
body += std::to_string(metrics[i].getValue());
body += "\n";
}
auto len = std::to_string(body.size());
iovec iov[] = {
{(void *)part1.data(), part1.size()},
{(void *)len.data(), len.size()},
{(void *)part2.data(), part2.size()},
{(void *)body.data(), body.size()},
};
int written;
do {
written = writev(connfd, iov, sizeof(iov) / sizeof(iov[0]));
} while (written < 0 && errno == EINTR);
close(connfd);
}
}
fail:
fprintf(stderr, "Expected ./%s <host> <port>\n", argv[0]);
return 1;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +0,0 @@
<EFBFBD><EFBFBD>
2

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1 +0,0 @@
<EFBFBD>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More