Compare commits
13 Commits
ad91fb36a5
...
v0.0.3
Author | SHA1 | Date | |
---|---|---|---|
a40b5dcd74 | |||
193b1926ff | |||
1c900c5a8c | |||
90fdcdd51a | |||
eb3f6823eb | |||
1534e10b75 | |||
3c100ccee8 | |||
5cf45d1c35 | |||
4f97932893 | |||
24b0f6b7e4 | |||
e77c3fdee6 | |||
383b956bc0 | |||
5fad15305a |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
.cache
|
.cache
|
||||||
|
__pycache__
|
||||||
build
|
build
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/pre-commit/mirrors-clang-format
|
- repo: https://github.com/pre-commit/mirrors-clang-format
|
||||||
rev: 6d365699efc33b1b432eab5b4ae331a19e1857de # frozen: v18.1.2
|
rev: 6d365699efc33b1b432eab5b4ae331a19e1857de # frozen: v18.1.2
|
||||||
hooks:
|
hooks:
|
||||||
- id: clang-format
|
- id: clang-format
|
||||||
exclude: ".*third_party/.*"
|
exclude: ".*third_party/.*"
|
||||||
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
- repo: https://github.com/cheshirekow/cmake-format-precommit
|
||||||
rev: e2c2116d86a80e72e7146a06e68b7c228afc6319 # frozen: v0.6.13
|
rev: e2c2116d86a80e72e7146a06e68b7c228afc6319 # frozen: v0.6.13
|
||||||
hooks:
|
hooks:
|
||||||
- id: cmake-format
|
- id: cmake-format
|
||||||
- repo: local
|
- repo: local
|
||||||
@@ -13,7 +13,7 @@ repos:
|
|||||||
- id: debug verbose check
|
- id: debug verbose check
|
||||||
name: disallow checking in DEBUG_VERBOSE=1
|
name: disallow checking in DEBUG_VERBOSE=1
|
||||||
description: disallow checking in DEBUG_VERBOSE=1
|
description: disallow checking in DEBUG_VERBOSE=1
|
||||||
entry: '^#define DEBUG_VERBOSE 1$'
|
entry: "^#define DEBUG_VERBOSE 1$"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
types: [c++]
|
types: [c++]
|
||||||
- repo: local
|
- repo: local
|
||||||
@@ -21,10 +21,14 @@ repos:
|
|||||||
- id: debug verbose check
|
- id: debug verbose check
|
||||||
name: disallow checking in SHOW_MEMORY=1
|
name: disallow checking in SHOW_MEMORY=1
|
||||||
description: disallow checking in SHOW_MEMORY=1
|
description: disallow checking in SHOW_MEMORY=1
|
||||||
entry: '^#define SHOW_MEMORY 1$'
|
entry: "^#define SHOW_MEMORY 1$"
|
||||||
language: pygrep
|
language: pygrep
|
||||||
types: [c++]
|
types: [c++]
|
||||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||||
rev: a23f6b85d0fdd5bb9d564e2579e678033debbdff # frozen: v0.10.0.1
|
rev: a23f6b85d0fdd5bb9d564e2579e678033debbdff # frozen: v0.10.0.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: shellcheck
|
- id: shellcheck
|
||||||
|
- repo: https://github.com/psf/black
|
||||||
|
rev: 552baf822992936134cbd31a38f69c8cfe7c0f05 # frozen: 24.3.0
|
||||||
|
hooks:
|
||||||
|
- id: black
|
||||||
|
@@ -1,13 +1,15 @@
|
|||||||
cmake_minimum_required(VERSION 3.18)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
project(
|
project(
|
||||||
conflict-set
|
conflict-set
|
||||||
VERSION 0.0.2
|
VERSION 0.0.3
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
"A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys."
|
"A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys."
|
||||||
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/conflict-set"
|
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/conflict-set"
|
||||||
LANGUAGES C CXX)
|
LANGUAGES C CXX)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
file(WRITE ${CMAKE_BINARY_DIR}/version.txt ${PROJECT_VERSION})
|
||||||
|
|
||||||
include(CMakePushCheckState)
|
include(CMakePushCheckState)
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
include(CheckIncludeFileCXX)
|
include(CheckIncludeFileCXX)
|
||||||
@@ -128,7 +130,7 @@ endif()
|
|||||||
if(APPLE)
|
if(APPLE)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET ${PROJECT_NAME}-static
|
TARGET ${PROJECT_NAME}-static
|
||||||
PRE_BUILD
|
PRE_LINK
|
||||||
COMMAND ${CMAKE_SOURCE_DIR}/privatize_symbols_macos.sh
|
COMMAND ${CMAKE_SOURCE_DIR}/privatize_symbols_macos.sh
|
||||||
$<TARGET_OBJECTS:${PROJECT_NAME}-object>)
|
$<TARGET_OBJECTS:${PROJECT_NAME}-object>)
|
||||||
else()
|
else()
|
||||||
@@ -302,7 +304,11 @@ if(BUILD_TESTING)
|
|||||||
set(symbol_imports ${CMAKE_SOURCE_DIR}/apple-symbol-imports.txt)
|
set(symbol_imports ${CMAKE_SOURCE_DIR}/apple-symbol-imports.txt)
|
||||||
else()
|
else()
|
||||||
set(symbol_exports ${CMAKE_SOURCE_DIR}/symbol-exports.txt)
|
set(symbol_exports ${CMAKE_SOURCE_DIR}/symbol-exports.txt)
|
||||||
set(symbol_imports ${CMAKE_SOURCE_DIR}/symbol-imports.txt)
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
|
||||||
|
set(symbol_imports ${CMAKE_SOURCE_DIR}/aarch64-symbol-imports.txt)
|
||||||
|
else()
|
||||||
|
set(symbol_imports ${CMAKE_SOURCE_DIR}/symbol-imports.txt)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
add_test(
|
add_test(
|
||||||
NAME conflict_set_shared_symbols
|
NAME conflict_set_shared_symbols
|
||||||
@@ -329,6 +335,7 @@ endif()
|
|||||||
# packaging
|
# packaging
|
||||||
|
|
||||||
set(CPACK_PACKAGE_CONTACT andrew@weaselab.dev)
|
set(CPACK_PACKAGE_CONTACT andrew@weaselab.dev)
|
||||||
|
set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME all)
|
||||||
|
|
||||||
set(CPACK_PACKAGE_VENDOR "Weaselab")
|
set(CPACK_PACKAGE_VENDOR "Weaselab")
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
@@ -342,6 +349,25 @@ set(CPACK_RPM_FILE_NAME RPM-DEFAULT)
|
|||||||
|
|
||||||
# deb
|
# deb
|
||||||
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
|
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
|
||||||
|
# see *-imports.txt - dependency versions need to be synced with symbol versions
|
||||||
|
if(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64)
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.17)")
|
||||||
|
else()
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.14)")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# macos
|
||||||
|
if(APPLE)
|
||||||
|
find_program(PANDOC_EXE pandoc)
|
||||||
|
if(PANDOC_EXE)
|
||||||
|
execute_process(COMMAND ${PANDOC_EXE} ${CMAKE_SOURCE_DIR}/README.md -o
|
||||||
|
${CMAKE_BINARY_DIR}/README.txt)
|
||||||
|
set(CPACK_RESOURCE_FILE_README ${CMAKE_BINARY_DIR}/README.txt)
|
||||||
|
endif()
|
||||||
|
configure_file(${CMAKE_SOURCE_DIR}/LICENSE ${CMAKE_BINARY_DIR}/LICENSE.txt
|
||||||
|
COPYONLY)
|
||||||
|
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_BINARY_DIR}/LICENSE.txt)
|
||||||
|
endif()
|
||||||
|
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|
||||||
@@ -367,8 +393,11 @@ install(
|
|||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
install(DIRECTORY include/
|
install(DIRECTORY include/
|
||||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
|
||||||
|
|
||||||
install(EXPORT ${PROJECT_NAME}Config
|
install(EXPORT ${PROJECT_NAME}Config
|
||||||
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
|
||||||
|
|
||||||
|
cpack_add_component(all)
|
||||||
|
36
README.md
36
README.md
@@ -58,27 +58,27 @@ Performance counters:
|
|||||||
|
|
||||||
## Skip list
|
## Skip list
|
||||||
|
|
||||||
| ns/op | op/s | err% | total | benchmark
|
| ns/op | op/s | err% | total | benchmark |
|
||||||
|--------------------:|--------------------:|--------:|----------:|:----------
|
| -----: | -----------: | ---: | ----: | :---------------------------------- |
|
||||||
| 246.99 | 4,048,700.59 | 0.2% | 0.01 | `point reads`
|
| 246.99 | 4,048,700.59 | 0.2% | 0.01 | `point reads` |
|
||||||
| 260.16 | 3,843,784.65 | 0.1% | 0.01 | `prefix reads`
|
| 260.16 | 3,843,784.65 | 0.1% | 0.01 | `prefix reads` |
|
||||||
| 493.35 | 2,026,953.19 | 0.1% | 0.01 | `range reads`
|
| 493.35 | 2,026,953.19 | 0.1% | 0.01 | `range reads` |
|
||||||
| 462.05 | 2,164,289.23 | 0.6% | 0.01 | `point writes`
|
| 462.05 | 2,164,289.23 | 0.6% | 0.01 | `point writes` |
|
||||||
| 448.19 | 2,231,205.25 | 0.9% | 0.01 | `prefix writes`
|
| 448.19 | 2,231,205.25 | 0.9% | 0.01 | `prefix writes` |
|
||||||
| 255.83 | 3,908,845.72 | 1.5% | 0.02 | `range writes`
|
| 255.83 | 3,908,845.72 | 1.5% | 0.02 | `range writes` |
|
||||||
| 582.63 | 1,716,349.02 | 1.3% | 0.01 | `monotonic increasing point writes`
|
| 582.63 | 1,716,349.02 | 1.3% | 0.01 | `monotonic increasing point writes` |
|
||||||
|
|
||||||
## Radix tree (this implementation)
|
## Radix tree (this implementation)
|
||||||
|
|
||||||
| ns/op | op/s | err% | total | benchmark
|
| ns/op | op/s | err% | total | benchmark |
|
||||||
|--------------------:|--------------------:|--------:|----------:|:----------
|
| -----: | ------------: | ---: | ----: | :---------------------------------- |
|
||||||
| 19.42 | 51,483,206.67 | 0.3% | 0.01 | `point reads`
|
| 19.42 | 51,483,206.67 | 0.3% | 0.01 | `point reads` |
|
||||||
| 58.43 | 17,115,612.57 | 0.1% | 0.01 | `prefix reads`
|
| 58.43 | 17,115,612.57 | 0.1% | 0.01 | `prefix reads` |
|
||||||
| 216.09 | 4,627,766.60 | 0.2% | 0.01 | `range reads`
|
| 216.09 | 4,627,766.60 | 0.2% | 0.01 | `range reads` |
|
||||||
| 28.35 | 35,267,567.72 | 0.2% | 0.01 | `point writes`
|
| 28.35 | 35,267,567.72 | 0.2% | 0.01 | `point writes` |
|
||||||
| 43.43 | 23,026,226.17 | 0.2% | 0.01 | `prefix writes`
|
| 43.43 | 23,026,226.17 | 0.2% | 0.01 | `prefix writes` |
|
||||||
| 50.00 | 20,000,000.00 | 0.0% | 0.01 | `range writes`
|
| 50.00 | 20,000,000.00 | 0.0% | 0.01 | `range writes` |
|
||||||
| 92.38 | 10,824,863.69 | 4.1% | 0.01 | `monotonic increasing point writes`
|
| 92.38 | 10,824,863.69 | 4.1% | 0.01 | `monotonic increasing point writes` |
|
||||||
|
|
||||||
# "Real data" test
|
# "Real data" test
|
||||||
|
|
||||||
|
8
aarch64-symbol-imports.txt
Normal file
8
aarch64-symbol-imports.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
__stack_chk_fail@GLIBC_2.17
|
||||||
|
__stack_chk_guard@GLIBC_2.17
|
||||||
|
abort@GLIBC_2.17
|
||||||
|
free@GLIBC_2.17
|
||||||
|
malloc@GLIBC_2.17
|
||||||
|
memcpy@GLIBC_2.17
|
||||||
|
memmove@GLIBC_2.17
|
||||||
|
memset@GLIBC_2.17
|
120
conflict_set.py
Normal file
120
conflict_set.py
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
import ctypes
|
||||||
|
import enum
|
||||||
|
import os
|
||||||
|
|
||||||
|
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):
|
||||||
|
_fields_ = [("p", ctypes.POINTER(ctypes.c_ubyte)), ("len", ctypes.c_int)]
|
||||||
|
|
||||||
|
|
||||||
|
class ReadRange(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("begin", _Key),
|
||||||
|
("end", _Key),
|
||||||
|
("readVersion", ctypes.c_int64),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class WriteRange(ctypes.Structure):
|
||||||
|
_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,)
|
||||||
|
|
||||||
|
|
||||||
|
class Result(enum.Enum):
|
||||||
|
COMMIT = 0
|
||||||
|
CONFLICT = 1
|
||||||
|
TOO_OLD = 2
|
||||||
|
|
||||||
|
|
||||||
|
def write(begin: bytes, end: Optional[bytes] = None) -> WriteRange:
|
||||||
|
b = (ctypes.c_ubyte * len(begin))()
|
||||||
|
b.value = begin
|
||||||
|
if end is None:
|
||||||
|
e = (ctypes.c_ubyte * 0)()
|
||||||
|
e.value = b""
|
||||||
|
else:
|
||||||
|
e = (ctypes.c_ubyte * len(end))()
|
||||||
|
e.value = end
|
||||||
|
return WriteRange(_Key(b, len(b)), _Key(e, len(e)))
|
||||||
|
|
||||||
|
|
||||||
|
def read(version: int, begin: bytes, end: Optional[bytes] = None) -> ReadRange:
|
||||||
|
b = (ctypes.c_ubyte * len(begin))()
|
||||||
|
b.value = begin
|
||||||
|
if end is None:
|
||||||
|
e = (ctypes.c_ubyte * 0)()
|
||||||
|
e.value = b""
|
||||||
|
else:
|
||||||
|
e = (ctypes.c_ubyte * len(end))()
|
||||||
|
e.value = end
|
||||||
|
return ReadRange(_Key(b, len(b)), _Key(e, len(e)), version)
|
||||||
|
|
||||||
|
|
||||||
|
class ConflictSet:
|
||||||
|
def __init__(self, version: int = 0) -> None:
|
||||||
|
self.p = _lib.ConflictSet_create(version)
|
||||||
|
|
||||||
|
def addWrites(self, version: int, *writes: WriteRange):
|
||||||
|
_lib.ConflictSet_addWrites(
|
||||||
|
self.p, (WriteRange * len(writes))(*writes), len(writes), version
|
||||||
|
)
|
||||||
|
|
||||||
|
def check(self, *reads: ReadRange) -> list[Result]:
|
||||||
|
r = (ctypes.c_int * len(reads))()
|
||||||
|
_lib.ConflictSet_check(self.p, *reads, r, 1)
|
||||||
|
return [Result(x) for x in r]
|
||||||
|
|
||||||
|
def setOldestVersion(self, version: int) -> None:
|
||||||
|
_lib.ConflictSet_setOldestVersion(self.p, version)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def close(self) -> None:
|
||||||
|
if self.p is not None:
|
||||||
|
_lib.ConflictSet_destroy(self.p)
|
||||||
|
self.p = None
|
||||||
|
|
||||||
|
def __exit__(self, exception_type, exception_value, exception_traceback):
|
||||||
|
if self.p is not None:
|
||||||
|
_lib.ConflictSet_destroy(self.p)
|
||||||
|
self.p = None
|
33
package_macos.sh
Executable file
33
package_macos.sh
Executable file
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euxo pipefail
|
||||||
|
|
||||||
|
umask 022
|
||||||
|
|
||||||
|
SRC_DIR="${0%/*}"
|
||||||
|
BUILD_ARM="$(mktemp -d -t conflict-set-arm)"
|
||||||
|
BUILD_X86="$(mktemp -d -t conflict-set-x86)"
|
||||||
|
|
||||||
|
cmake_args=(-DCMAKE_CXX_FLAGS=-DNVALGRIND -DCPACK_PACKAGING_INSTALL_PREFIX=/usr/local)
|
||||||
|
|
||||||
|
cmake -S"$SRC_DIR" -B"$BUILD_ARM" -DCMAKE_OSX_ARCHITECTURES=arm64 "${cmake_args[@]}"
|
||||||
|
cmake --build "$BUILD_ARM" --target conflict-set --target conflict-set-static
|
||||||
|
|
||||||
|
cmake -S"$SRC_DIR" -B"$BUILD_X86" -DCMAKE_OSX_ARCHITECTURES=x86_64 "${cmake_args[@]}"
|
||||||
|
cmake --build "$BUILD_X86" --target conflict-set --target conflict-set-static
|
||||||
|
|
||||||
|
VERSION="$(cat "$BUILD_ARM/version.txt")"
|
||||||
|
|
||||||
|
lipo -create "$BUILD_ARM/radix_tree/libconflict-set.$VERSION.dylib" "$BUILD_X86/radix_tree/libconflict-set.$VERSION.dylib" -output "libconflict-set.$VERSION.dylib.tmp"
|
||||||
|
lipo -create "$BUILD_ARM"/libconflict-set-static.a "$BUILD_X86"/libconflict-set-static.a -output libconflict-set-static.a.tmp
|
||||||
|
|
||||||
|
mv "libconflict-set.$VERSION.dylib.tmp" "$BUILD_ARM/radix_tree/libconflict-set.$VERSION.dylib"
|
||||||
|
mv libconflict-set-static.a.tmp "$BUILD_ARM/libconflict-set-static.a"
|
||||||
|
|
||||||
|
pushd "$BUILD_ARM"
|
||||||
|
cpack -G productbuild
|
||||||
|
popd
|
||||||
|
|
||||||
|
mv "$BUILD_ARM/conflict-set-$VERSION-Darwin.pkg" .
|
||||||
|
|
||||||
|
rm -rf "$BUILD_ARM" "$BUILD_X86"
|
@@ -2,5 +2,7 @@
|
|||||||
|
|
||||||
# This has the effect of making visibility=hidden symbols private in object files
|
# This has the effect of making visibility=hidden symbols private in object files
|
||||||
for obj in "$@" ; do
|
for obj in "$@" ; do
|
||||||
ld -r "$obj" -o "$obj.tmp" && mv "$obj.tmp" "$obj"
|
ld -r "$obj" -o "$obj.tmp"
|
||||||
|
touch -r "$obj" "$obj.tmp"
|
||||||
|
mv "$obj.tmp" "$obj"
|
||||||
done
|
done
|
||||||
|
@@ -1,17 +1,9 @@
|
|||||||
_GLOBAL_OFFSET_TABLE_
|
_GLOBAL_OFFSET_TABLE_
|
||||||
__stack_chk_fail@GLIBC_2.17
|
|
||||||
__stack_chk_fail@GLIBC_2.4
|
__stack_chk_fail@GLIBC_2.4
|
||||||
__stack_chk_guard@GLIBC_2.17
|
|
||||||
__tls_get_addr@GLIBC_2.3
|
__tls_get_addr@GLIBC_2.3
|
||||||
abort@GLIBC_2.17
|
|
||||||
abort@GLIBC_2.2.5
|
abort@GLIBC_2.2.5
|
||||||
free@GLIBC_2.17
|
|
||||||
free@GLIBC_2.2.5
|
free@GLIBC_2.2.5
|
||||||
malloc@GLIBC_2.17
|
|
||||||
malloc@GLIBC_2.2.5
|
malloc@GLIBC_2.2.5
|
||||||
memcpy@GLIBC_2.14
|
memcpy@GLIBC_2.14
|
||||||
memcpy@GLIBC_2.17
|
|
||||||
memmove@GLIBC_2.17
|
|
||||||
memmove@GLIBC_2.2.5
|
memmove@GLIBC_2.2.5
|
||||||
memset@GLIBC_2.17
|
memset@GLIBC_2.2.5
|
||||||
memset@GLIBC_2.2.5
|
|
||||||
|
9
test_conflict_set.py
Normal file
9
test_conflict_set.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from conflict_set import *
|
||||||
|
|
||||||
|
|
||||||
|
def test_conflict_set():
|
||||||
|
with ConflictSet() as cs:
|
||||||
|
cs.addWrites(1, write(b""))
|
||||||
|
assert cs.check(read(0, b"")) == [Result.CONFLICT]
|
||||||
|
cs.setOldestVersion(1)
|
||||||
|
assert cs.check(read(0, b"")) == [Result.TOO_OLD]
|
Reference in New Issue
Block a user