Fix conflict_set.py bug, and add full inner words test
All checks were successful
Tests / Clang total: 1091, passed: 1091
Clang |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Tests / SIMD fallback total: 1091, passed: 1091
Tests / Release [gcc] total: 1091, passed: 1091
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 817, passed: 817
Tests / Coverage total: 818, passed: 818
weaselab/conflict-set/pipeline/head This commit looks good
All checks were successful
Tests / Clang total: 1091, passed: 1091
Clang |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Tests / SIMD fallback total: 1091, passed: 1091
Tests / Release [gcc] total: 1091, passed: 1091
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 817, passed: 817
Tests / Coverage total: 818, passed: 818
weaselab/conflict-set/pipeline/head This commit looks good
Apparently all bytes were 0
This commit is contained in:
@@ -267,9 +267,10 @@ if(BUILD_TESTING)
|
|||||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/test_conflict_set.py
|
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/test_conflict_set.py
|
||||||
list OUTPUT_VARIABLE SCRIPT_TESTS)
|
list OUTPUT_VARIABLE SCRIPT_TESTS)
|
||||||
foreach(TEST ${SCRIPT_TESTS})
|
foreach(TEST ${SCRIPT_TESTS})
|
||||||
add_test(NAME script_test_${TEST}
|
add_test(
|
||||||
COMMAND ${Python3_EXECUTABLE}
|
NAME script_test_${TEST}
|
||||||
${CMAKE_SOURCE_DIR}/test_conflict_set.py test ${TEST})
|
COMMAND ${Python3_EXECUTABLE} ${CMAKE_SOURCE_DIR}/test_conflict_set.py
|
||||||
|
test ${TEST} --build-dir ${CMAKE_BINARY_DIR})
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@@ -613,6 +613,10 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
|||||||
for (int s = stripes - 1; s >= 0; s--) {
|
for (int s = stripes - 1; s >= 0; s--) {
|
||||||
for (int i = 0; i * 2 < ss; ++i) {
|
for (int i = 0; i * 2 < ss; ++i) {
|
||||||
const auto &w = writes[s * stripeSize / 2 + i];
|
const auto &w = writes[s * stripeSize / 2 + i];
|
||||||
|
#if DEBUG_VERBOSE
|
||||||
|
printf("Write begin: %s\n", printable(w.begin).c_str());
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
values[i * 2] = {w.begin.p, size_t(w.begin.len)};
|
values[i * 2] = {w.begin.p, size_t(w.begin.len)};
|
||||||
values[i * 2 + 1] = w.end.len > 0
|
values[i * 2 + 1] = w.end.len > 0
|
||||||
? StringRef{w.end.p, size_t(w.end.len)}
|
? StringRef{w.end.p, size_t(w.end.len)}
|
||||||
|
@@ -28,39 +28,38 @@ class Result(enum.Enum):
|
|||||||
|
|
||||||
|
|
||||||
def write(begin: bytes, end: Optional[bytes] = None) -> WriteRange:
|
def write(begin: bytes, end: Optional[bytes] = None) -> WriteRange:
|
||||||
b = (ctypes.c_ubyte * len(begin))()
|
b = (ctypes.c_ubyte * len(begin)).from_buffer(bytearray(begin))
|
||||||
b.value = begin
|
|
||||||
if end is None:
|
if end is None:
|
||||||
e = (ctypes.c_ubyte * 0)()
|
e = (ctypes.c_ubyte * 0)()
|
||||||
e.value = b""
|
|
||||||
else:
|
else:
|
||||||
e = (ctypes.c_ubyte * len(end))()
|
e = (ctypes.c_ubyte * len(end)).from_buffer(bytearray(end))
|
||||||
e.value = end
|
|
||||||
return WriteRange(_Key(b, len(b)), _Key(e, len(e)))
|
return WriteRange(_Key(b, len(b)), _Key(e, len(e)))
|
||||||
|
|
||||||
|
|
||||||
def read(version: int, begin: bytes, end: Optional[bytes] = None) -> ReadRange:
|
def read(version: int, begin: bytes, end: Optional[bytes] = None) -> ReadRange:
|
||||||
b = (ctypes.c_ubyte * len(begin))()
|
b = (ctypes.c_ubyte * len(begin)).from_buffer(bytearray(begin))
|
||||||
b.value = begin
|
|
||||||
if end is None:
|
if end is None:
|
||||||
e = (ctypes.c_ubyte * 0)()
|
e = (ctypes.c_ubyte * 0)()
|
||||||
e.value = b""
|
|
||||||
else:
|
else:
|
||||||
e = (ctypes.c_ubyte * len(end))()
|
e = (ctypes.c_ubyte * len(end)).from_buffer(bytearray(end))
|
||||||
e.value = end
|
|
||||||
return ReadRange(_Key(b, len(b)), _Key(e, len(e)), version)
|
return ReadRange(_Key(b, len(b)), _Key(e, len(e)), version)
|
||||||
|
|
||||||
|
|
||||||
class ConflictSet:
|
class ConflictSet:
|
||||||
def __init__(self, version: int = 0, implementation: Optional[str] = None) -> None:
|
def __init__(
|
||||||
|
self,
|
||||||
|
version: int = 0,
|
||||||
|
build_dir: Optional[str] = None,
|
||||||
|
implementation: Optional[str] = None,
|
||||||
|
) -> None:
|
||||||
self._lib = None
|
self._lib = None
|
||||||
|
if build_dir is None:
|
||||||
|
build_dir = os.path.dirname(__file__) + "/build"
|
||||||
if implementation is None:
|
if implementation is None:
|
||||||
implementation = "radix_tree"
|
implementation = "radix_tree"
|
||||||
for f in (
|
for f in (
|
||||||
os.path.dirname(__file__)
|
build_dir + "/" + implementation + "/libconflict-set.so.0",
|
||||||
+ "/build/"
|
|
||||||
+ implementation
|
|
||||||
+ "/libconflict-set.so.0",
|
|
||||||
os.path.dirname(__file__)
|
os.path.dirname(__file__)
|
||||||
+ "/build/"
|
+ "/build/"
|
||||||
+ implementation
|
+ implementation
|
||||||
|
@@ -1,14 +1,21 @@
|
|||||||
from conflict_set import *
|
from conflict_set import *
|
||||||
|
|
||||||
|
|
||||||
|
build_dir = None
|
||||||
|
|
||||||
|
|
||||||
class DebugConflictSet:
|
class DebugConflictSet:
|
||||||
"""
|
"""
|
||||||
Bisimulates the skip list and radix tree conflict sets for testing purposes
|
Bisimulates the skip list and radix tree conflict sets for testing purposes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, version: int = 0) -> None:
|
def __init__(self, version: int = 0) -> None:
|
||||||
self.skip_list = ConflictSet(version, implementation="skip_list")
|
self.skip_list = ConflictSet(
|
||||||
self.radix_tree = ConflictSet(version, implementation="radix_tree")
|
version, build_dir=build_dir, implementation="skip_list"
|
||||||
|
)
|
||||||
|
self.radix_tree = ConflictSet(
|
||||||
|
version, build_dir=build_dir, implementation="radix_tree"
|
||||||
|
)
|
||||||
|
|
||||||
def addWrites(self, version: int, *writes: WriteRange):
|
def addWrites(self, version: int, *writes: WriteRange):
|
||||||
self.skip_list.addWrites(version, *writes)
|
self.skip_list.addWrites(version, *writes)
|
||||||
@@ -49,6 +56,16 @@ def test_conflict_set():
|
|||||||
assert cs.check(read(0, key)) == [Result.TOO_OLD]
|
assert cs.check(read(0, key)) == [Result.TOO_OLD]
|
||||||
|
|
||||||
|
|
||||||
|
def test_inner_full_words():
|
||||||
|
with DebugConflictSet() as cs:
|
||||||
|
cs.addWrites(1, write(b"\x3f\x61"), write(b"\x81\x61"))
|
||||||
|
writes = []
|
||||||
|
for i in range(0x40, 0x81):
|
||||||
|
writes.append(write(bytes([i, 0x61])))
|
||||||
|
cs.addWrites(2, *writes)
|
||||||
|
cs.check(read(1, b"\x21", b"\xc2"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# budget "pytest" for ctest integration without pulling in a dependency. You can of course still use pytest in local development.
|
# budget "pytest" for ctest integration without pulling in a dependency. You can of course still use pytest in local development.
|
||||||
import argparse
|
import argparse
|
||||||
@@ -61,6 +78,7 @@ if __name__ == "__main__":
|
|||||||
list_parser = subparsers.add_parser("list")
|
list_parser = subparsers.add_parser("list")
|
||||||
test_parser = subparsers.add_parser("test")
|
test_parser = subparsers.add_parser("test")
|
||||||
test_parser.add_argument("test")
|
test_parser.add_argument("test")
|
||||||
|
test_parser.add_argument("--build-dir")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@@ -74,4 +92,5 @@ if __name__ == "__main__":
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
elif args.command == "test":
|
elif args.command == "test":
|
||||||
|
build_dir = args.build_dir
|
||||||
globals()["test_" + args.test]()
|
globals()["test_" + args.test]()
|
||||||
|
Reference in New Issue
Block a user