Compare commits
51 Commits
interleave
...
ceecc62a63
Author | SHA1 | Date | |
---|---|---|---|
ceecc62a63 | |||
80f0697e79 | |||
ce23d3995c | |||
6f899e063b | |||
e5b9c03e77 | |||
a158d375f5 | |||
ee5a84cd7b | |||
33f14e3d9b | |||
77262ee2d3 | |||
9945998e05 | |||
2777e016ff | |||
661ffcd843 | |||
3a34d3cecb | |||
189c73e3bd | |||
35987030fc | |||
0621741ec3 | |||
f5ec9f726a | |||
552fc11c5d | |||
71ace9cc55 | |||
bcf459304f | |||
f403c78410 | |||
08958d4109 | |||
dcc5275ec9 | |||
c5ef843f9e | |||
b78e817e24 | |||
9c82f17e20 | |||
665a9313a4 | |||
6e66202d5e | |||
a92271a205 | |||
0dbfb4deae | |||
6e229b6b36 | |||
2200de11c8 | |||
b37feb58dd | |||
94a4802824 | |||
707dbdb391 | |||
bdd343bb57 | |||
7b31bd5efe | |||
e255e1a926 | |||
f85b92f8db | |||
3c44614311 | |||
9c1ac3702e | |||
224d21648a | |||
33f9c89328 | |||
12c2d5eb95 | |||
db357e747d | |||
4494359ca2 | |||
f079d84bda | |||
724ec09248 | |||
4eaad39294 | |||
891100e649 | |||
22e55309be |
@@ -57,6 +57,7 @@ ConflictSet::ReadRange prefixRange(Arena &arena, TrivialSpan key) {
|
||||
|
||||
void benchConflictSet() {
|
||||
ankerl::nanobench::Bench bench;
|
||||
bench.minEpochIterations(10000);
|
||||
ConflictSet cs{0};
|
||||
|
||||
bench.batch(kOpsPerTx);
|
||||
|
@@ -31,11 +31,24 @@ 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)
|
||||
add_compile_options(
|
||||
-Werror=switch-enum
|
||||
-Wswitch-enum
|
||||
-Wunused-variable
|
||||
-fPIC
|
||||
-fdata-sections
|
||||
-ffunction-sections
|
||||
-fno-jump-tables # https://github.com/llvm/llvm-project/issues/54247
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
add_link_options("-Wno-unused-command-line-argument")
|
||||
find_program(LLVM_OBJCOPY llvm-objcopy)
|
||||
if(LLVM_OBJCOPY)
|
||||
set(CMAKE_OBJCOPY
|
||||
${LLVM_OBJCOPY}
|
||||
CACHE FILEPATH "path to objcopy binary" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
@@ -56,6 +69,22 @@ if(HAS_FULL_RELRO)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL
|
||||
arm64)
|
||||
add_compile_options(-mbranch-protection=standard)
|
||||
else()
|
||||
add_compile_options(-fcf-protection)
|
||||
set(rewrite_endbr_flags "-fuse-ld=mold;LINKER:-z,rewrite-endbr")
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${rewrite_endbr_flags})
|
||||
check_cxx_source_compiles("int main(){}" HAS_REWRITE_ENDBR FAIL_REGEX
|
||||
"warning:")
|
||||
if(HAS_REWRITE_ENDBR)
|
||||
add_link_options(${rewrite_endbr_flags})
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
|
||||
set(version_script_flags
|
||||
LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/linker.map)
|
||||
cmake_push_check_state()
|
||||
@@ -81,19 +110,11 @@ else()
|
||||
add_link_options(-Wl,--gc-sections)
|
||||
endif()
|
||||
|
||||
if(NOT USE_SIMD_FALLBACK)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS -mavx)
|
||||
check_include_file_cxx("immintrin.h" HAS_AVX)
|
||||
if(HAS_AVX)
|
||||
if(USE_SIMD_FALLBACK)
|
||||
add_compile_definitions(USE_SIMD_FALLBACK)
|
||||
else()
|
||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64)
|
||||
add_compile_options(-mavx)
|
||||
add_compile_definitions(HAS_AVX)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
|
||||
check_include_file_cxx("arm_neon.h" HAS_ARM_NEON)
|
||||
if(HAS_ARM_NEON)
|
||||
add_compile_definitions(HAS_ARM_NEON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -356,6 +377,15 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND BUILD_TESTING)
|
||||
${symbol_imports})
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
find_program(HARDENING_CHECK hardening-check)
|
||||
if(HARDENING_CHECK)
|
||||
add_test(NAME hardening_check
|
||||
COMMAND ${HARDENING_CHECK} $<TARGET_FILE:${PROJECT_NAME}>
|
||||
--nofortify --nostackprotector)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# bench
|
||||
add_executable(conflict_set_bench Bench.cpp)
|
||||
target_link_libraries(conflict_set_bench PRIVATE ${PROJECT_NAME} nanobench)
|
||||
|
762
ConflictSet.cpp
762
ConflictSet.cpp
File diff suppressed because it is too large
Load Diff
@@ -13,12 +13,14 @@ RUN TZ=America/Los_Angeles DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
ccache \
|
||||
cmake \
|
||||
curl \
|
||||
devscripts \
|
||||
g++-aarch64-linux-gnu \
|
||||
gcovr \
|
||||
git \
|
||||
gnupg \
|
||||
libc6-dbg \
|
||||
lsb-release \
|
||||
mold \
|
||||
ninja-build \
|
||||
pre-commit \
|
||||
python3-requests \
|
||||
|
18
Internal.h
18
Internal.h
@@ -18,7 +18,6 @@ using namespace weaselab;
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
#include <callgrind.h>
|
||||
@@ -368,23 +367,6 @@ template <class T, class C = std::less<T>> auto set(Arena &arena) {
|
||||
return Set<T, C>(ArenaAlloc<T>(&arena));
|
||||
}
|
||||
|
||||
template <class T> struct MyHash;
|
||||
|
||||
template <class T> struct MyHash<T *> {
|
||||
size_t operator()(const T *t) const noexcept {
|
||||
size_t result;
|
||||
memcpy(&result, &t, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
using HashSet =
|
||||
std::unordered_set<T, MyHash<T>, std::equal_to<T>, ArenaAlloc<T>>;
|
||||
template <class T> auto hashSet(Arena &arena) {
|
||||
return HashSet<T>(ArenaAlloc<T>(&arena));
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
bool operator==(const ArenaAlloc<T> &lhs, const ArenaAlloc<U> &rhs) {
|
||||
return lhs.arena == rhs.arena;
|
||||
|
8
Jenkinsfile
vendored
8
Jenkinsfile
vendored
@@ -11,11 +11,11 @@ def CleanBuildAndTest(String cmakeArgs) {
|
||||
catchError {
|
||||
sh '''
|
||||
cd build
|
||||
ctest --no-compress-output --test-output-size-passed 100000 --test-output-size-failed 100000 -T Test -j `nproc` --timeout 90
|
||||
ctest --no-compress-output --test-output-size-passed 100000 --test-output-size-failed 100000 -T Test -j `nproc` --timeout 90 > /dev/null
|
||||
zstd Testing/*/Test.xml
|
||||
'''
|
||||
}
|
||||
xunit tools: [CTest(pattern: 'build/Testing/*/Test.xml')], reduceLog: false, skipPublishingChecks: false
|
||||
xunit tools: [CTest(pattern: 'build/Testing/*/Test.xml')], skipPublishingChecks: false
|
||||
minio bucket: 'jenkins', credentialsId: 'jenkins-minio', excludes: '', host: 'minio.weaselab.dev', includes: 'build/Testing/*/Test.xml.zst', targetFolder: '${JOB_NAME}/${BUILD_NUMBER}/${STAGE_NAME}/'
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ pipeline {
|
||||
minio bucket: 'jenkins', credentialsId: 'jenkins-minio', excludes: '', host: 'minio.weaselab.dev', includes: 'build/*.deb,build/*.rpm,paper/*.pdf', targetFolder: '${JOB_NAME}/${BUILD_NUMBER}/${STAGE_NAME}/'
|
||||
}
|
||||
}
|
||||
stage('Release [gcc]') {
|
||||
stage('gcc') {
|
||||
agent {
|
||||
dockerfile {
|
||||
args '-v /home/jenkins/ccache:/ccache'
|
||||
@@ -99,7 +99,7 @@ pipeline {
|
||||
}
|
||||
}
|
||||
steps {
|
||||
CleanBuildAndTest("-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS=-DNVALGRIND")
|
||||
CleanBuildAndTest("-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++")
|
||||
recordIssues(tools: [gcc()])
|
||||
}
|
||||
}
|
||||
|
57
README.md
57
README.md
@@ -2,7 +2,16 @@ A data structure for optimistic concurrency control on ranges of bitwise-lexicog
|
||||
|
||||
Intended as an alternative to FoundationDB's skip list.
|
||||
|
||||
Hardware for all benchmarks is an AMD Ryzen 9 7900 with (2x32GB) 5600MT/s CL28-34-34-89 1.35V RAM
|
||||
Hardware for all benchmarks is an AMD Ryzen 9 7900 with (2x32GB) 5600MT/s CL28-34-34-89 1.35V RAM.
|
||||
|
||||
```
|
||||
$ clang++ --version
|
||||
|
||||
Ubuntu clang version 20.0.0 (++20241119082716+7e85cb8a8a9d-1~exp1~20241119082825.551)
|
||||
Target: x86_64-pc-linux-gnu
|
||||
Thread model: posix
|
||||
InstalledDir: /usr/lib/llvm-20/bin
|
||||
```
|
||||
|
||||
# Microbenchmark
|
||||
|
||||
@@ -10,44 +19,45 @@ 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
|
||||
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|
||||
| 172.03 | 5,812,791.77 | 0.4% | 3,130.62 | 879.00 | 3.562 | 509.23 | 0.0% | 0.01 | `point reads`
|
||||
| 167.44 | 5,972,130.71 | 0.2% | 3,065.14 | 862.27 | 3.555 | 494.30 | 0.0% | 0.01 | `prefix reads`
|
||||
| 238.77 | 4,188,130.84 | 0.9% | 3,589.93 | 1,259.30 | 2.851 | 637.12 | 0.0% | 0.01 | `range reads`
|
||||
| 424.01 | 2,358,426.70 | 0.2% | 5,620.05 | 2,242.35 | 2.506 | 854.80 | 1.7% | 0.01 | `point writes`
|
||||
| 418.45 | 2,389,780.56 | 0.4% | 5,525.07 | 2,211.05 | 2.499 | 831.71 | 1.7% | 0.01 | `prefix writes`
|
||||
| 254.87 | 3,923,568.88 | 2.6% | 3,187.01 | 1,366.50 | 2.332 | 529.11 | 2.7% | 0.02 | `range writes`
|
||||
| 675.96 | 1,479,374.50 | 3.3% | 7,735.41 | 3,468.60 | 2.230 | 1,386.02 | 1.8% | 0.01 | `monotonic increasing point writes`
|
||||
| 137,986.20 | 7,247.10 | 0.6% | 789,752.33 | 699,462.00 | 1.129 | 144,824.14 | 0.0% | 0.01 | `worst case for radix tree`
|
||||
| 21.63 | 46,231,564.03 | 1.0% | 448.00 | 107.14 | 4.181 | 84.00 | 0.0% | 0.01 | `create and destroy`
|
||||
| 169.16 | 5,911,582.44 | 0.0% | 3,014.03 | 855.12 | 3.525 | 504.59 | 0.0% | 2.02 | `point reads`
|
||||
| 167.17 | 5,981,796.19 | 0.0% | 2,954.16 | 845.14 | 3.495 | 490.17 | 0.0% | 2.00 | `prefix reads`
|
||||
| 250.44 | 3,992,954.35 | 0.1% | 3,592.41 | 1,265.18 | 2.839 | 629.31 | 0.0% | 2.99 | `range reads`
|
||||
| 467.10 | 2,140,846.36 | 0.0% | 4,450.57 | 2,488.36 | 1.789 | 707.92 | 2.1% | 5.62 | `point writes`
|
||||
| 465.18 | 2,149,723.11 | 0.2% | 4,410.22 | 2,474.92 | 1.782 | 694.74 | 2.1% | 5.55 | `prefix writes`
|
||||
| 297.45 | 3,361,954.05 | 0.1% | 2,315.38 | 1,581.64 | 1.464 | 396.69 | 3.3% | 3.57 | `range writes`
|
||||
| 476.56 | 2,098,370.82 | 1.0% | 6,999.33 | 2,492.26 | 2.808 | 1,251.74 | 1.3% | 0.06 | `monotonic increasing point writes`
|
||||
| 129,455.00 | 7,724.69 | 1.0% | 807,446.67 | 698,559.40 | 1.156 | 144,584.60 | 0.8% | 0.01 | `worst case for radix tree`
|
||||
| 44.67 | 22,384,996.63 | 0.5% | 902.00 | 235.18 | 3.835 | 132.00 | 0.0% | 0.01 | `create and destroy`
|
||||
|
||||
## Radix tree (this implementation)
|
||||
|
||||
|
||||
| ns/op | op/s | err% | ins/op | cyc/op | IPC | bra/op | miss% | total | benchmark
|
||||
|--------------------:|--------------------:|--------:|----------------:|----------------:|-------:|---------------:|--------:|----------:|:----------
|
||||
| 12.88 | 77,653,350.77 | 0.5% | 185.37 | 64.45 | 2.876 | 41.51 | 0.4% | 0.01 | `point reads`
|
||||
| 14.67 | 68,179,354.49 | 0.1% | 271.44 | 73.40 | 3.698 | 53.70 | 0.3% | 0.01 | `prefix reads`
|
||||
| 34.84 | 28,701,444.36 | 0.3% | 715.74 | 175.27 | 4.084 | 127.30 | 0.2% | 0.01 | `range reads`
|
||||
| 17.12 | 58,422,988.28 | 0.2% | 314.30 | 86.11 | 3.650 | 39.82 | 0.4% | 0.01 | `point writes`
|
||||
| 31.42 | 31,830,804.65 | 0.1% | 591.06 | 158.07 | 3.739 | 82.67 | 0.2% | 0.01 | `prefix writes`
|
||||
| 37.37 | 26,759,432.70 | 2.2% | 681.98 | 188.95 | 3.609 | 96.10 | 0.1% | 0.01 | `range writes`
|
||||
| 76.72 | 13,035,140.63 | 2.3% | 1,421.28 | 387.17 | 3.671 | 257.76 | 0.1% | 0.01 | `monotonic increasing point writes`
|
||||
| 297,452.00 | 3,361.89 | 0.9% | 3,508,083.00 | 1,500,834.67 | 2.337 | 727,525.33 | 0.1% | 0.01 | `worst case for radix tree`
|
||||
| 87.70 | 11,402,490.60 | 1.0% | 1,795.00 | 442.09 | 4.060 | 297.00 | 0.0% | 0.01 | `create and destroy`
|
||||
| 14.11 | 70,857,435.19 | 0.1% | 247.13 | 71.03 | 3.479 | 32.64 | 0.8% | 0.17 | `point reads`
|
||||
| 15.63 | 63,997,306.79 | 0.0% | 299.99 | 78.59 | 3.817 | 42.50 | 0.4% | 0.19 | `prefix reads`
|
||||
| 36.24 | 27,590,266.59 | 0.1% | 782.70 | 182.21 | 4.296 | 106.65 | 0.2% | 0.43 | `range reads`
|
||||
| 22.72 | 44,004,627.40 | 0.1% | 376.04 | 114.33 | 3.289 | 49.97 | 0.8% | 0.27 | `point writes`
|
||||
| 40.83 | 24,494,110.04 | 0.0% | 666.07 | 205.35 | 3.244 | 101.33 | 0.3% | 0.49 | `prefix writes`
|
||||
| 43.45 | 23,016,324.00 | 0.0% | 732.33 | 218.41 | 3.353 | 111.64 | 0.1% | 0.53 | `range writes`
|
||||
| 81.46 | 12,276,650.63 | 3.6% | 1,458.85 | 411.52 | 3.545 | 280.42 | 0.1% | 0.01 | `monotonic increasing point writes`
|
||||
| 314,217.00 | 3,182.51 | 1.2% | 4,043,063.50 | 1,593,715.00 | 2.537 | 714,828.00 | 0.1% | 0.01 | `worst case for radix tree`
|
||||
| 106.79 | 9,364,602.60 | 0.5% | 2,046.00 | 539.75 | 3.791 | 329.00 | 0.0% | 0.01 | `create and destroy`
|
||||
|
||||
# "Real data" test
|
||||
|
||||
Point queries only, best of three runs. Gc ratio is the ratio of time spent doing garbage collection to time spent adding writes or doing garbage collection. Lower is better.
|
||||
Point queries only. Gc ratio is the ratio of time spent doing garbage collection to time spent adding writes or doing garbage collection. Lower is better.
|
||||
|
||||
## skip list
|
||||
|
||||
```
|
||||
Check: 4.47891 seconds, 364.05 MB/s, Add: 4.55599 seconds, 123.058 MB/s, Gc ratio: 37.1145%
|
||||
Check: 4.62434 seconds, 364.633 MB/s, Add: 3.90399 seconds, 147.371 MB/s, Gc ratio: 33.6898%, Peak idle memory: 5.61007e+06
|
||||
```
|
||||
|
||||
## radix tree
|
||||
|
||||
```
|
||||
Check: 0.953012 seconds, 1710.94 MB/s, Add: 1.30025 seconds, 431.188 MB/s, Gc ratio: 43.9816%, Peak idle memory: 2.28375e+06
|
||||
Check: 0.956689 seconds, 1762.52 MB/s, Add: 1.35744 seconds, 423.84 MB/s, Gc ratio: 35.0946%, Peak idle memory: 2.32922e+06
|
||||
```
|
||||
|
||||
## hash table
|
||||
@@ -55,5 +65,6 @@ Check: 0.953012 seconds, 1710.94 MB/s, Add: 1.30025 seconds, 431.188 MB/s, Gc ra
|
||||
(The hash table implementation doesn't work on range queries, and its purpose is to provide an idea of how fast point queries can be)
|
||||
|
||||
```
|
||||
Check: 0.804094 seconds, 2027.81 MB/s, Add: 0.652952 seconds, 858.645 MB/s, Gc ratio: 35.3885%
|
||||
Check: 0.799863 seconds, 2108.09 MB/s, Add: 0.667736 seconds, 861.621 MB/s, Gc ratio: 35.0666%, Peak idle memory: 0
|
||||
```
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
#include <string_view>
|
||||
#include <span>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
@@ -64,7 +64,7 @@ int main(int argc, const char **argv) {
|
||||
auto *const mapOriginal = begin;
|
||||
const auto sizeOriginal = size;
|
||||
|
||||
using StringView = std::basic_string_view<uint8_t>;
|
||||
using StringView = std::span<const uint8_t>;
|
||||
|
||||
StringView write;
|
||||
std::vector<StringView> reads;
|
||||
@@ -78,9 +78,9 @@ int main(int argc, const char **argv) {
|
||||
end = (uint8_t *)memchr(begin, '\n', size);
|
||||
|
||||
if (line.size() > 0 && line[0] == 'P') {
|
||||
write = line.substr(2, line.size());
|
||||
write = line.subspan(2, line.size());
|
||||
} else if (line.size() > 0 && line[0] == 'L') {
|
||||
reads.push_back(line.substr(2, line.size()));
|
||||
reads.push_back(line.subspan(2, line.size()));
|
||||
} else if (line.empty()) {
|
||||
{
|
||||
readRanges.resize(reads.size());
|
||||
@@ -133,10 +133,10 @@ int main(int argc, const char **argv) {
|
||||
int metricsCount;
|
||||
cs.getMetricsV1(&metrics, &metricsCount);
|
||||
for (int i = 0; i < metricsCount; ++i) {
|
||||
printf("# HELP %s %s\n", metrics[i].name, metrics[i].help);
|
||||
printf("# TYPE %s %s\n", metrics[i].name,
|
||||
metrics[i].type == metrics[i].Counter ? "counter" : "gauge");
|
||||
printf("%s %g\n", metrics[i].name, metrics[i].getValue());
|
||||
fprintf(stderr, "# HELP %s %s\n", metrics[i].name, metrics[i].help);
|
||||
fprintf(stderr, "# TYPE %s %s\n", metrics[i].name,
|
||||
metrics[i].type == metrics[i].Counter ? "counter" : "gauge");
|
||||
fprintf(stderr, "%s %g\n", metrics[i].name, metrics[i].getValue());
|
||||
}
|
||||
|
||||
printf("Check: %g seconds, %g MB/s, Add: %g seconds, %g MB/s, Gc ratio: "
|
||||
|
230
ServerBench.cpp
230
ServerBench.cpp
@@ -1,3 +1,4 @@
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
@@ -19,41 +20,210 @@
|
||||
#include <vector>
|
||||
|
||||
#include "ConflictSet.h"
|
||||
#include "Internal.h"
|
||||
#include "third_party/nadeau.h"
|
||||
|
||||
constexpr int kCacheLine = 64; // TODO mac m1 is 128
|
||||
|
||||
template <class T> struct TxQueue {
|
||||
|
||||
explicit TxQueue(int lgSlotCount)
|
||||
: slotCount(1 << lgSlotCount), slotCountMask(slotCount - 1),
|
||||
slots(new T[slotCount]) {
|
||||
// Otherwise we can't tell the difference between full and empty.
|
||||
assert(!(slotCountMask & 0x80000000));
|
||||
}
|
||||
|
||||
/// Call from producer thread, after ensuring consumer is no longer accessing
|
||||
/// it somehow
|
||||
~TxQueue() { delete[] slots; }
|
||||
|
||||
/// Must be called from the producer thread
|
||||
void push(T t) {
|
||||
if (wouldBlock()) {
|
||||
// Wait for pops to change and try again
|
||||
consumer.pops.wait(producer.lastPopRead, std::memory_order_relaxed);
|
||||
producer.lastPopRead = consumer.pops.load(std::memory_order_acquire);
|
||||
}
|
||||
slots[producer.pushesNonAtomic++ & slotCountMask] = std::move(t);
|
||||
// seq_cst so that the notify can't be ordered before the store
|
||||
producer.pushes.store(producer.pushesNonAtomic, std::memory_order_seq_cst);
|
||||
// We have to notify every time, since we don't know if this is the last
|
||||
// push ever
|
||||
producer.pushes.notify_one();
|
||||
}
|
||||
|
||||
/// Must be called from the producer thread
|
||||
uint32_t outstanding() {
|
||||
return producer.pushesNonAtomic -
|
||||
consumer.pops.load(std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
/// Returns true if a call to push might block. Must be called from the
|
||||
/// producer thread.
|
||||
bool wouldBlock() {
|
||||
// See if we can determine that overflow won't happen entirely from state
|
||||
// local to the producer
|
||||
if (producer.pushesNonAtomic - producer.lastPopRead == slotCount - 1) {
|
||||
// Re-read pops with memory order
|
||||
producer.lastPopRead = consumer.pops.load(std::memory_order_acquire);
|
||||
return producer.pushesNonAtomic - producer.lastPopRead == slotCount - 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Valid until the next pop, or until this queue is destroyed.
|
||||
T *pop() {
|
||||
// See if we can determine that there's an entry we can pop entirely from
|
||||
// state local to the consumer
|
||||
if (consumer.lastPushRead - consumer.popsNonAtomic == 0) {
|
||||
// Re-read pushes with memory order and try again
|
||||
consumer.lastPushRead = producer.pushes.load(std::memory_order_acquire);
|
||||
if (consumer.lastPushRead - consumer.popsNonAtomic == 0) {
|
||||
// Wait for pushes to change and try again
|
||||
producer.pushes.wait(consumer.lastPushRead, std::memory_order_relaxed);
|
||||
consumer.lastPushRead = producer.pushes.load(std::memory_order_acquire);
|
||||
}
|
||||
}
|
||||
auto result = &slots[consumer.popsNonAtomic++ & slotCountMask];
|
||||
// We only have to write pops with memory order if we've run out of items.
|
||||
// We know that we'll eventually run out.
|
||||
if (consumer.lastPushRead - consumer.popsNonAtomic == 0) {
|
||||
// seq_cst so that the notify can't be ordered before the store
|
||||
consumer.pops.store(consumer.popsNonAtomic, std::memory_order_seq_cst);
|
||||
consumer.pops.notify_one();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint32_t slotCount;
|
||||
const uint32_t slotCountMask;
|
||||
T *slots;
|
||||
struct alignas(kCacheLine) ProducerState {
|
||||
std::atomic<uint32_t> pushes{0};
|
||||
uint32_t pushesNonAtomic{0};
|
||||
uint32_t lastPopRead{0};
|
||||
};
|
||||
struct alignas(kCacheLine) ConsumerState {
|
||||
std::atomic<uint32_t> pops{0};
|
||||
uint32_t popsNonAtomic{0};
|
||||
uint32_t lastPushRead{0};
|
||||
};
|
||||
ProducerState producer;
|
||||
ConsumerState consumer;
|
||||
};
|
||||
|
||||
std::atomic<int64_t> transactions;
|
||||
|
||||
constexpr int kWindowSize = 10000000;
|
||||
int64_t safeUnaryMinus(int64_t x) {
|
||||
return x == std::numeric_limits<int64_t>::min() ? x : -x;
|
||||
}
|
||||
|
||||
constexpr int kNumPrefixes = 250000;
|
||||
void tupleAppend(std::string &output, int64_t value) {
|
||||
if (value == 0) {
|
||||
output.push_back(0x14);
|
||||
return;
|
||||
}
|
||||
uint32_t size = 8 - __builtin_clrsbll(value) / 8;
|
||||
int typeCode = 0x14 + (value < 0 ? -1 : 1) * size;
|
||||
output.push_back(typeCode);
|
||||
if (value < 0) {
|
||||
value = ~safeUnaryMinus(value);
|
||||
}
|
||||
uint64_t swap = __builtin_bswap64(value);
|
||||
output.insert(output.end(), (uint8_t *)&swap + 8 - size,
|
||||
(uint8_t *)&swap + 8);
|
||||
}
|
||||
|
||||
std::string makeKey(int64_t num, int suffixLen) {
|
||||
void tupleAppend(std::string &output, std::string_view value) {
|
||||
output.push_back('\x02');
|
||||
if (memchr(value.data(), '\x00', value.size()) != nullptr) {
|
||||
for (auto c : value) {
|
||||
if (c == '\x00') {
|
||||
output.push_back('\x00');
|
||||
output.push_back('\xff');
|
||||
} else {
|
||||
output.push_back(c);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
output.insert(output.end(), value.begin(), value.end());
|
||||
}
|
||||
output.push_back('\x00');
|
||||
}
|
||||
|
||||
template <class... Ts> std::string tupleKey(const Ts &...ts) {
|
||||
std::string result;
|
||||
result.resize(sizeof(int64_t) + suffixLen);
|
||||
int64_t be = __builtin_bswap64(num);
|
||||
memcpy(result.data(), &be, sizeof(int64_t));
|
||||
memset(result.data() + sizeof(int64_t), 0, suffixLen);
|
||||
(tupleAppend(result, ts), ...);
|
||||
return result;
|
||||
}
|
||||
|
||||
void workload(weaselab::ConflictSet *cs) {
|
||||
int64_t version = kWindowSize;
|
||||
constexpr int kNumWrites = 16;
|
||||
for (;; transactions.fetch_add(1, std::memory_order_relaxed)) {
|
||||
std::vector<std::string> keys;
|
||||
std::vector<weaselab::ConflictSet::WriteRange> writes;
|
||||
for (int i = 0; i < kNumWrites; ++i) {
|
||||
keys.push_back(makeKey(rand() % kNumPrefixes, rand() % 50));
|
||||
constexpr int kTotalKeyRange = 1'000'000'000;
|
||||
constexpr int kWindowSize = 1'000'000;
|
||||
constexpr int kNumReadKeysPerTx = 10;
|
||||
constexpr int kNumWriteKeysPerTx = 5;
|
||||
|
||||
struct Transaction {
|
||||
std::vector<std::string> keys;
|
||||
std::vector<weaselab::ConflictSet::ReadRange> reads;
|
||||
std::vector<weaselab::ConflictSet::WriteRange> writes;
|
||||
int64_t version;
|
||||
int64_t oldestVersion;
|
||||
Transaction() = default;
|
||||
explicit Transaction(int64_t version)
|
||||
: version(version), oldestVersion(version - kWindowSize) {
|
||||
std::vector<int64_t> keyIndices;
|
||||
for (int i = 0; i < std::max(kNumReadKeysPerTx, kNumWriteKeysPerTx); ++i) {
|
||||
keyIndices.push_back(rand() % kTotalKeyRange);
|
||||
}
|
||||
for (int i = 0; i < kNumWrites; ++i) {
|
||||
std::sort(keyIndices.begin(), keyIndices.end());
|
||||
constexpr std::string_view fullString =
|
||||
"this is a string, where a prefix of it is used as an element of the "
|
||||
"tuple forming the key";
|
||||
for (int i = 0; i < int(keyIndices.size()); ++i) {
|
||||
keys.push_back(
|
||||
tupleKey(0x100, keyIndices[i] / fullString.size(),
|
||||
fullString.substr(0, keyIndices[i] % fullString.size())));
|
||||
// printf("%s\n", printable(keys.back()).c_str());
|
||||
}
|
||||
for (int i = 0; i < kNumWriteKeysPerTx; ++i) {
|
||||
writes.push_back({{(const uint8_t *)keys[i].data(), int(keys[i].size())},
|
||||
{nullptr, 0}});
|
||||
}
|
||||
cs->addWrites(writes.data(), writes.size(), version);
|
||||
cs->setOldestVersion(version - kWindowSize);
|
||||
++version;
|
||||
reads.push_back({{(const uint8_t *)keys[0].data(), int(keys[0].size())},
|
||||
{(const uint8_t *)keys[1].data(), int(keys[1].size())},
|
||||
version - std::min(10, kWindowSize)});
|
||||
static_assert(kNumReadKeysPerTx >= 3);
|
||||
for (int i = 2; i < kNumReadKeysPerTx; ++i) {
|
||||
reads.push_back({{(const uint8_t *)keys[i].data(), int(keys[i].size())},
|
||||
{nullptr, 0},
|
||||
version - kWindowSize});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Transaction(Transaction &&) = default;
|
||||
Transaction &operator=(Transaction &&) = default;
|
||||
Transaction(Transaction const &) = delete;
|
||||
Transaction const &operator=(Transaction const &) = delete;
|
||||
};
|
||||
|
||||
struct Resolver {
|
||||
|
||||
void resolve(const weaselab::ConflictSet::ReadRange *reads, int readCount,
|
||||
const weaselab::ConflictSet::WriteRange *writes, int writeCount,
|
||||
int64_t newVersion, int64_t newOldestVersion) {
|
||||
results.resize(readCount);
|
||||
cs.check(reads, results.data(), readCount);
|
||||
cs.addWrites(writes, writeCount, newVersion);
|
||||
cs.setOldestVersion(newOldestVersion);
|
||||
}
|
||||
|
||||
ConflictSet cs{0};
|
||||
|
||||
private:
|
||||
std::vector<weaselab::ConflictSet::Result> results;
|
||||
};
|
||||
|
||||
// Adapted from getaddrinfo man page
|
||||
int getListenFd(const char *node, const char *service) {
|
||||
@@ -196,7 +366,8 @@ int main(int argc, char **argv) {
|
||||
{
|
||||
int listenFd = getListenFd(argv[1], argv[2]);
|
||||
|
||||
weaselab::ConflictSet cs{0};
|
||||
Resolver resolver;
|
||||
auto &cs = resolver.cs;
|
||||
weaselab::ConflictSet::MetricsV1 *metrics;
|
||||
int metricsCount;
|
||||
cs.getMetricsV1(&metrics, &metricsCount);
|
||||
@@ -245,7 +416,22 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
auto w = std::thread{workload, &cs};
|
||||
TxQueue<Transaction> queue{10};
|
||||
|
||||
auto workloadThread = std::thread{[&]() {
|
||||
for (int64_t version = kWindowSize;;
|
||||
++version, transactions.fetch_add(1, std::memory_order_relaxed)) {
|
||||
queue.push(Transaction(version));
|
||||
}
|
||||
}};
|
||||
|
||||
auto resolverThread = std::thread{[&]() {
|
||||
for (;;) {
|
||||
auto tx = queue.pop();
|
||||
resolver.resolve(tx->reads.data(), tx->reads.size(), tx->writes.data(),
|
||||
tx->writes.size(), tx->version, tx->oldestVersion);
|
||||
}
|
||||
}};
|
||||
|
||||
for (;;) {
|
||||
struct sockaddr_storage peer_addr = {};
|
||||
|
@@ -767,7 +767,9 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
false, true);
|
||||
}
|
||||
|
||||
sortPoints(points);
|
||||
if (!std::is_sorted(points.begin(), points.end())) {
|
||||
sortPoints(points);
|
||||
}
|
||||
|
||||
int activeWriteCount = 0;
|
||||
std::vector<std::pair<StringRef, StringRef>> combinedWriteConflictRanges;
|
||||
@@ -794,7 +796,6 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
int temp[stripeSize];
|
||||
int stripes = (stringCount + stripeSize - 1) / stripeSize;
|
||||
StringRef values[stripeSize];
|
||||
int64_t writeVersions[stripeSize / 2];
|
||||
int ss = stringCount - (stripes - 1) * stripeSize;
|
||||
int64_t entryDelta = 0;
|
||||
for (int s = stripes - 1; s >= 0; s--) {
|
||||
|
@@ -1,3 +1,4 @@
|
||||
___chkstk_darwin
|
||||
___stack_chk_fail
|
||||
___stack_chk_guard
|
||||
__tlv_bootstrap
|
||||
@@ -5,6 +6,7 @@ _abort
|
||||
_bzero
|
||||
_free
|
||||
_malloc
|
||||
_memcmp
|
||||
_memcpy
|
||||
_memmove
|
||||
dyld_stub_binder
|
BIN
corpus/00c877491b1fcc8bb8fb36874a7922de7f3f4df2
Normal file
BIN
corpus/00c877491b1fcc8bb8fb36874a7922de7f3f4df2
Normal file
Binary file not shown.
BIN
corpus/03cbf22d59d0005921ca3e3c725fc9c165f9e873
Normal file
BIN
corpus/03cbf22d59d0005921ca3e3c725fc9c165f9e873
Normal file
Binary file not shown.
BIN
corpus/03d3918b737a86ed38fbeae6dff198d6913b90b2
Normal file
BIN
corpus/03d3918b737a86ed38fbeae6dff198d6913b90b2
Normal file
Binary file not shown.
BIN
corpus/04228353f0feb04662eebbe15dab859927d87982
Normal file
BIN
corpus/04228353f0feb04662eebbe15dab859927d87982
Normal file
Binary file not shown.
BIN
corpus/042c4df1a3357a2b015db64e8e6b09549d3655c5
Normal file
BIN
corpus/042c4df1a3357a2b015db64e8e6b09549d3655c5
Normal file
Binary file not shown.
BIN
corpus/04c53e268f5d34ac6033f80672ebf9b48975cfc8
Normal file
BIN
corpus/04c53e268f5d34ac6033f80672ebf9b48975cfc8
Normal file
Binary file not shown.
BIN
corpus/04c65b5774374b94914863a1c244cd4ca26873d2
Normal file
BIN
corpus/04c65b5774374b94914863a1c244cd4ca26873d2
Normal file
Binary file not shown.
BIN
corpus/054623afeda876d353806d81077181229affdd36
Normal file
BIN
corpus/054623afeda876d353806d81077181229affdd36
Normal file
Binary file not shown.
BIN
corpus/0558cbe0f7b69d3e129a95d07a67e6bcd737f280
Normal file
BIN
corpus/0558cbe0f7b69d3e129a95d07a67e6bcd737f280
Normal file
Binary file not shown.
BIN
corpus/060d0c1be7331609f5b8c1d1201bc06c1b203c21
Normal file
BIN
corpus/060d0c1be7331609f5b8c1d1201bc06c1b203c21
Normal file
Binary file not shown.
BIN
corpus/0677708940f8c88cd48e841993d34838d9b1215e
Normal file
BIN
corpus/0677708940f8c88cd48e841993d34838d9b1215e
Normal file
Binary file not shown.
BIN
corpus/080d022ba31789a6276dbf9c7796f05cc9559c36
Normal file
BIN
corpus/080d022ba31789a6276dbf9c7796f05cc9559c36
Normal file
Binary file not shown.
BIN
corpus/097e37993adeed2f667efe74003d98b0cd90c5d8
Normal file
BIN
corpus/097e37993adeed2f667efe74003d98b0cd90c5d8
Normal file
Binary file not shown.
BIN
corpus/09d49cebef016c9caf2c3efe971375557329053b
Normal file
BIN
corpus/09d49cebef016c9caf2c3efe971375557329053b
Normal file
Binary file not shown.
BIN
corpus/0b43bd12f2b7df4397072b128c1eac80fc308b47
Normal file
BIN
corpus/0b43bd12f2b7df4397072b128c1eac80fc308b47
Normal file
Binary file not shown.
BIN
corpus/0b93fbf7c443c8403e0c3ee6cd3d9498aa9aaeb0
Normal file
BIN
corpus/0b93fbf7c443c8403e0c3ee6cd3d9498aa9aaeb0
Normal file
Binary file not shown.
BIN
corpus/0bb1476984cada2ca3fc922dd918f0d2df54114c
Normal file
BIN
corpus/0bb1476984cada2ca3fc922dd918f0d2df54114c
Normal file
Binary file not shown.
BIN
corpus/0c80c84b1d1b8b157106f257cf9bf2fd404936d5
Normal file
BIN
corpus/0c80c84b1d1b8b157106f257cf9bf2fd404936d5
Normal file
Binary file not shown.
BIN
corpus/0cb7fd64803ef442156dab03223d5cca8d8ee899
Normal file
BIN
corpus/0cb7fd64803ef442156dab03223d5cca8d8ee899
Normal file
Binary file not shown.
BIN
corpus/0d35b148f45f7e3f722f4ac298558ba0dd545b48
Normal file
BIN
corpus/0d35b148f45f7e3f722f4ac298558ba0dd545b48
Normal file
Binary file not shown.
BIN
corpus/0eb983ee4da4177894988ab187e0d17719df3c3e
Normal file
BIN
corpus/0eb983ee4da4177894988ab187e0d17719df3c3e
Normal file
Binary file not shown.
BIN
corpus/0f1d504244bcffbad21d5b849e245326f62807ff
Normal file
BIN
corpus/0f1d504244bcffbad21d5b849e245326f62807ff
Normal file
Binary file not shown.
BIN
corpus/1030748ff092d1b4ec3d30d7b68ba29d895b4b7a
Normal file
BIN
corpus/1030748ff092d1b4ec3d30d7b68ba29d895b4b7a
Normal file
Binary file not shown.
BIN
corpus/12e31d99ae65da7d9d6bcb04c6bd97422a85d309
Normal file
BIN
corpus/12e31d99ae65da7d9d6bcb04c6bd97422a85d309
Normal file
Binary file not shown.
BIN
corpus/1319ce414e7cd478b06628f9951e7620134cbbf2
Normal file
BIN
corpus/1319ce414e7cd478b06628f9951e7620134cbbf2
Normal file
Binary file not shown.
BIN
corpus/136ad900e11b346cf1ef2d3b0a2a94ce6a17e797
Normal file
BIN
corpus/136ad900e11b346cf1ef2d3b0a2a94ce6a17e797
Normal file
Binary file not shown.
BIN
corpus/136c9552d2addd4e4796bb87ea2a26d5c18bc9c6
Normal file
BIN
corpus/136c9552d2addd4e4796bb87ea2a26d5c18bc9c6
Normal file
Binary file not shown.
BIN
corpus/137f0707639206c6829f2fadb5f2afe28ccc28ca
Normal file
BIN
corpus/137f0707639206c6829f2fadb5f2afe28ccc28ca
Normal file
Binary file not shown.
BIN
corpus/1422bf555066426571aacaa1a32317dc1c327899
Normal file
BIN
corpus/1422bf555066426571aacaa1a32317dc1c327899
Normal file
Binary file not shown.
BIN
corpus/16a5be5020942fa702a6ecd856fdcc74febd58aa
Normal file
BIN
corpus/16a5be5020942fa702a6ecd856fdcc74febd58aa
Normal file
Binary file not shown.
BIN
corpus/17deb8c5506e9e6383f3303464e3947309dce6af
Normal file
BIN
corpus/17deb8c5506e9e6383f3303464e3947309dce6af
Normal file
Binary file not shown.
BIN
corpus/194df5c76063026f1c8abd184d735a4b1eb241f1
Normal file
BIN
corpus/194df5c76063026f1c8abd184d735a4b1eb241f1
Normal file
Binary file not shown.
BIN
corpus/1954acdf763b1b51cded78bd229888301c69aa91
Normal file
BIN
corpus/1954acdf763b1b51cded78bd229888301c69aa91
Normal file
Binary file not shown.
BIN
corpus/19cfb9577be15c68580d0f57a181c3f3d3d306bd
Normal file
BIN
corpus/19cfb9577be15c68580d0f57a181c3f3d3d306bd
Normal file
Binary file not shown.
BIN
corpus/1aa3ffd1ac1252a7c28ddabfea013fc012a35d55
Normal file
BIN
corpus/1aa3ffd1ac1252a7c28ddabfea013fc012a35d55
Normal file
Binary file not shown.
BIN
corpus/1c65a17a05d620dd0b46c63d71d0febfbbb6aeb6
Normal file
BIN
corpus/1c65a17a05d620dd0b46c63d71d0febfbbb6aeb6
Normal file
Binary file not shown.
BIN
corpus/1d5fcccb6b1cc7302609da41cacddb3bd9b23d24
Normal file
BIN
corpus/1d5fcccb6b1cc7302609da41cacddb3bd9b23d24
Normal file
Binary file not shown.
BIN
corpus/1dc7440bcc0d68c7c8bfa6acae094449f63acaa1
Normal file
BIN
corpus/1dc7440bcc0d68c7c8bfa6acae094449f63acaa1
Normal file
Binary file not shown.
BIN
corpus/1e7a4ca606559d15183818a6c3d93b2f132b2fff
Normal file
BIN
corpus/1e7a4ca606559d15183818a6c3d93b2f132b2fff
Normal file
Binary file not shown.
BIN
corpus/20107cb023d141fa1971e489933b434f1f5e14ed
Normal file
BIN
corpus/20107cb023d141fa1971e489933b434f1f5e14ed
Normal file
Binary file not shown.
BIN
corpus/205a52b91111417c390bf2ad3bf01688b0f9287e
Normal file
BIN
corpus/205a52b91111417c390bf2ad3bf01688b0f9287e
Normal file
Binary file not shown.
BIN
corpus/207397463b1d25099638e8425560aee6e7b5e1c6
Normal file
BIN
corpus/207397463b1d25099638e8425560aee6e7b5e1c6
Normal file
Binary file not shown.
BIN
corpus/20a2ac8914e72e9855c5bd1d7de64cae52ccccc4
Normal file
BIN
corpus/20a2ac8914e72e9855c5bd1d7de64cae52ccccc4
Normal file
Binary file not shown.
BIN
corpus/20d0972b42d55ac327f990a815306f7dc78a7dea
Normal file
BIN
corpus/20d0972b42d55ac327f990a815306f7dc78a7dea
Normal file
Binary file not shown.
BIN
corpus/2151def25909e36ffcbd00a6b32359e0ef1cef32
Normal file
BIN
corpus/2151def25909e36ffcbd00a6b32359e0ef1cef32
Normal file
Binary file not shown.
BIN
corpus/21f2f836827351a73a6c923d5663d056b34d3287
Normal file
BIN
corpus/21f2f836827351a73a6c923d5663d056b34d3287
Normal file
Binary file not shown.
BIN
corpus/23b9378fd1cb569c30ce7dc580eb28b44aff7126
Normal file
BIN
corpus/23b9378fd1cb569c30ce7dc580eb28b44aff7126
Normal file
Binary file not shown.
BIN
corpus/247170df5721ec417ade8bd4ecfee2093f1785e6
Normal file
BIN
corpus/247170df5721ec417ade8bd4ecfee2093f1785e6
Normal file
Binary file not shown.
BIN
corpus/24df6265915cc880c972ee07c161ffac178fb863
Normal file
BIN
corpus/24df6265915cc880c972ee07c161ffac178fb863
Normal file
Binary file not shown.
BIN
corpus/25046edfa84c50539e352d8a5c14d5a38cbccbc9
Normal file
BIN
corpus/25046edfa84c50539e352d8a5c14d5a38cbccbc9
Normal file
Binary file not shown.
BIN
corpus/2516ed82e09a82fb3208befc7bbec866b45709ad
Normal file
BIN
corpus/2516ed82e09a82fb3208befc7bbec866b45709ad
Normal file
Binary file not shown.
BIN
corpus/25aac6502b651821dbd979eb57bf6b0b58fd5a62
Normal file
BIN
corpus/25aac6502b651821dbd979eb57bf6b0b58fd5a62
Normal file
Binary file not shown.
BIN
corpus/25b53bb777958923b70116b7117624593ae48c02
Normal file
BIN
corpus/25b53bb777958923b70116b7117624593ae48c02
Normal file
Binary file not shown.
BIN
corpus/25e3c7c3e927f09e1b6de72c6a2306f80d483216
Normal file
BIN
corpus/25e3c7c3e927f09e1b6de72c6a2306f80d483216
Normal file
Binary file not shown.
BIN
corpus/26ac1ea5ad85e43ed4aff18c34b6622a5f6982ce
Normal file
BIN
corpus/26ac1ea5ad85e43ed4aff18c34b6622a5f6982ce
Normal file
Binary file not shown.
BIN
corpus/27b944fa456f2e21417e099d13e629a5b434c02c
Normal file
BIN
corpus/27b944fa456f2e21417e099d13e629a5b434c02c
Normal file
Binary file not shown.
BIN
corpus/29011c665d23b30dc75ab6d25637fa01f2c210f7
Normal file
BIN
corpus/29011c665d23b30dc75ab6d25637fa01f2c210f7
Normal file
Binary file not shown.
BIN
corpus/298e4662b83f59e9689da9642a85f29da21cce6e
Normal file
BIN
corpus/298e4662b83f59e9689da9642a85f29da21cce6e
Normal file
Binary file not shown.
BIN
corpus/2ba7bf5e5384faaa057fb2d959f1f72da11bd42c
Normal file
BIN
corpus/2ba7bf5e5384faaa057fb2d959f1f72da11bd42c
Normal file
Binary file not shown.
BIN
corpus/2c1d38ee4c45adf9c5140de0eaf8f32aa9a07ef9
Normal file
BIN
corpus/2c1d38ee4c45adf9c5140de0eaf8f32aa9a07ef9
Normal file
Binary file not shown.
BIN
corpus/2c974e4cf958415bf3b53a46d0f4a9487a3b6b51
Normal file
BIN
corpus/2c974e4cf958415bf3b53a46d0f4a9487a3b6b51
Normal file
Binary file not shown.
BIN
corpus/2d4fb3ad67c766ebc47e3527260422ea03af7971
Normal file
BIN
corpus/2d4fb3ad67c766ebc47e3527260422ea03af7971
Normal file
Binary file not shown.
BIN
corpus/2d98ecbaadf6adcba6d9dbb5de15436dfa92df6e
Normal file
BIN
corpus/2d98ecbaadf6adcba6d9dbb5de15436dfa92df6e
Normal file
Binary file not shown.
BIN
corpus/2e04ff65d8e5acae31b2362e0f69ac0c18a92dcf
Normal file
BIN
corpus/2e04ff65d8e5acae31b2362e0f69ac0c18a92dcf
Normal file
Binary file not shown.
BIN
corpus/2e83539f9e2231d919e3b0a78daff27922f6b3f1
Normal file
BIN
corpus/2e83539f9e2231d919e3b0a78daff27922f6b3f1
Normal file
Binary file not shown.
BIN
corpus/3079be46e3d119bd7d06acf317a987326aa8632d
Normal file
BIN
corpus/3079be46e3d119bd7d06acf317a987326aa8632d
Normal file
Binary file not shown.
BIN
corpus/30c2bb0e617ff9a8b3ab252971be3fdc61f58e9b
Normal file
BIN
corpus/30c2bb0e617ff9a8b3ab252971be3fdc61f58e9b
Normal file
Binary file not shown.
BIN
corpus/3152eab8b81e46d345055a317c5bdc73c5c3bb9c
Normal file
BIN
corpus/3152eab8b81e46d345055a317c5bdc73c5c3bb9c
Normal file
Binary file not shown.
BIN
corpus/3228c1e3b4146e1700d9e0cc656f59c41671a4a4
Normal file
BIN
corpus/3228c1e3b4146e1700d9e0cc656f59c41671a4a4
Normal file
Binary file not shown.
BIN
corpus/323ac17ef36be225783d3f0c88b0d055a7ce7f45
Normal file
BIN
corpus/323ac17ef36be225783d3f0c88b0d055a7ce7f45
Normal file
Binary file not shown.
BIN
corpus/331ea636a95119523c7cab0a280bbef9873a05d5
Normal file
BIN
corpus/331ea636a95119523c7cab0a280bbef9873a05d5
Normal file
Binary file not shown.
BIN
corpus/3349a2cb0de93c001fc81dd09b795b7bb2911cb2
Normal file
BIN
corpus/3349a2cb0de93c001fc81dd09b795b7bb2911cb2
Normal file
Binary file not shown.
BIN
corpus/3388003130da408556ca4ebbe6f1e3cc3e110b33
Normal file
BIN
corpus/3388003130da408556ca4ebbe6f1e3cc3e110b33
Normal file
Binary file not shown.
BIN
corpus/342740d94427af6509e3332d46d99e1091a5c065
Normal file
BIN
corpus/342740d94427af6509e3332d46d99e1091a5c065
Normal file
Binary file not shown.
BIN
corpus/34fb7dac66e0e779e88368c44c96b19a4717c897
Normal file
BIN
corpus/34fb7dac66e0e779e88368c44c96b19a4717c897
Normal file
Binary file not shown.
BIN
corpus/3571178de127e769d6229057b205f9df36506cbd
Normal file
BIN
corpus/3571178de127e769d6229057b205f9df36506cbd
Normal file
Binary file not shown.
BIN
corpus/358402b95edb4ab9c4577f4627f0b41a194e741b
Normal file
BIN
corpus/358402b95edb4ab9c4577f4627f0b41a194e741b
Normal file
Binary file not shown.
BIN
corpus/358f96c9170a589697f4f93c5ec7ed31e5878778
Normal file
BIN
corpus/358f96c9170a589697f4f93c5ec7ed31e5878778
Normal file
Binary file not shown.
BIN
corpus/36bc3a1544e6b3564de3e1944274541ea8e44346
Normal file
BIN
corpus/36bc3a1544e6b3564de3e1944274541ea8e44346
Normal file
Binary file not shown.
BIN
corpus/3774dad136ef596aeb2c117de9ec7a9a96ca03c2
Normal file
BIN
corpus/3774dad136ef596aeb2c117de9ec7a9a96ca03c2
Normal file
Binary file not shown.
BIN
corpus/37c207869d991553727871f56ae2bb26cd779979
Normal file
BIN
corpus/37c207869d991553727871f56ae2bb26cd779979
Normal file
Binary file not shown.
BIN
corpus/39d85e639d592624cae186777f00753a5e9029db
Normal file
BIN
corpus/39d85e639d592624cae186777f00753a5e9029db
Normal file
Binary file not shown.
BIN
corpus/3b2f45d609b426487d7f50eaecb12c34513f5f77
Normal file
BIN
corpus/3b2f45d609b426487d7f50eaecb12c34513f5f77
Normal file
Binary file not shown.
BIN
corpus/3c1a9cec8435cdf21b6d0ae9635dfc73df7f9c50
Normal file
BIN
corpus/3c1a9cec8435cdf21b6d0ae9635dfc73df7f9c50
Normal file
Binary file not shown.
BIN
corpus/3d06d1df0c1014d2566900f6f999195f82360576
Normal file
BIN
corpus/3d06d1df0c1014d2566900f6f999195f82360576
Normal file
Binary file not shown.
BIN
corpus/3e488fe489477f86a15c00a6e58dccdea748c0aa
Normal file
BIN
corpus/3e488fe489477f86a15c00a6e58dccdea748c0aa
Normal file
Binary file not shown.
BIN
corpus/3ed5e36f67e3dcd0aaf17d62eb2d3fc877c95510
Normal file
BIN
corpus/3ed5e36f67e3dcd0aaf17d62eb2d3fc877c95510
Normal file
Binary file not shown.
BIN
corpus/3f3103d592f54abbe073a2eca8c32eb1e69f8c54
Normal file
BIN
corpus/3f3103d592f54abbe073a2eca8c32eb1e69f8c54
Normal file
Binary file not shown.
BIN
corpus/3f6e8816eb9b31c008b6b576a1c0d99bbbdcb8bf
Normal file
BIN
corpus/3f6e8816eb9b31c008b6b576a1c0d99bbbdcb8bf
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user