Compare commits
41 Commits
v0.0.9
...
d1dc1247e1
Author | SHA1 | Date | |
---|---|---|---|
d1dc1247e1 | |||
f1ad68109a | |||
c4443bc355 | |||
857b402fe2 | |||
9b3e1b219b | |||
ab52c63935 | |||
bad9d7ced8 | |||
c8d9dc034d | |||
72168ef6a3 | |||
620a0afd2a | |||
b0414969be | |||
1673e1c0dd | |||
7351b6e417 | |||
561ed45e3e | |||
ca804f28c0 | |||
3898cb596a | |||
b8edd92698 | |||
8e480528d5 | |||
4113183155 | |||
adb8fdc5e9 | |||
c86e407985 | |||
71a84057cb | |||
9c5e5863c2 | |||
be67555756 | |||
988ec5ce69 | |||
f5a0d81c52 | |||
3b2bd16cd1 | |||
4b3df0a426 | |||
4cdf6deb50 | |||
f21dde06d3 | |||
2b11650589 | |||
fce998460f | |||
6da3125719 | |||
79410d071f | |||
1fcca6450d | |||
55271ad06c | |||
e675612599 | |||
42b5d50492 | |||
6394995def | |||
c649bc7964 | |||
ec85a06d01 |
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.18)
|
||||
project(
|
||||
conflict-set
|
||||
VERSION 0.0.9
|
||||
VERSION 0.0.10
|
||||
DESCRIPTION
|
||||
"A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys."
|
||||
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/conflict-set"
|
||||
@@ -19,12 +19,6 @@ include(CheckCXXSourceCompiles)
|
||||
|
||||
set(DEFAULT_BUILD_TYPE "Release")
|
||||
|
||||
if(EMSCRIPTEN OR CMAKE_SYSTEM_NAME STREQUAL WASI)
|
||||
set(WASM ON)
|
||||
else()
|
||||
set(WASM OFF)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
message(
|
||||
STATUS
|
||||
@@ -37,8 +31,14 @@ 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(
|
||||
-fdata-sections
|
||||
-ffunction-sections
|
||||
-Wswitch-enum
|
||||
-Werror=switch-enum
|
||||
-fPIC
|
||||
-g
|
||||
-fno-omit-frame-pointer)
|
||||
|
||||
set(full_relro_flags "-pie;LINKER:-z,relro,-z,now,-z,noexecstack")
|
||||
cmake_push_check_state()
|
||||
@@ -81,15 +81,6 @@ if(EMSCRIPTEN)
|
||||
endif()
|
||||
|
||||
if(NOT USE_SIMD_FALLBACK)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS -msimd128)
|
||||
check_include_file_cxx("wasm_simd128.h" HAS_WASM_SIMD)
|
||||
if(HAS_WASM_SIMD)
|
||||
add_compile_options(-msimd128)
|
||||
add_compile_definitions(HAS_WASM_SIMD)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS -mavx)
|
||||
check_include_file_cxx("immintrin.h" HAS_AVX)
|
||||
@@ -162,47 +153,40 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND BUILD_TESTING)
|
||||
|
||||
file(GLOB CORPUS_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/corpus/*)
|
||||
|
||||
# extra testing that relies on shared libraries, which aren't available with
|
||||
# wasm
|
||||
if(NOT WASM)
|
||||
# Shared library version of FoundationDB's skip list implementation
|
||||
add_library(skip_list SHARED SkipList.cpp)
|
||||
target_compile_options(skip_list PRIVATE -fno-exceptions
|
||||
-fvisibility=hidden)
|
||||
target_include_directories(skip_list
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
set_target_properties(
|
||||
skip_list PROPERTIES LIBRARY_OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/skip_list")
|
||||
set_target_properties(skip_list PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
|
||||
set_target_properties(
|
||||
skip_list PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION
|
||||
${PROJECT_VERSION_MAJOR})
|
||||
# Shared library version of FoundationDB's skip list implementation
|
||||
add_library(skip_list SHARED SkipList.cpp)
|
||||
target_compile_options(skip_list PRIVATE -fno-exceptions -fvisibility=hidden)
|
||||
target_include_directories(skip_list
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
set_target_properties(
|
||||
skip_list PROPERTIES LIBRARY_OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/skip_list")
|
||||
set_target_properties(skip_list PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
|
||||
set_target_properties(skip_list PROPERTIES VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR})
|
||||
|
||||
# Shared library version of a std::unordered_map-based conflict set (point
|
||||
# queries only)
|
||||
add_library(hash_table SHARED HashTable.cpp)
|
||||
target_compile_options(hash_table PRIVATE -fno-exceptions
|
||||
-fvisibility=hidden)
|
||||
target_include_directories(hash_table
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
set_target_properties(
|
||||
hash_table PROPERTIES LIBRARY_OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/hash_table")
|
||||
set_target_properties(hash_table PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
|
||||
set_target_properties(
|
||||
hash_table PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION
|
||||
${PROJECT_VERSION_MAJOR})
|
||||
# Shared library version of a std::unordered_map-based conflict set (point
|
||||
# queries only)
|
||||
add_library(hash_table SHARED HashTable.cpp)
|
||||
target_compile_options(hash_table PRIVATE -fno-exceptions -fvisibility=hidden)
|
||||
target_include_directories(hash_table
|
||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
set_target_properties(
|
||||
hash_table PROPERTIES LIBRARY_OUTPUT_DIRECTORY
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/hash_table")
|
||||
set_target_properties(hash_table PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
|
||||
set_target_properties(
|
||||
hash_table PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION
|
||||
${PROJECT_VERSION_MAJOR})
|
||||
|
||||
add_executable(driver_skip_list TestDriver.cpp)
|
||||
target_compile_options(driver_skip_list PRIVATE ${TEST_FLAGS})
|
||||
target_link_libraries(driver_skip_list PRIVATE skip_list)
|
||||
add_executable(driver_skip_list TestDriver.cpp)
|
||||
target_compile_options(driver_skip_list PRIVATE ${TEST_FLAGS})
|
||||
target_link_libraries(driver_skip_list PRIVATE skip_list)
|
||||
|
||||
foreach(TEST ${CORPUS_TESTS})
|
||||
get_filename_component(hash ${TEST} NAME)
|
||||
add_test(NAME skip_list_${hash} COMMAND driver_skip_list ${TEST})
|
||||
endforeach()
|
||||
endif()
|
||||
foreach(TEST ${CORPUS_TESTS})
|
||||
get_filename_component(hash ${TEST} NAME)
|
||||
add_test(NAME skip_list_${hash} COMMAND driver_skip_list ${TEST})
|
||||
endforeach()
|
||||
|
||||
# ad hoc testing
|
||||
add_executable(conflict_set_main ConflictSet.cpp)
|
||||
@@ -320,7 +304,7 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR AND BUILD_TESTING)
|
||||
add_test(NAME conflict_set_cxx_api_test COMMAND conflict_set_cxx_api_test)
|
||||
|
||||
# symbol visibility tests
|
||||
if(NOT WASM AND NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
if(APPLE)
|
||||
set(symbol_exports ${CMAKE_CURRENT_SOURCE_DIR}/apple-symbol-exports.txt)
|
||||
set(symbol_imports ${CMAKE_CURRENT_SOURCE_DIR}/apple-symbol-imports.txt)
|
||||
|
836
ConflictSet.cpp
836
ConflictSet.cpp
File diff suppressed because it is too large
Load Diff
126
Internal.h
126
Internal.h
@@ -580,11 +580,14 @@ namespace {
|
||||
|
||||
template <class ConflictSetImpl, bool kEnableAssertions = true>
|
||||
struct TestDriver {
|
||||
Arbitrary arbitrary;
|
||||
explicit TestDriver(const uint8_t *data, size_t size)
|
||||
: arbitrary({data, size}) {}
|
||||
Arbitrary *arbitrary;
|
||||
explicit TestDriver(Arbitrary &a) : arbitrary(&a) {
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
fprintf(stderr, "%p Initial version: {%" PRId64 "}\n", this, writeVersion);
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t oldestVersion = arbitrary.next();
|
||||
int64_t oldestVersion = arbitrary->next();
|
||||
int64_t writeVersion = oldestVersion;
|
||||
ConflictSetImpl cs{oldestVersion};
|
||||
ReferenceImpl refImpl{oldestVersion};
|
||||
@@ -593,33 +596,34 @@ struct TestDriver {
|
||||
|
||||
bool ok = true;
|
||||
|
||||
const int prefixLen = arbitrary.bounded(512);
|
||||
const int prefixByte = arbitrary.randT<uint8_t>();
|
||||
const int prefixLen = arbitrary->bounded(512);
|
||||
const int prefixByte = arbitrary->randT<uint8_t>();
|
||||
|
||||
// Call until it returns true, for "done". Check internal invariants etc
|
||||
// between calls to next.
|
||||
bool next() {
|
||||
assert(cs.getBytes() >= 0);
|
||||
if (!arbitrary.hasEntropy()) {
|
||||
if (!arbitrary->hasEntropy()) {
|
||||
return true;
|
||||
}
|
||||
Arena arena;
|
||||
{
|
||||
int numPointWrites = arbitrary.bounded(100);
|
||||
int numRangeWrites = arbitrary.bounded(100);
|
||||
int64_t v = (writeVersion += arbitrary.bounded(10) ? arbitrary.bounded(10)
|
||||
: arbitrary.next());
|
||||
int numPointWrites = arbitrary->bounded(100);
|
||||
int numRangeWrites = arbitrary->bounded(100);
|
||||
int64_t v =
|
||||
(writeVersion +=
|
||||
arbitrary->bounded(10) ? arbitrary->bounded(10) : arbitrary->next());
|
||||
auto *writes =
|
||||
new (arena) ConflictSet::WriteRange[numPointWrites + numRangeWrites];
|
||||
auto keys = set<std::string_view>(arena);
|
||||
while (int(keys.size()) < numPointWrites + numRangeWrites * 2) {
|
||||
if (!arbitrary.hasEntropy()) {
|
||||
if (!arbitrary->hasEntropy()) {
|
||||
return true;
|
||||
}
|
||||
int keyLen = prefixLen + arbitrary.bounded(kMaxKeySuffixLen);
|
||||
int keyLen = prefixLen + arbitrary->bounded(kMaxKeySuffixLen);
|
||||
auto *begin = new (arena) uint8_t[keyLen];
|
||||
memset(begin, prefixByte, prefixLen);
|
||||
arbitrary.randomBytes(begin + prefixLen, keyLen - prefixLen);
|
||||
arbitrary->randomBytes(begin + prefixLen, keyLen - prefixLen);
|
||||
keys.insert(std::string_view((const char *)begin, keyLen));
|
||||
}
|
||||
|
||||
@@ -629,7 +633,7 @@ struct TestDriver {
|
||||
rangesRemaining = numRangeWrites;
|
||||
pointsRemaining > 0 || rangesRemaining > 0; ++i) {
|
||||
bool pointRead = pointsRemaining > 0 && rangesRemaining > 0
|
||||
? bool(arbitrary.bounded(2))
|
||||
? bool(arbitrary->bounded(2))
|
||||
: pointsRemaining > 0;
|
||||
if (pointRead) {
|
||||
assert(pointsRemaining > 0);
|
||||
@@ -648,33 +652,20 @@ struct TestDriver {
|
||||
++iter;
|
||||
--rangesRemaining;
|
||||
}
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
if (writes[i].end.len == 0) {
|
||||
fprintf(stderr, "Write: {%s}\n", printable(writes[i].begin).c_str());
|
||||
} else {
|
||||
fprintf(stderr, "Write: [%s, %s)\n",
|
||||
printable(writes[i].begin).c_str(),
|
||||
printable(writes[i].end).c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
assert(iter == keys.end());
|
||||
assert(i == numPointWrites + numRangeWrites);
|
||||
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
fprintf(stderr, "Write @ %" PRId64 "\n", v);
|
||||
#endif
|
||||
|
||||
// Test non-canonical writes
|
||||
if (numPointWrites > 0) {
|
||||
int overlaps = arbitrary.bounded(numPointWrites);
|
||||
int overlaps = arbitrary->bounded(numPointWrites);
|
||||
for (int i = 0; i < numPointWrites + numRangeWrites && overlaps > 0;
|
||||
++i) {
|
||||
if (writes[i].end.len == 0) {
|
||||
int keyLen = prefixLen + arbitrary.bounded(kMaxKeySuffixLen);
|
||||
int keyLen = prefixLen + arbitrary->bounded(kMaxKeySuffixLen);
|
||||
auto *begin = new (arena) uint8_t[keyLen];
|
||||
memset(begin, prefixByte, prefixLen);
|
||||
arbitrary.randomBytes(begin + prefixLen, keyLen - prefixLen);
|
||||
arbitrary->randomBytes(begin + prefixLen, keyLen - prefixLen);
|
||||
writes[i].end.len = keyLen;
|
||||
writes[i].end.p = begin;
|
||||
auto c =
|
||||
@@ -692,10 +683,10 @@ struct TestDriver {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (arbitrary.bounded(2)) {
|
||||
if (arbitrary->bounded(2)) {
|
||||
// Shuffle writes
|
||||
for (int i = numPointWrites + numRangeWrites - 1; i > 0; --i) {
|
||||
int j = arbitrary.bounded(i + 1);
|
||||
int j = arbitrary->bounded(i + 1);
|
||||
if (i != j) {
|
||||
using std::swap;
|
||||
swap(writes[i], writes[j]);
|
||||
@@ -704,7 +695,7 @@ struct TestDriver {
|
||||
}
|
||||
|
||||
oldestVersion +=
|
||||
arbitrary.bounded(10) ? arbitrary.bounded(10) : arbitrary.next();
|
||||
arbitrary->bounded(10) ? arbitrary->bounded(10) : arbitrary->next();
|
||||
oldestVersion = std::min(oldestVersion, writeVersion);
|
||||
|
||||
#ifdef THREAD_TEST
|
||||
@@ -721,6 +712,20 @@ struct TestDriver {
|
||||
ready.wait();
|
||||
#endif
|
||||
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
for (int i = 0; i < numPointWrites + numRangeWrites; ++i) {
|
||||
if (writes[i].end.len == 0) {
|
||||
fprintf(stderr, "%p Write: {%s}\n", this,
|
||||
printable(writes[i].begin).c_str());
|
||||
} else {
|
||||
fprintf(stderr, "%p Write: [%s, %s)\n", this,
|
||||
printable(writes[i].begin).c_str(),
|
||||
printable(writes[i].end).c_str());
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "%p Write @ %" PRId64 "\n", this, v);
|
||||
#endif
|
||||
|
||||
CALLGRIND_START_INSTRUMENTATION;
|
||||
cs.addWrites(writes, numPointWrites + numRangeWrites, v);
|
||||
CALLGRIND_STOP_INSTRUMENTATION;
|
||||
@@ -729,6 +734,10 @@ struct TestDriver {
|
||||
refImpl.addWrites(writes, numPointWrites + numRangeWrites, v);
|
||||
}
|
||||
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
fprintf(stderr, "%p Set oldest version: %" PRId64 "\n", this,
|
||||
oldestVersion);
|
||||
#endif
|
||||
cs.setOldestVersion(oldestVersion);
|
||||
if constexpr (kEnableAssertions) {
|
||||
refImpl.setOldestVersion(oldestVersion);
|
||||
@@ -739,24 +748,24 @@ struct TestDriver {
|
||||
#endif
|
||||
}
|
||||
{
|
||||
int numPointReads = arbitrary.bounded(100);
|
||||
int numRangeReads = arbitrary.bounded(100);
|
||||
int numPointReads = arbitrary->bounded(100);
|
||||
int numRangeReads = arbitrary->bounded(100);
|
||||
|
||||
int64_t v = std::max<int64_t>(writeVersion - (arbitrary.bounded(10)
|
||||
? arbitrary.bounded(10)
|
||||
: arbitrary.next()),
|
||||
int64_t v = std::max<int64_t>(writeVersion - (arbitrary->bounded(10)
|
||||
? arbitrary->bounded(10)
|
||||
: arbitrary->next()),
|
||||
0);
|
||||
auto *reads =
|
||||
new (arena) ConflictSet::ReadRange[numPointReads + numRangeReads];
|
||||
auto keys = set<std::string_view>(arena);
|
||||
while (int(keys.size()) < numPointReads + numRangeReads * 2) {
|
||||
if (!arbitrary.hasEntropy()) {
|
||||
if (!arbitrary->hasEntropy()) {
|
||||
return true;
|
||||
}
|
||||
int keyLen = prefixLen + arbitrary.bounded(kMaxKeySuffixLen);
|
||||
int keyLen = prefixLen + arbitrary->bounded(kMaxKeySuffixLen);
|
||||
auto *begin = new (arena) uint8_t[keyLen];
|
||||
memset(begin, prefixByte, prefixLen);
|
||||
arbitrary.randomBytes(begin + prefixLen, keyLen - prefixLen);
|
||||
arbitrary->randomBytes(begin + prefixLen, keyLen - prefixLen);
|
||||
keys.insert(std::string_view((const char *)begin, keyLen));
|
||||
}
|
||||
|
||||
@@ -765,7 +774,7 @@ struct TestDriver {
|
||||
for (int pointsRemaining = numPointReads, rangesRemaining = numRangeReads;
|
||||
pointsRemaining > 0 || rangesRemaining > 0; ++i) {
|
||||
bool pointRead = pointsRemaining > 0 && rangesRemaining > 0
|
||||
? bool(arbitrary.bounded(2))
|
||||
? bool(arbitrary->bounded(2))
|
||||
: pointsRemaining > 0;
|
||||
if (pointRead) {
|
||||
assert(pointsRemaining > 0);
|
||||
@@ -787,10 +796,10 @@ struct TestDriver {
|
||||
reads[i].readVersion = v;
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
if (reads[i].end.len == 0) {
|
||||
fprintf(stderr, "Read: {%s} @ %" PRId64 "\n",
|
||||
fprintf(stderr, "%p Read: {%s} @ %" PRId64 "\n", this,
|
||||
printable(reads[i].begin).c_str(), reads[i].readVersion);
|
||||
} else {
|
||||
fprintf(stderr, "Read: [%s, %s) @ %" PRId64 "\n",
|
||||
fprintf(stderr, "%p Read: [%s, %s) @ %" PRId64 "\n", this,
|
||||
printable(reads[i].begin).c_str(),
|
||||
printable(reads[i].end).c_str(), reads[i].readVersion);
|
||||
}
|
||||
@@ -839,24 +848,27 @@ struct TestDriver {
|
||||
refImpl.check(reads, results2, numPointReads + numRangeReads);
|
||||
}
|
||||
|
||||
auto compareResults = [reads](ConflictSet::Result *results1,
|
||||
ConflictSet::Result *results2, int count) {
|
||||
auto compareResults = [reads, this](ConflictSet::Result *results1,
|
||||
ConflictSet::Result *results2,
|
||||
int count) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
if (results1[i] != results2[i]) {
|
||||
if (reads[i].end.len == 0) {
|
||||
fprintf(stderr,
|
||||
"Expected %s, got %s for read of {%s} at version %" PRId64
|
||||
"\n",
|
||||
resultToStr(results2[i]), resultToStr(results1[i]),
|
||||
printable(reads[i].begin).c_str(), reads[i].readVersion);
|
||||
} else {
|
||||
fprintf(
|
||||
stderr,
|
||||
"Expected %s, got %s for read of [%s, %s) at version %" PRId64
|
||||
"%p Expected %s, got %s for read of {%s} at version %" PRId64
|
||||
"\n",
|
||||
resultToStr(results2[i]), resultToStr(results1[i]),
|
||||
printable(reads[i].begin).c_str(),
|
||||
printable(reads[i].end).c_str(), reads[i].readVersion);
|
||||
(void *)this, resultToStr(results2[i]),
|
||||
resultToStr(results1[i]), printable(reads[i].begin).c_str(),
|
||||
reads[i].readVersion);
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"%p Expected %s, got %s for read of [%s, %s) at version "
|
||||
"%" PRId64 "\n",
|
||||
(void *)this, resultToStr(results2[i]),
|
||||
resultToStr(results1[i]),
|
||||
printable(reads[i].begin).c_str(),
|
||||
printable(reads[i].end).c_str(), reads[i].readVersion);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
4
Jenkinsfile
vendored
4
Jenkinsfile
vendored
@@ -123,8 +123,8 @@ pipeline {
|
||||
'''
|
||||
recordCoverage qualityGates: [[criticality: 'NOTE', metric: 'MODULE']], tools: [[parser: 'COBERTURA', pattern: 'build/coverage.xml']]
|
||||
sh '''
|
||||
# Suppress again, because we haven't dealt with function multi-versioning for x86 yet
|
||||
# gcovr -f ConflictSet.cpp --fail-under-line 100 > /dev/null
|
||||
gcovr -f ConflictSet.cpp
|
||||
gcovr -f ConflictSet.cpp --fail-under-line 100 > /dev/null
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
104
README.md
104
README.md
@@ -1,86 +1,38 @@
|
||||
A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys.
|
||||
|
||||
Intended to replace FoundationDB's skip list.
|
||||
Intended as an alternative to FoundationDB's skip list.
|
||||
|
||||
Hardware for all benchmarks is a mac m1 2020.
|
||||
Hardware for all benchmarks is an AMD Ryzen 9 7900 with (2x32GB) 5600MT/s CL28-34-34-89 1.35V RAM
|
||||
|
||||
# FoundationDB's benchmark
|
||||
# Microbenchmark
|
||||
|
||||
## Skip list
|
||||
|
||||
```
|
||||
New conflict set: 1.957 sec
|
||||
0.639 Mtransactions/sec
|
||||
2.555 Mkeys/sec
|
||||
Detect only: 1.845 sec
|
||||
0.678 Mtransactions/sec
|
||||
2.710 Mkeys/sec
|
||||
Skiplist only: 1.263 sec
|
||||
0.990 Mtransactions/sec
|
||||
3.960 Mkeys/sec
|
||||
Performance counters:
|
||||
Build: 0.0546
|
||||
Add: 0.0563
|
||||
Detect: 1.84
|
||||
D.Sort: 0.412
|
||||
D.Combine: 0.0141
|
||||
D.CheckRead: 0.671
|
||||
D.CheckIntraBatch: 0.0068
|
||||
D.MergeWrite: 0.592
|
||||
D.RemoveBefore: 0.146
|
||||
```
|
||||
| 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`
|
||||
|
||||
## Radix tree (this implementation)
|
||||
|
||||
```
|
||||
New conflict set: 1.366 sec
|
||||
0.915 Mtransactions/sec
|
||||
3.660 Mkeys/sec
|
||||
Detect only: 1.248 sec
|
||||
1.002 Mtransactions/sec
|
||||
4.007 Mkeys/sec
|
||||
Skiplist only: 0.573 sec
|
||||
2.182 Mtransactions/sec
|
||||
8.730 Mkeys/sec
|
||||
Performance counters:
|
||||
Build: 0.0594
|
||||
Add: 0.0572
|
||||
Detect: 1.25
|
||||
D.Sort: 0.418
|
||||
D.Combine: 0.0149
|
||||
D.CheckRead: 0.232
|
||||
D.CheckIntraBatch: 0.0067
|
||||
D.MergeWrite: 0.341
|
||||
D.RemoveBefore: 0.232
|
||||
```
|
||||
|
||||
# Our benchmark
|
||||
|
||||
## Skip list
|
||||
|
||||
| ns/op | op/s | err% | total | benchmark
|
||||
|--------------------:|--------------------:|--------:|----------:|:----------
|
||||
| 245.99 | 4,065,232.81 | 0.3% | 0.01 | `point reads`
|
||||
| 265.93 | 3,760,430.49 | 0.2% | 0.01 | `prefix reads`
|
||||
| 485.30 | 2,060,569.50 | 0.2% | 0.01 | `range reads`
|
||||
| 449.60 | 2,224,195.17 | 0.4% | 0.01 | `point writes`
|
||||
| 441.76 | 2,263,688.18 | 1.1% | 0.01 | `prefix writes`
|
||||
| 245.42 | 4,074,647.54 | 2.4% | 0.02 | `range writes`
|
||||
| 572.80 | 1,745,810.06 | 1.3% | 0.01 | `monotonic increasing point writes`
|
||||
| 154,819.33 | 6,459.14 | 0.9% | 0.01 | `worst case for radix tree`
|
||||
|
||||
## Radix tree (this implementation)
|
||||
|
||||
| ns/op | op/s | err% | total | benchmark
|
||||
|--------------------:|--------------------:|--------:|----------:|:----------
|
||||
| 19.17 | 52,163,930.66 | 0.1% | 0.01 | `point reads`
|
||||
| 23.68 | 42,224,388.21 | 0.7% | 0.01 | `prefix reads`
|
||||
| 63.30 | 15,797,506.06 | 0.9% | 0.01 | `range reads`
|
||||
| 29.66 | 33,720,994.74 | 0.3% | 0.01 | `point writes`
|
||||
| 43.50 | 22,987,781.25 | 1.0% | 0.01 | `prefix writes`
|
||||
| 50.00 | 20,000,000.00 | 0.8% | 0.01 | `range writes`
|
||||
| 103.25 | 9,684,786.47 | 2.9% | 0.01 | `monotonic increasing point writes`
|
||||
| 1,181,500.00 | 846.38 | 2.3% | 0.01 | `worst case for radix tree`
|
||||
| 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`
|
||||
|
||||
# "Real data" test
|
||||
|
||||
@@ -89,13 +41,13 @@ Point queries only, best of three runs. Gc ratio is the ratio of time spent doin
|
||||
## skip list
|
||||
|
||||
```
|
||||
Check: 11.3385 seconds, 329.718 MB/s, Add: 5.35612 seconds, 131.072 MB/s, Gc ratio: 45.7173%
|
||||
Check: 4.47891 seconds, 364.05 MB/s, Add: 4.55599 seconds, 123.058 MB/s, Gc ratio: 37.1145%
|
||||
```
|
||||
|
||||
## radix tree
|
||||
|
||||
```
|
||||
Check: 2.48583 seconds, 1503.93 MB/s, Add: 2.12768 seconds, 329.954 MB/s, Gc ratio: 41.7943%
|
||||
Check: 1.05813 seconds, 1540.97 MB/s, Add: 1.32071 seconds, 424.508 MB/s, Gc ratio: 42.2067%
|
||||
```
|
||||
|
||||
## hash table
|
||||
@@ -103,5 +55,5 @@ Check: 2.48583 seconds, 1503.93 MB/s, Add: 2.12768 seconds, 329.954 MB/s, Gc rat
|
||||
(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: 1.83386 seconds, 2038.6 MB/s, Add: 0.601411 seconds, 1167.32 MB/s, Gc ratio: 48.9776%
|
||||
Check: 0.804094 seconds, 2027.81 MB/s, Add: 0.652952 seconds, 858.645 MB/s, Gc ratio: 35.3885%
|
||||
```
|
||||
|
@@ -778,10 +778,6 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
for (int s = stripes - 1; s >= 0; s--) {
|
||||
for (int i = 0; i * 2 < ss; ++i) {
|
||||
const auto &w = combinedWriteConflictRanges[s * stripeSize / 2 + i];
|
||||
#if DEBUG_VERBOSE
|
||||
printf("Write begin: %s\n", printable(w.begin).c_str());
|
||||
fflush(stdout);
|
||||
#endif
|
||||
values[i * 2] = w.first;
|
||||
values[i * 2 + 1] = w.second;
|
||||
keyUpdates += 3;
|
||||
|
@@ -13,25 +13,58 @@ int main(int argc, char **argv) {
|
||||
std::stringstream buffer;
|
||||
buffer << t.rdbuf();
|
||||
auto str = buffer.str();
|
||||
TestDriver<ConflictSet, !PERF_TEST> driver{(const uint8_t *)str.data(),
|
||||
str.size()};
|
||||
while (!driver.next())
|
||||
;
|
||||
if (!driver.ok) {
|
||||
abort();
|
||||
Arbitrary arbitrary({(const uint8_t *)str.data(), str.size()});
|
||||
TestDriver<ConflictSet, !PERF_TEST> driver1{arbitrary};
|
||||
TestDriver<ConflictSet, !PERF_TEST> driver2{arbitrary};
|
||||
bool done1 = false;
|
||||
bool done2 = false;
|
||||
for (;;) {
|
||||
if (!done1) {
|
||||
done1 = driver1.next();
|
||||
if (!driver1.ok) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (!done2) {
|
||||
done2 = driver2.next();
|
||||
if (!driver2.ok) {
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (done1 && done2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ConflictSet::MetricsV1 *metrics;
|
||||
int metricsCount;
|
||||
driver.cs.getMetricsV1(&metrics, &metricsCount);
|
||||
printf("#################### METRICS FOR %s ####################\n",
|
||||
argv[i]);
|
||||
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());
|
||||
{
|
||||
ConflictSet::MetricsV1 *metrics;
|
||||
int metricsCount;
|
||||
driver1.cs.getMetricsV1(&metrics, &metricsCount);
|
||||
printf("#################### METRICS for ConflictSet 1 for %s "
|
||||
"####################\n",
|
||||
argv[i]);
|
||||
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());
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
{
|
||||
ConflictSet::MetricsV1 *metrics;
|
||||
int metricsCount;
|
||||
driver2.cs.getMetricsV1(&metrics, &metricsCount);
|
||||
printf("#################### METRICS for ConflictSet 2 for %s "
|
||||
"####################\n",
|
||||
argv[i]);
|
||||
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());
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
__aarch64_cas8_relax
|
||||
__aarch64_ldadd8_relax
|
||||
__getauxval@GLIBC_2.17
|
||||
__stack_chk_fail@GLIBC_2.17
|
||||
__stack_chk_guard@GLIBC_2.17
|
||||
|
BIN
corpus/0007f332ccbce5f880942d87fb47bc20032a0016
Normal file
BIN
corpus/0007f332ccbce5f880942d87fb47bc20032a0016
Normal file
Binary file not shown.
BIN
corpus/00227cd64448f052f3fbe97d3163015e9ed7087b
Normal file
BIN
corpus/00227cd64448f052f3fbe97d3163015e9ed7087b
Normal file
Binary file not shown.
BIN
corpus/003c017feb31736884931b849be62d293f056c48
Normal file
BIN
corpus/003c017feb31736884931b849be62d293f056c48
Normal file
Binary file not shown.
BIN
corpus/003f579a8a732e6ebd7a104b3277fd3864053b76
Normal file
BIN
corpus/003f579a8a732e6ebd7a104b3277fd3864053b76
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/0077c650ff07d21c43ddfc40079417e8760e444b
Normal file
BIN
corpus/0077c650ff07d21c43ddfc40079417e8760e444b
Normal file
Binary file not shown.
BIN
corpus/0112c3723c9ab42395c0f74e446998c0c63e8aef
Normal file
BIN
corpus/0112c3723c9ab42395c0f74e446998c0c63e8aef
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/02a897ecff57f621da1ba1ac133b74e1fbb35504
Normal file
BIN
corpus/02a897ecff57f621da1ba1ac133b74e1fbb35504
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/043d4b742d47ab17743046da8d8e4cbc83db2576
Normal file
BIN
corpus/043d4b742d47ab17743046da8d8e4cbc83db2576
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/062ced08788a248ed0a09e6d28a6299abe1773d5
Normal file
BIN
corpus/062ced08788a248ed0a09e6d28a6299abe1773d5
Normal file
Binary file not shown.
BIN
corpus/06b5ef40a3ef94a1fcd6bc3a1fff0e48864aca9a
Normal file
BIN
corpus/06b5ef40a3ef94a1fcd6bc3a1fff0e48864aca9a
Normal file
Binary file not shown.
BIN
corpus/06d8bb9b740017d7e4ce122022542b2e8e2c1427
Normal file
BIN
corpus/06d8bb9b740017d7e4ce122022542b2e8e2c1427
Normal file
Binary file not shown.
BIN
corpus/06e7021fcbe50e9fd239738577bc87e54ac491b2
Normal file
BIN
corpus/06e7021fcbe50e9fd239738577bc87e54ac491b2
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/081a367777aa78bc8db86261f5be1f88046eafc8
Normal file
BIN
corpus/081a367777aa78bc8db86261f5be1f88046eafc8
Normal file
Binary file not shown.
BIN
corpus/082141793d3294fd0f0d2f6c9d2411090dc615c4
Normal file
BIN
corpus/082141793d3294fd0f0d2f6c9d2411090dc615c4
Normal file
Binary file not shown.
BIN
corpus/0846a0fd98deaebbb56359f2375d1dd0e2e5558d
Normal file
BIN
corpus/0846a0fd98deaebbb56359f2375d1dd0e2e5558d
Normal file
Binary file not shown.
BIN
corpus/08732e4de188b7d33f2fa2b6598204d7dcc2cce4
Normal file
BIN
corpus/08732e4de188b7d33f2fa2b6598204d7dcc2cce4
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/0a6ce121c4377c296b9c546d431a6e117920a880
Normal file
BIN
corpus/0a6ce121c4377c296b9c546d431a6e117920a880
Normal file
Binary file not shown.
BIN
corpus/0aaa996798719771b1bfd3fb09c87251dc753c73
Normal file
BIN
corpus/0aaa996798719771b1bfd3fb09c87251dc753c73
Normal file
Binary file not shown.
BIN
corpus/0abee4d75ae69828b768afd5e31e3f495031686b
Normal file
BIN
corpus/0abee4d75ae69828b768afd5e31e3f495031686b
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/0bfa2bc09ac83e2f4da5297ead958f3f06be084a
Normal file
BIN
corpus/0bfa2bc09ac83e2f4da5297ead958f3f06be084a
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/0eaefa9d1c4cb97b3c06427aef61cdf37bde1d21
Normal file
BIN
corpus/0eaefa9d1c4cb97b3c06427aef61cdf37bde1d21
Normal file
Binary file not shown.
BIN
corpus/0ef587f2356c26fac3030bd028d97c8415c3f919
Normal file
BIN
corpus/0ef587f2356c26fac3030bd028d97c8415c3f919
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
5
corpus/0f5c5f28c31e44ee0ec085fec09adf0981065771
Normal file
5
corpus/0f5c5f28c31e44ee0ec085fec09adf0981065771
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
<EFBFBD><EFBFBD>
|
||||
|
||||
|
||||
2
|
BIN
corpus/0f5ffb3f35a973148d984201872f51189c65e008
Normal file
BIN
corpus/0f5ffb3f35a973148d984201872f51189c65e008
Normal file
Binary file not shown.
BIN
corpus/0f6a5e977759d36fb90b813b2c49393b622e92f9
Normal file
BIN
corpus/0f6a5e977759d36fb90b813b2c49393b622e92f9
Normal file
Binary file not shown.
BIN
corpus/0f905983f3a3c63826c1931bf79d57dd4d00256a
Normal file
BIN
corpus/0f905983f3a3c63826c1931bf79d57dd4d00256a
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/0fc993489a75f52dbbffeb823e79e30588649421
Normal file
BIN
corpus/0fc993489a75f52dbbffeb823e79e30588649421
Normal file
Binary file not shown.
BIN
corpus/10f95ef6229d112b9c60421ed30e17b71d3a3bbe
Normal file
BIN
corpus/10f95ef6229d112b9c60421ed30e17b71d3a3bbe
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/12aa5ccf41729754238bbce514f0a42c71778d85
Normal file
BIN
corpus/12aa5ccf41729754238bbce514f0a42c71778d85
Normal file
Binary file not shown.
BIN
corpus/12af911f6fcef6f6d9c0b4bffdce21b08426510c
Normal file
BIN
corpus/12af911f6fcef6f6d9c0b4bffdce21b08426510c
Normal file
Binary file not shown.
1
corpus/12bdd00fd4038756cbcf8ecdad1b0cd862603cd8
Normal file
1
corpus/12bdd00fd4038756cbcf8ecdad1b0cd862603cd8
Normal file
@@ -0,0 +1 @@
|
||||
<EFBFBD>
|
BIN
corpus/13250d5d83ddcd78bdee76819457b1ac8325e832
Normal file
BIN
corpus/13250d5d83ddcd78bdee76819457b1ac8325e832
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/134ae20630757b82a98cd51995e5e873658a77bd
Normal file
BIN
corpus/134ae20630757b82a98cd51995e5e873658a77bd
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/13685939a2bf2856e4d456b3ebd3ae80c60a5a89
Normal file
BIN
corpus/13685939a2bf2856e4d456b3ebd3ae80c60a5a89
Normal file
Binary file not shown.
BIN
corpus/13e9947558401750276e831e41e8d20fbbc43c38
Normal file
BIN
corpus/13e9947558401750276e831e41e8d20fbbc43c38
Normal file
Binary file not shown.
BIN
corpus/146251930843d0de92324ac7c2440c28114f8686
Normal file
BIN
corpus/146251930843d0de92324ac7c2440c28114f8686
Normal file
Binary file not shown.
BIN
corpus/1480a39f104e51c35070d117a8874dbed05c3192
Normal file
BIN
corpus/1480a39f104e51c35070d117a8874dbed05c3192
Normal file
Binary file not shown.
BIN
corpus/1495ce19b61c21a9afeba91bdd6d28668726d629
Normal file
BIN
corpus/1495ce19b61c21a9afeba91bdd6d28668726d629
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/1686662b70c89952ef195ddea713381eff5cff61
Normal file
BIN
corpus/1686662b70c89952ef195ddea713381eff5cff61
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/1779d74cb71b98f654d769c860c13d07303bb91a
Normal file
BIN
corpus/1779d74cb71b98f654d769c860c13d07303bb91a
Normal file
Binary file not shown.
BIN
corpus/17807a96f622ee8ed4bf30436f519ff64d107c66
Normal file
BIN
corpus/17807a96f622ee8ed4bf30436f519ff64d107c66
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/18465140630efdf18334db5be8cba958ad18c690
Normal file
BIN
corpus/18465140630efdf18334db5be8cba958ad18c690
Normal file
Binary file not shown.
BIN
corpus/1852f648f4f9057f97a4fb33a6878e1877037473
Normal file
BIN
corpus/1852f648f4f9057f97a4fb33a6878e1877037473
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/1a17ced47b4b9ede6abe15f2eafb022d76bcfb95
Normal file
BIN
corpus/1a17ced47b4b9ede6abe15f2eafb022d76bcfb95
Normal file
Binary file not shown.
BIN
corpus/1a9d532641a2a6e2d273248551117f3ca9e8ff33
Normal file
BIN
corpus/1a9d532641a2a6e2d273248551117f3ca9e8ff33
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/1c1094a1e9c0b0b68ac37ea341ab90189f6e7fa6
Normal file
BIN
corpus/1c1094a1e9c0b0b68ac37ea341ab90189f6e7fa6
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/1d24ad7169dd2551a53ea45fdc6e3e776b90c9a1
Normal file
BIN
corpus/1d24ad7169dd2551a53ea45fdc6e3e776b90c9a1
Normal file
Binary file not shown.
Binary file not shown.
BIN
corpus/1e5a1ac450d7ff49eb6cdb8c2b654d1083f40119
Normal file
BIN
corpus/1e5a1ac450d7ff49eb6cdb8c2b654d1083f40119
Normal file
Binary file not shown.
BIN
corpus/1e67153b33280c8a6f06619a2fb6cb535a025a5b
Normal file
BIN
corpus/1e67153b33280c8a6f06619a2fb6cb535a025a5b
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
corpus/1f6162dc7f472bdb6f2efe5e124183f3556bb37d
Normal file
BIN
corpus/1f6162dc7f472bdb6f2efe5e124183f3556bb37d
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