4 Commits

Author SHA1 Message Date
309d315956 Add DebugConflictSet, which asserts using skip list as a reference
Some checks failed
Tests / Clang total: 1090, passed: 1090
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1090, passed: 1090
Tests / Release [gcc] total: 1090, passed: 1090
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 818, failed: 1, passed: 817
Tests / Coverage total: 817, passed: 817
weaselab/conflict-set/pipeline/head There was a failure building this commit
CC #23
2024-04-17 12:08:39 -07:00
eab2e46a56 Mention that we modified SkipList.cpp 2024-04-17 12:08:33 -07:00
85db1a8786 Allow to choose implementation in python wrapper
And fix a few minor bugs to make the python tests pass for skip_list.

CC #23
2024-04-17 12:08:28 -07:00
717f9d6829 Remove ScriptTest.cpp, replace with test_conflict_set.py
CC #23
2024-04-17 12:08:08 -07:00
13 changed files with 192 additions and 1065 deletions

View File

@@ -261,13 +261,14 @@ if(BUILD_TESTING)
# scripted tests. Written manually to fill in anything libfuzzer couldn't # scripted tests. Written manually to fill in anything libfuzzer couldn't
# find. # find.
add_executable(script_test ScriptTest.cpp) find_package(Python3 REQUIRED COMPONENTS Interpreter)
target_compile_options(script_test PRIVATE ${TEST_FLAGS}) execute_process(
target_link_libraries(script_test PRIVATE ${PROJECT_NAME}) COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/test_conflict_set.py list
file(GLOB SCRIPT_TESTS ${CMAKE_SOURCE_DIR}/script_tests/*) OUTPUT_VARIABLE SCRIPT_TESTS)
foreach(TEST ${SCRIPT_TESTS}) foreach(TEST ${SCRIPT_TESTS})
get_filename_component(name ${TEST} NAME) add_test(NAME script_test_${TEST}
add_test(NAME conflict_set_script_${name} COMMAND script_test ${TEST}) COMMAND ${Python3_EXECUTABLE}
${CMAKE_SOURCE_DIR}/test_conflict_set.py test ${TEST})
endforeach() endforeach()
find_program(VALGRIND_EXE valgrind) find_program(VALGRIND_EXE valgrind)

View File

@@ -2510,6 +2510,10 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
} }
explicit Impl(int64_t oldestVersion) : oldestVersion(oldestVersion) { explicit Impl(int64_t oldestVersion) : oldestVersion(oldestVersion) {
#if DEBUG_VERBOSE
fprintf(stderr, "radix_tree: create\n");
#endif
// Insert "" // Insert ""
root = allocators.node0.allocate(0); root = allocators.node0.allocate(0);
root->numChildren = 0; root->numChildren = 0;
@@ -2524,7 +2528,12 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
root->entry.pointVersion = oldestVersion; root->entry.pointVersion = oldestVersion;
root->entry.rangeVersion = oldestVersion; root->entry.rangeVersion = oldestVersion;
} }
~Impl() { destroyTree(root); } ~Impl() {
#if DEBUG_VERBOSE
fprintf(stderr, "radix_tree: destroy\n");
#endif
destroyTree(root);
}
NodeAllocators allocators; NodeAllocators allocators;
@@ -2647,17 +2656,27 @@ ConflictSet_check(void *cs, const ConflictSet_ReadRange *reads,
__attribute__((__visibility__("default"))) void __attribute__((__visibility__("default"))) void
ConflictSet_addWrites(void *cs, const ConflictSet_WriteRange *writes, int count, ConflictSet_addWrites(void *cs, const ConflictSet_WriteRange *writes, int count,
int64_t writeVersion) { int64_t writeVersion) {
auto *impl = ((ConflictSet::Impl *)cs); auto *impl = (ConflictSet::Impl *)cs;
mallocBytesDelta = 0; mallocBytesDelta = 0;
impl->addWrites(writes, count, writeVersion); impl->addWrites(writes, count, writeVersion);
impl->totalBytes += mallocBytesDelta; impl->totalBytes += mallocBytesDelta;
#if SHOW_MEMORY
if (impl->totalBytes != mallocBytes) {
abort();
}
#endif
} }
__attribute__((__visibility__("default"))) void __attribute__((__visibility__("default"))) void
ConflictSet_setOldestVersion(void *cs, int64_t oldestVersion) { ConflictSet_setOldestVersion(void *cs, int64_t oldestVersion) {
auto *impl = ((ConflictSet::Impl *)cs); auto *impl = (ConflictSet::Impl *)cs;
mallocBytesDelta = 0; mallocBytesDelta = 0;
impl->setOldestVersion(oldestVersion); impl->setOldestVersion(oldestVersion);
impl->totalBytes += mallocBytesDelta; impl->totalBytes += mallocBytesDelta;
#if SHOW_MEMORY
if (impl->totalBytes != mallocBytes) {
abort();
}
#endif
} }
__attribute__((__visibility__("default"))) void * __attribute__((__visibility__("default"))) void *
ConflictSet_create(int64_t oldestVersion) { ConflictSet_create(int64_t oldestVersion) {
@@ -2995,6 +3014,7 @@ void removeKey(Node *n) {
struct __attribute__((visibility("default"))) PeakPrinter { struct __attribute__((visibility("default"))) PeakPrinter {
~PeakPrinter() { ~PeakPrinter() {
printf("--- radix_tree ---\n");
printf("malloc bytes: %g\n", double(mallocBytes)); printf("malloc bytes: %g\n", double(mallocBytes));
printf("Peak malloc bytes: %g\n", double(peakMallocBytes)); printf("Peak malloc bytes: %g\n", double(peakMallocBytes));
printf("Node bytes: %g\n", double(nodeBytes)); printf("Node bytes: %g\n", double(nodeBytes));

View File

@@ -1,155 +0,0 @@
#include "Internal.h"
#include <ConflictSet.h>
#include <chrono>
#include <cstring>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
inline size_t getPageSize() {
static size_t kPageSize = sysconf(_SC_PAGESIZE);
return kPageSize;
}
/// Helper for rounding up to page size (or some other alignment)
constexpr inline size_t rightAlign(size_t offset, size_t alignment) {
return offset % alignment == 0 ? offset
: ((offset / alignment) + 1) * alignment;
}
using StringView = std::basic_string_view<uint8_t>;
inline StringView operator"" _v(const char *str, size_t size) {
return {reinterpret_cast<const uint8_t *>(str), size};
}
int main(int argc, const char **argv) {
ConflictSet cs{0};
ReferenceImpl ref{0};
for (int i = 1; i < argc; ++i) {
int fd = open(argv[i], O_RDONLY);
struct stat st;
if (fstat(fd, &st) == -1) {
int err = errno;
fprintf(stderr, "stat error %s - %s\n", argv[i], strerror(err));
fflush(stderr);
abort();
}
int64_t size = rightAlign(st.st_size, getPageSize());
const uint8_t *begin =
(uint8_t *)mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);
madvise((void *)begin, size, MADV_SEQUENTIAL);
auto *const mapOriginal = begin;
const auto sizeOriginal = size;
StringView b;
StringView e;
int64_t v = 0;
int64_t lastWriteVersion = 0;
int64_t lastOldestVersion = 0;
std::vector<ConflictSet::WriteRange> writeRanges;
std::vector<ConflictSet::ReadRange> readRanges;
std::vector<ConflictSet::Result> results;
for (uint8_t *end = (uint8_t *)memchr(begin, '\n', size); end != nullptr;) {
StringView line{begin, static_cast<size_t>(end - begin)};
size -= end - begin + 1;
begin = end + 1;
end = (uint8_t *)memchr(begin, '\n', size);
if (line.starts_with("begin"_v)) {
b = line.substr("begin "_v.size(), line.size());
printf("b <- %.*s\n", int(b.size()), b.data());
} else if (line.starts_with("end"_v)) {
e = line.substr("end "_v.size(), line.size());
printf("e <- %.*s\n", int(e.size()), e.data());
} else if (line.starts_with("version"_v)) {
line = line.substr("version "_v.size(), line.size());
v = 0;
for (auto c : line) {
v = v * 10 + int(c) - int('0');
}
printf("v <- %" PRId64 "\n", v);
} else if (line.starts_with("pointread"_v)) {
printf("pointread\n");
ConflictSet::ReadRange r;
r.begin.p = b.data();
r.begin.len = b.size();
r.end.len = 0;
r.readVersion = v;
readRanges.push_back(r);
} else if (line.starts_with("pointwrite"_v)) {
printf("pointwrite\n");
assert(writeRanges.empty() ||
(writeRanges.back().end.len == 0 ? writeRanges.back().begin
: writeRanges.back().end) < b);
ConflictSet::WriteRange w;
w.begin.p = b.data();
w.begin.len = b.size();
w.end.len = 0;
writeRanges.push_back(w);
} else if (line.starts_with("rangeread"_v)) {
printf("rangeread\n");
ConflictSet::ReadRange r;
r.begin.p = b.data();
r.begin.len = b.size();
r.end.p = e.data();
r.end.len = e.size();
r.readVersion = v;
readRanges.push_back(r);
} else if (line.starts_with("rangewrite"_v)) {
printf("rangewrite\n");
assert(b < e);
assert(writeRanges.empty() ||
(writeRanges.back().end.len == 0 ? writeRanges.back().begin
: writeRanges.back().end) < b);
ConflictSet::WriteRange w;
w.begin.p = b.data();
w.begin.len = b.size();
w.end.p = e.data();
w.end.len = e.size();
writeRanges.push_back(w);
} else if (line.starts_with("check"_v)) {
printf("check\n");
Arena arena;
auto *expected = new (arena) ConflictSet::Result[readRanges.size()];
auto *actual = new (arena) ConflictSet::Result[readRanges.size()];
ref.check(readRanges.data(), expected, readRanges.size());
cs.check(readRanges.data(), actual, readRanges.size());
for (int i = 0; i < int(readRanges.size()); ++i) {
if (expected[i] != actual[i]) {
fprintf(stderr, "Expected %s, got %s at index %d\n",
resultToStr(expected[i]), resultToStr(actual[i]), i);
return 1;
}
}
readRanges = {};
} else if (line.starts_with("addwrites"_v)) {
printf("addwrites\n");
assert(v > lastWriteVersion);
lastWriteVersion = v;
cs.addWrites(writeRanges.data(), writeRanges.size(), v);
ref.addWrites(writeRanges.data(), writeRanges.size(), v);
writeRanges = {};
} else if (line.starts_with("setoldest"_v)) {
printf("setoldest\n");
assert(v > lastOldestVersion);
lastOldestVersion = v;
cs.setOldestVersion(v);
ref.setOldestVersion(v);
} else if (line.empty() || line.starts_with(";"_v)) {
// skip
} else {
printf("Unrecognized line: %.*s\n", int(line.size()), line.data());
}
}
munmap((void *)mapOriginal, sizeOriginal);
close(fd);
}
}

View File

@@ -16,6 +16,8 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*
* This source code is modified to compile outside of FoundationDB
*/ */
#include "ConflictSet.h" #include "ConflictSet.h"
@@ -268,13 +270,21 @@ public:
} }
explicit SkipList(Version version = 0) { explicit SkipList(Version version = 0) {
#if DEBUG_VERBOSE
fprintf(stderr, "skip_list: create\n");
#endif
header = Node::create(StringRef(), MaxLevels - 1); header = Node::create(StringRef(), MaxLevels - 1);
for (int l = 0; l < MaxLevels; l++) { for (int l = 0; l < MaxLevels; l++) {
header->setNext(l, nullptr); header->setNext(l, nullptr);
header->setMaxVersion(l, version); header->setMaxVersion(l, version);
} }
} }
~SkipList() { destroy(); } ~SkipList() {
#if DEBUG_VERBOSE
fprintf(stderr, "skip_list: destroy\n");
#endif
destroy();
}
SkipList(SkipList &&other) noexcept : header(other.header) { SkipList(SkipList &&other) noexcept : header(other.header) {
other.header = nullptr; other.header = nullptr;
} }
@@ -702,16 +712,35 @@ ConflictSet_check(void *cs, const ConflictSet_ReadRange *reads,
__attribute__((__visibility__("default"))) void __attribute__((__visibility__("default"))) void
ConflictSet_addWrites(void *cs, const ConflictSet_WriteRange *writes, int count, ConflictSet_addWrites(void *cs, const ConflictSet_WriteRange *writes, int count,
int64_t writeVersion) { int64_t writeVersion) {
((ConflictSet::Impl *)cs)->addWrites(writes, count, writeVersion); auto *impl = (ConflictSet::Impl *)cs;
mallocBytesDelta = 0;
impl->addWrites(writes, count, writeVersion);
impl->totalBytes += mallocBytesDelta;
#if SHOW_MEMORY
if (impl->totalBytes != mallocBytes) {
abort();
}
#endif
} }
__attribute__((__visibility__("default"))) void __attribute__((__visibility__("default"))) void
ConflictSet_setOldestVersion(void *cs, int64_t oldestVersion) { ConflictSet_setOldestVersion(void *cs, int64_t oldestVersion) {
((ConflictSet::Impl *)cs)->setOldestVersion(oldestVersion); auto *impl = (ConflictSet::Impl *)cs;
mallocBytesDelta = 0;
impl->setOldestVersion(oldestVersion);
impl->totalBytes += mallocBytesDelta;
#if SHOW_MEMORY
if (impl->totalBytes != mallocBytes) {
abort();
}
#endif
} }
__attribute__((__visibility__("default"))) void * __attribute__((__visibility__("default"))) void *
ConflictSet_create(int64_t oldestVersion) { ConflictSet_create(int64_t oldestVersion) {
return new (safe_malloc(sizeof(ConflictSet::Impl))) mallocBytesDelta = 0;
auto *result = new (safe_malloc(sizeof(ConflictSet::Impl)))
ConflictSet::Impl{oldestVersion}; ConflictSet::Impl{oldestVersion};
result->totalBytes += mallocBytesDelta;
return result;
} }
__attribute__((__visibility__("default"))) void ConflictSet_destroy(void *cs) { __attribute__((__visibility__("default"))) void ConflictSet_destroy(void *cs) {
using Impl = ConflictSet::Impl; using Impl = ConflictSet::Impl;
@@ -728,6 +757,7 @@ ConflictSet_getBytes(void *cs) {
#if SHOW_MEMORY #if SHOW_MEMORY
struct __attribute__((visibility("default"))) PeakPrinter { struct __attribute__((visibility("default"))) PeakPrinter {
~PeakPrinter() { ~PeakPrinter() {
printf("--- skip_list ---\n");
printf("malloc bytes: %g\n", double(mallocBytes)); printf("malloc bytes: %g\n", double(mallocBytes));
printf("Peak malloc bytes: %g\n", double(peakMallocBytes)); printf("Peak malloc bytes: %g\n", double(peakMallocBytes));
} }

View File

@@ -4,22 +4,6 @@ import os
from typing import Optional from typing import Optional
_lib = None
for f in (
os.path.dirname(__file__) + "/build/radix_tree/libconflict-set.so.0",
os.path.dirname(__file__) + "/build/radix_tree/libconflict-set.0.dylib",
):
try:
_lib = ctypes.cdll.LoadLibrary(f)
except:
pass
if _lib is None:
import sys
print("Could not find libconflict-set", file=sys.stderr)
sys.exit(1)
class _Key(ctypes.Structure): class _Key(ctypes.Structure):
_fields_ = [("p", ctypes.POINTER(ctypes.c_ubyte)), ("len", ctypes.c_int)] _fields_ = [("p", ctypes.POINTER(ctypes.c_ubyte)), ("len", ctypes.c_int)]
@@ -37,31 +21,6 @@ class WriteRange(ctypes.Structure):
_fields_ = [("begin", _Key), ("end", _Key)] _fields_ = [("begin", _Key), ("end", _Key)]
_lib.ConflictSet_create.argtypes = (ctypes.c_int64,)
_lib.ConflictSet_create.restype = ctypes.c_void_p
_lib.ConflictSet_check.argtypes = (
ctypes.c_void_p,
ctypes.POINTER(ReadRange),
ctypes.POINTER(ctypes.c_int),
ctypes.c_int,
)
_lib.ConflictSet_addWrites.argtypes = (
ctypes.c_void_p,
ctypes.POINTER(WriteRange),
ctypes.c_int,
ctypes.c_int64,
)
_lib.ConflictSet_setOldestVersion.argtypes = (ctypes.c_void_p, ctypes.c_int64)
_lib.ConflictSet_destroy.argtypes = (ctypes.c_void_p,)
_lib.ConflictSet_getBytes.argtypes = (ctypes.c_void_p,)
_lib.ConflictSet_getBytes.restype = ctypes.c_int64
class Result(enum.Enum): class Result(enum.Enum):
COMMIT = 0 COMMIT = 0
CONFLICT = 1 CONFLICT = 1
@@ -93,34 +52,86 @@ def read(version: int, begin: bytes, end: Optional[bytes] = None) -> ReadRange:
class ConflictSet: class ConflictSet:
def __init__(self, version: int = 0) -> None: def __init__(self, version: int = 0, implementation: Optional[str] = None) -> None:
self.p = _lib.ConflictSet_create(version) self._lib = None
if implementation is None:
implementation = "radix_tree"
for f in (
os.path.dirname(__file__)
+ "/build/"
+ implementation
+ "/libconflict-set.so.0",
os.path.dirname(__file__)
+ "/build/"
+ implementation
+ "/libconflict-set.0.dylib",
):
try:
self._lib = ctypes.cdll.LoadLibrary(f)
except:
pass
if self._lib is None:
import sys
print(
"Could not find libconflict-set implementation " + implementation,
file=sys.stderr,
)
sys.exit(1)
self._lib.ConflictSet_create.argtypes = (ctypes.c_int64,)
self._lib.ConflictSet_create.restype = ctypes.c_void_p
self._lib.ConflictSet_check.argtypes = (
ctypes.c_void_p,
ctypes.POINTER(ReadRange),
ctypes.POINTER(ctypes.c_int),
ctypes.c_int,
)
self._lib.ConflictSet_addWrites.argtypes = (
ctypes.c_void_p,
ctypes.POINTER(WriteRange),
ctypes.c_int,
ctypes.c_int64,
)
self._lib.ConflictSet_setOldestVersion.argtypes = (
ctypes.c_void_p,
ctypes.c_int64,
)
self._lib.ConflictSet_destroy.argtypes = (ctypes.c_void_p,)
self._lib.ConflictSet_getBytes.argtypes = (ctypes.c_void_p,)
self._lib.ConflictSet_getBytes.restype = ctypes.c_int64
self.p = self._lib.ConflictSet_create(version)
def addWrites(self, version: int, *writes: WriteRange): def addWrites(self, version: int, *writes: WriteRange):
_lib.ConflictSet_addWrites( self._lib.ConflictSet_addWrites(
self.p, (WriteRange * len(writes))(*writes), len(writes), version self.p, (WriteRange * len(writes))(*writes), len(writes), version
) )
def check(self, *reads: ReadRange) -> list[Result]: def check(self, *reads: ReadRange) -> list[Result]:
r = (ctypes.c_int * len(reads))() r = (ctypes.c_int * len(reads))()
_lib.ConflictSet_check(self.p, *reads, r, 1) self._lib.ConflictSet_check(self.p, *reads, r, 1)
return [Result(x) for x in r] return [Result(x) for x in r]
def setOldestVersion(self, version: int) -> None: def setOldestVersion(self, version: int) -> None:
_lib.ConflictSet_setOldestVersion(self.p, version) self._lib.ConflictSet_setOldestVersion(self.p, version)
def getBytes(self) -> int: def getBytes(self) -> int:
return _lib.ConflictSet_getBytes(self.p) return self._lib.ConflictSet_getBytes(self.p)
def __enter__(self): def __enter__(self):
return self return self
def close(self) -> None: def close(self) -> None:
if self.p is not None: if self.p is not None:
_lib.ConflictSet_destroy(self.p) self._lib.ConflictSet_destroy(self.p)
self.p = None self.p = None
def __exit__(self, exception_type, exception_value, exception_traceback): def __exit__(self, exception_type, exception_value, exception_traceback):
if self.p is not None: self.close()
_lib.ConflictSet_destroy(self.p)
self.p = None

View File

@@ -1,262 +0,0 @@
; Create a node with a large partial key capacity
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
pointwrite
; Make it a Node256
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaA
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaB
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaC
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaD
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaE
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaF
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaG
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaH
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaI
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaJ
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaK
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaL
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaM
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaN
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaO
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaP
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaQ
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaR
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaS
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaT
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaU
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaV
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaW
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaX
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaY
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaZ
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaai
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaak
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaam
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaap
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaq
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaat
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaau
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaav
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaw
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaax
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz
pointwrite
version 1
addwrites
; Lower its partial key length
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
pointwrite
version 2
addwrites
; Create work for setoldest
begin x
end y
rangewrite
version 3
addwrites
rangewrite
version 4
addwrites
rangewrite
version 5
addwrites
rangewrite
version 6
addwrites
rangewrite
version 7
addwrites
rangewrite
version 8
addwrites
rangewrite
version 9
addwrites
rangewrite
version 10
addwrites
rangewrite
version 11
addwrites
rangewrite
version 12
addwrites
rangewrite
version 13
addwrites
rangewrite
version 14
addwrites
rangewrite
version 15
addwrites
rangewrite
version 16
addwrites
rangewrite
version 17
addwrites
rangewrite
version 18
addwrites
rangewrite
version 19
addwrites
rangewrite
version 20
addwrites
rangewrite
version 21
addwrites
rangewrite
version 22
addwrites
rangewrite
version 23
addwrites
version 1
setoldest

View File

@@ -1,147 +0,0 @@
; Create a node with a large partial key capacity
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0
pointwrite
; Make it a Node48
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaae
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaf
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaai
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaj
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaak
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaal
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaam
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaan
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaao
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaap
pointwrite
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaq
pointwrite
version 2
addwrites
; Lower its partial key length
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
pointwrite
version 3
addwrites
; Create work for setoldest
begin x
end y
rangewrite
version 4
addwrites
rangewrite
version 5
addwrites
rangewrite
version 6
addwrites
rangewrite
version 7
addwrites
rangewrite
version 8
addwrites
rangewrite
version 9
addwrites
rangewrite
version 10
addwrites
rangewrite
version 11
addwrites
rangewrite
version 12
addwrites
rangewrite
version 13
addwrites
rangewrite
version 14
addwrites
rangewrite
version 15
addwrites
rangewrite
version 16
addwrites
rangewrite
version 17
addwrites
rangewrite
version 18
addwrites
rangewrite
version 19
addwrites
rangewrite
version 20
addwrites
rangewrite
version 21
addwrites
rangewrite
version 22
addwrites
version 1
setoldest

View File

@@ -1,124 +0,0 @@
begin
pointwrite
begin 0
pointwrite
begin 00
pointwrite
begin 00A
pointwrite
begin 00B
pointwrite
begin 00C
pointwrite
begin 00D
pointwrite
begin 00E
pointwrite
begin 00F
pointwrite
begin 00G
pointwrite
begin 00H
pointwrite
begin 00I
pointwrite
begin 00J
pointwrite
begin 00K
pointwrite
begin 00L
pointwrite
begin 00M
pointwrite
begin 00N
pointwrite
begin 00O
pointwrite
begin 00P
pointwrite
begin 00Q
pointwrite
begin 00R
pointwrite
begin 00S
pointwrite
begin 00T
pointwrite
begin 00U
pointwrite
begin 00V
pointwrite
begin 00W
pointwrite
begin 00X
pointwrite
begin 00Y
pointwrite
begin 00Z
pointwrite
begin 00a
pointwrite
begin 00b
pointwrite
begin 00c
pointwrite
begin 00d
pointwrite
begin 00e
pointwrite
begin 00f
pointwrite
begin 00g
pointwrite
begin 00h
pointwrite
begin 00i
pointwrite
begin 00j
pointwrite
begin 00k
pointwrite
begin 00l
pointwrite
begin 00m
pointwrite
begin 00n
pointwrite
begin 00o
pointwrite
begin 00p
pointwrite
begin 00q
pointwrite
begin 00r
pointwrite
begin 00s
pointwrite
begin 00t
pointwrite
begin 00u
pointwrite
begin 00v
pointwrite
begin 00w
pointwrite
begin 00x
pointwrite
begin 00y
pointwrite
begin 00z
pointwrite
version 1
addwrites
begin 0
end 000
rangewrite
version 2
addwrites
begin
end 00
rangewrite
version 3
addwrites

View File

@@ -1,72 +0,0 @@
begin
pointwrite
begin 0
pointwrite
begin 00
pointwrite
begin 00a
pointwrite
begin 00b
pointwrite
begin 00c
pointwrite
begin 00d
pointwrite
begin 00e
pointwrite
begin 00f
pointwrite
begin 00g
pointwrite
begin 00h
pointwrite
begin 00i
pointwrite
begin 00j
pointwrite
begin 00k
pointwrite
begin 00l
pointwrite
begin 00m
pointwrite
begin 00n
pointwrite
begin 00o
pointwrite
begin 00p
pointwrite
begin 00q
pointwrite
begin 00r
pointwrite
begin 00s
pointwrite
begin 00t
pointwrite
begin 00u
pointwrite
begin 00v
pointwrite
begin 00w
pointwrite
begin 00x
pointwrite
begin 00y
pointwrite
begin 00z
pointwrite
version 1
addwrites
begin 0
end 000
rangewrite
version 2
addwrites
begin
end 00
rangewrite
version 3
addwrites

View File

@@ -1,9 +0,0 @@
begin aa
pointwrite
version 1
addwrites
begin aa
end bb
version 0
rangeread
check

View File

@@ -1,212 +0,0 @@
; insert \x3fa at version 1
begin ?a
pointwrite
; insert \x81a at version 1
begin a
pointwrite
version 1
addwrites
; insert [\x40-\x80]a at version 2
begin @a
pointwrite
begin Aa
pointwrite
begin Ba
pointwrite
begin Ca
pointwrite
begin Da
pointwrite
begin Ea
pointwrite
begin Fa
pointwrite
begin Ga
pointwrite
begin Ha
pointwrite
begin Ia
pointwrite
begin Ja
pointwrite
begin Ka
pointwrite
begin La
pointwrite
begin Ma
pointwrite
begin Na
pointwrite
begin Oa
pointwrite
begin Pa
pointwrite
begin Qa
pointwrite
begin Ra
pointwrite
begin Sa
pointwrite
begin Ta
pointwrite
begin Ua
pointwrite
begin Va
pointwrite
begin Wa
pointwrite
begin Xa
pointwrite
begin Ya
pointwrite
begin Za
pointwrite
begin [a
pointwrite
begin \a
pointwrite
begin ]a
pointwrite
begin ^a
pointwrite
begin _a
pointwrite
begin `a
pointwrite
begin aa
pointwrite
begin ba
pointwrite
begin ca
pointwrite
begin da
pointwrite
begin ea
pointwrite
begin fa
pointwrite
begin ga
pointwrite
begin ha
pointwrite
begin ia
pointwrite
begin ja
pointwrite
begin ka
pointwrite
begin la
pointwrite
begin ma
pointwrite
begin na
pointwrite
begin oa
pointwrite
begin pa
pointwrite
begin qa
pointwrite
begin ra
pointwrite
begin sa
pointwrite
begin ta
pointwrite
begin ua
pointwrite
begin va
pointwrite
begin wa
pointwrite
begin xa
pointwrite
begin ya
pointwrite
begin za
pointwrite
begin {a
pointwrite
begin |a
pointwrite
begin }a
pointwrite
begin ~a
pointwrite
begin a
pointwrite
version 2
addwrites
; readrange a superset at version 1
begin !
end ‚
version 1
rangeread
check

View File

@@ -1,19 +0,0 @@
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
end aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
rangeread
check
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
end aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazaaaaaaaaaaaaaaaaaaaaaab
rangeread
check
begin aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
end aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaa
rangeread
check
begin aaaaaaaaaa
end aaaaaaabaa
rangeread
check

View File

@@ -1,8 +1,45 @@
from conflict_set import * from conflict_set import *
class DebugConflictSet:
"""
Bisimulates the skip list and radix tree conflict sets for testing purposes
"""
def __init__(self, version: int = 0) -> None:
self.skip_list = ConflictSet(version, implementation="skip_list")
self.radix_tree = ConflictSet(version, implementation="radix_tree")
def addWrites(self, version: int, *writes: WriteRange):
self.skip_list.addWrites(version, *writes)
self.radix_tree.addWrites(version, *writes)
def check(self, *reads: ReadRange) -> list[Result]:
expected = self.skip_list.check(*reads)
actual = self.radix_tree.check(*reads)
assert expected == actual
return actual
def setOldestVersion(self, version: int) -> None:
self.skip_list.setOldestVersion(version)
self.radix_tree.setOldestVersion(version)
def getBytes(self) -> int:
return self.radix_tree.getBytes()
def __enter__(self):
return self
def close(self) -> None:
self.skip_list.close()
self.radix_tree.close()
def __exit__(self, exception_type, exception_value, exception_traceback):
self.close()
def test_conflict_set(): def test_conflict_set():
with ConflictSet() as cs: with DebugConflictSet() as cs:
before = cs.getBytes() before = cs.getBytes()
key = b"a key" key = b"a key"
cs.addWrites(1, write(key)) cs.addWrites(1, write(key))
@@ -10,3 +47,31 @@ def test_conflict_set():
assert cs.check(read(0, key)) == [Result.CONFLICT] assert cs.check(read(0, key)) == [Result.CONFLICT]
cs.setOldestVersion(1) cs.setOldestVersion(1)
assert cs.check(read(0, key)) == [Result.TOO_OLD] assert cs.check(read(0, key)) == [Result.TOO_OLD]
if __name__ == "__main__":
# budget "pytest" for ctest integration without pulling in a dependency. You can of course still use pytest in local development.
import argparse
import inspect
import sys
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="command")
list_parser = subparsers.add_parser("list")
test_parser = subparsers.add_parser("test")
test_parser.add_argument("test")
args = parser.parse_args()
if args.command == "list":
sys.stdout.write(
";".join(
name[5:]
for name in dir()
if name.startswith("test_")
and inspect.isfunction(getattr(sys.modules[__name__], name))
)
)
elif args.command == "test":
globals()["test_" + args.test]()