31 Commits

Author SHA1 Message Date
24b0f6b7e4 Add missing _GLOBAL_OFFSET_TABLE_ symbol
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-04-04 11:36:32 -07:00
e77c3fdee6 Adding missing memset import 2024-04-04 11:35:44 -07:00
383b956bc0 Set debian libc6 dep precisely
Some checks failed
Tests / Clang total: 1096, failed: 2, passed: 1094
Tests / SIMD fallback total: 1096, failed: 2, passed: 1094
Tests / Release [gcc] total: 1096, failed: 1, passed: 1095
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-04-04 11:12:41 -07:00
5fad15305a Track x64 and arm imports in separate files 2024-04-04 11:04:26 -07:00
ad91fb36a5 Symbol tests for macos + whitelist imports/exports
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
commit 1ad8276100
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:44:35 2024 -0700

    Add symbols for arm build

commit 058e4d5302
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:42:48 2024 -0700

    Add _GLOBAL_OFFSET_TABLE_

commit a201f3ada8
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:34:05 2024 -0700

    Add memset to symbol imports

commit c1129ed0e2
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:32:28 2024 -0700

    Add symbol imports file

commit 618766ce2e
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:27:07 2024 -0700

    Fix objcopy filepath

commit e774a90007
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:24:44 2024 -0700

    Use shellcheck precommit without docker

commit baddea7f57
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:20:26 2024 -0700

    Update and freeze pre-commit hooks

commit 2d3e7b9004
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:19:55 2024 -0700

    Add shellcheck to pre-commit

    Closes #22

commit c4862fee9b
Author: Andrew Noyes <andrew@weaselab.dev>
Date:   Wed Apr 3 12:15:08 2024 -0700

    Add symbol tests for apple

    closes #21
2024-04-03 12:50:51 -07:00
38c1481432 Make visibility=hidden symbols private on macos
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-04-02 18:30:17 -07:00
771ae896e7 Check that -msimd128 flag is valid 2024-04-02 15:48:18 -07:00
5bf72bda61 Don't treat full_relro_flags as all one flag
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-04-02 14:20:22 -07:00
a534f3b758 Conditionally add -pie
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-04-02 14:15:11 -07:00
ae4fa889c7 Partial support for wasi-sdk
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-04-02 12:14:04 -07:00
e3d3b0ec0d objcopy doesn't support --keep-global-symbols for wasm
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-04-02 12:09:01 -07:00
dea8d6ae01 Align ArenaImpl allocation to alignof(ArenaImpl)
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
Fixes #20
2024-04-01 17:31:16 -07:00
dbc6f2313a Add missing cerrno include 2024-04-01 17:21:43 -07:00
4f51878642 Add -msimd128 if USE_SIMD_FALLBACK=OFF
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-30 17:57:50 -07:00
215865a462 Experimental wasm support 2024-03-30 16:20:55 -07:00
348ebf016a Enable relro for shared lib
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-29 21:51:02 -07:00
377259ffa0 Unsuppress -Wmaybe-uninitialized
I don't see the warning anymore locally
2024-03-29 18:57:43 -07:00
70220d95e7 Bump version
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-29 16:23:09 -07:00
71c39f9955 Opt-in to rpm/deb default package filenames
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-29 15:56:58 -07:00
8cc17158fd Fix preprocessing instructions for linux
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-28 14:58:29 -07:00
ab211c646a Apply compiler-appeasing syntax changes from Taoxi 2024-03-28 14:57:31 -07:00
7af961f141 Fix jenkins build
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-28 11:44:01 -07:00
a91df62608 Add USE_SIMD_FALLBACK build in jenkins
Some checks failed
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-03-28 11:33:53 -07:00
0a1843a161 Add USE_SIMD_FALLBACK
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-28 11:12:50 -07:00
4edf0315d9 Find insertion point for Node16 with simd
Closes #13
2024-03-28 10:47:20 -07:00
14515e186a Update readme benchmarks again
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
I think the last skiplisttest benchmark looked bad because I had vscode
+ firefox + ?? open
2024-03-27 16:47:36 -07:00
b0085df5ad Update symbols.txt
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-27 16:29:30 -07:00
76a7e17b29 Update readme benchmarks
Some checks failed
Tests / Clang total: 1096, failed: 2, passed: 1094
Tests / Release [gcc] total: 1096, failed: 2, passed: 1094
Tests / Release [gcc,aarch64] total: 824, failed: 2, passed: 822
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head There was a failure building this commit
I was incorrectly linking to an old build of conflict set, before the
conflict-set name change. I don't know what the regression is from, but
update the README for transparency now.
2024-03-27 16:12:45 -07:00
5cf43d1bfa Add weaselab namespace 2024-03-27 16:07:05 -07:00
25cc427ec5 Assert safe_free size is correct in debug builds
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
Closes #16
2024-03-27 15:34:24 -07:00
c15c2e7b44 Remove redundant static assert
Closes #14
2024-03-27 12:41:45 -07:00
21 changed files with 398 additions and 247 deletions

View File

@@ -1,11 +1,11 @@
repos:
- repo: https://github.com/pre-commit/mirrors-clang-format
rev: b111689e7b5cba60be3c62d5db2bd1357f4d36ca
rev: 6d365699efc33b1b432eab5b4ae331a19e1857de # frozen: v18.1.2
hooks:
- id: clang-format
exclude: ".*third_party/.*"
- repo: https://github.com/cheshirekow/cmake-format-precommit
rev: e2c2116d86a80e72e7146a06e68b7c228afc6319
rev: e2c2116d86a80e72e7146a06e68b7c228afc6319 # frozen: v0.6.13
hooks:
- id: cmake-format
- repo: local
@@ -23,4 +23,8 @@ repos:
description: disallow checking in SHOW_MEMORY=1
entry: '^#define SHOW_MEMORY 1$'
language: pygrep
types: [c++]
types: [c++]
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: a23f6b85d0fdd5bb9d564e2579e678033debbdff # frozen: v0.10.0.1
hooks:
- id: shellcheck

View File

@@ -34,7 +34,7 @@ ConflictSet::ReadRange singleton(Arena &arena, std::span<const uint8_t> key) {
std::span<uint8_t>(new (arena) uint8_t[key.size() + 1], key.size() + 1);
memcpy(r.data(), key.data(), key.size());
r[key.size()] = 0;
return {key.data(), int(key.size()), r.data(), int(r.size())};
return {{key.data(), int(key.size())}, {r.data(), int(r.size())}, 0};
}
ConflictSet::ReadRange prefixRange(Arena &arena, std::span<const uint8_t> key) {
@@ -52,7 +52,7 @@ ConflictSet::ReadRange prefixRange(Arena &arena, std::span<const uint8_t> key) {
auto r = std::span<uint8_t>(new (arena) uint8_t[index + 1], index + 1);
memcpy(r.data(), key.data(), index + 1);
r[r.size() - 1]++;
return {key.data(), int(key.size()), r.data(), int(r.size())};
return {{key.data(), int(key.size())}, {r.data(), int(r.size())}, 0};
}
void benchConflictSet() {
@@ -258,4 +258,4 @@ void benchConflictSet() {
}
}
int main(void) { benchConflictSet(); }
int main(void) { benchConflictSet(); }

View File

@@ -1,15 +1,26 @@
cmake_minimum_required(VERSION 3.18)
project(
conflict-set
VERSION 0.0.1
VERSION 0.0.2
DESCRIPTION
"A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys."
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/conflict-set"
LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 20)
include(CMakePushCheckState)
include(CheckCXXCompilerFlag)
include(CheckIncludeFileCXX)
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
@@ -23,16 +34,32 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
endif()
add_compile_options(-fdata-sections -ffunction-sections -Wswitch-enum
-Werror=switch-enum)
-Werror=switch-enum -fPIC)
set(full_relro_flags "-pie;LINKER:-z,relro,-z,now,-z,noexecstack")
cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${full_relro_flags})
check_cxx_source_compiles("int main(){}" HAS_FULL_RELRO FAIL_REGEX "warning:")
if(HAS_FULL_RELRO)
add_link_options(${full_relro_flags})
endif()
cmake_pop_check_state()
set(version_script_flags LINKER:--version-script=${CMAKE_SOURCE_DIR}/linker.map)
cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${version_script_flags})
check_cxx_source_compiles("int main(){}" HAS_VERSION_SCRIPT FAIL_REGEX
"warning:")
cmake_pop_check_state()
option(USE_SIMD_FALLBACK
"Use fallback implementations of functions that use SIMD" OFF)
# This is encouraged according to
# https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/third_party/valgrind)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
add_compile_options(-Wno-maybe-uninitialized
$<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>)
endif()
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>)
if(APPLE)
add_link_options(-Wl,-dead_strip)
@@ -40,32 +67,46 @@ else()
add_link_options(-Wl,--gc-sections)
endif()
include(CheckIncludeFileCXX)
include(CMakePushCheckState)
cmake_push_check_state()
list(APPEND CMAKE_REQUIRED_FLAGS -mavx)
check_include_file_cxx("immintrin.h" HAS_AVX)
if(HAS_AVX)
add_compile_options(-mavx)
add_compile_definitions(HAS_AVX)
if(EMSCRIPTEN)
# https://github.com/emscripten-core/emscripten/issues/15377#issuecomment-1285167486
add_link_options(-lnodefs.js -lnoderawfs.js)
add_link_options(-s ALLOW_MEMORY_GROWTH)
endif()
cmake_pop_check_state()
check_include_file_cxx("arm_neon.h" HAS_ARM_NEON)
if(HAS_ARM_NEON)
add_compile_definitions(HAS_ARM_NEON)
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)
if(HAS_AVX)
add_compile_options(-mavx)
add_compile_definitions(HAS_AVX)
endif()
cmake_pop_check_state()
check_include_file_cxx("arm_neon.h" HAS_ARM_NEON)
if(HAS_ARM_NEON)
add_compile_definitions(HAS_ARM_NEON)
endif()
endif()
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
add_library(${PROJECT_NAME}_object OBJECT ConflictSet.cpp)
target_compile_options(${PROJECT_NAME}_object PRIVATE -fPIC -fno-exceptions
add_library(${PROJECT_NAME}-object OBJECT ConflictSet.cpp)
target_compile_options(${PROJECT_NAME}-object PRIVATE -fno-exceptions
-fvisibility=hidden)
target_include_directories(${PROJECT_NAME}_object
target_include_directories(${PROJECT_NAME}-object
PRIVATE ${CMAKE_SOURCE_DIR}/include)
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:${PROJECT_NAME}_object>)
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:${PROJECT_NAME}-object>)
set_target_properties(
${PROJECT_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/radix_tree")
@@ -73,24 +114,32 @@ if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)
endif()
if(NOT APPLE)
if(HAS_VERSION_SCRIPT)
target_link_options(${PROJECT_NAME} PRIVATE
LINKER:--version-script=${CMAKE_SOURCE_DIR}/linker.map)
endif()
add_library(${PROJECT_NAME}-static STATIC
$<TARGET_OBJECTS:${PROJECT_NAME}_object>)
$<TARGET_OBJECTS:${PROJECT_NAME}-object>)
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
set_target_properties(${PROJECT_NAME}-static PROPERTIES LINKER_LANGUAGE C)
endif()
if(NOT APPLE AND CMAKE_OBJCOPY)
if(APPLE)
add_custom_command(
TARGET conflict-set-static
TARGET ${PROJECT_NAME}-static
PRE_BUILD
COMMAND ${CMAKE_SOURCE_DIR}/privatize_symbols_macos.sh
$<TARGET_OBJECTS:${PROJECT_NAME}-object>)
else()
add_custom_command(
TARGET ${PROJECT_NAME}-static
POST_BUILD
COMMAND
${CMAKE_OBJCOPY} --keep-global-symbols=${CMAKE_SOURCE_DIR}/symbols.txt
$<TARGET_FILE:${PROJECT_NAME}-static>)
${CMAKE_OBJCOPY}
--keep-global-symbols=${CMAKE_SOURCE_DIR}/symbol-exports.txt
$<TARGET_FILE:${PROJECT_NAME}-static> || echo
"Proceeding with all symbols global in static library")
endif()
set(TEST_FLAGS -Wall -Wextra -Wunreachable-code -Wpedantic -UNDEBUG)
@@ -99,30 +148,51 @@ include(CTest)
if(BUILD_TESTING)
# Shared library version of FoundationDB's skip list implementation
add_library(skip_list SHARED SkipList.cpp)
target_compile_options(skip_list PRIVATE -fPIC -fno-exceptions
-fvisibility=hidden)
target_include_directories(skip_list PUBLIC ${CMAKE_SOURCE_DIR}/include)
set_target_properties(skip_list PROPERTIES LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_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})
# corpus tests, which are tests curated by libfuzzer. The goal is to get broad
# coverage with a small number of tests.
# 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 -fPIC -fno-exceptions
-fvisibility=hidden)
target_include_directories(hash_table PUBLIC ${CMAKE_SOURCE_DIR}/include)
set_target_properties(hash_table PROPERTIES LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_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})
file(GLOB CORPUS_TESTS ${CMAKE_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_SOURCE_DIR}/include)
set_target_properties(skip_list PROPERTIES LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_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_SOURCE_DIR}/include)
set_target_properties(
hash_table PROPERTIES LIBRARY_OUTPUT_DIRECTORY
"${CMAKE_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)
foreach(TEST ${CORPUS_TESTS})
get_filename_component(hash ${TEST} NAME)
add_test(NAME skip_list_${hash} COMMAND driver_skip_list ${TEST})
endforeach()
endif()
# ad hoc testing
add_executable(conflict_set_main ConflictSet.cpp)
target_include_directories(conflict_set_main
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
@@ -149,10 +219,7 @@ if(BUILD_TESTING)
endif()
endif()
# corpus tests
file(GLOB CORPUS_TESTS ${CMAKE_SOURCE_DIR}/corpus/*)
# whitebox tests
add_executable(fuzz_driver ConflictSet.cpp FuzzTestDriver.cpp)
target_compile_options(fuzz_driver PRIVATE ${TEST_FLAGS})
if(NOT CMAKE_CROSSCOMPILING)
@@ -167,8 +234,7 @@ if(BUILD_TESTING)
add_test(NAME conflict_set_fuzz_${hash} COMMAND fuzz_driver ${TEST})
endforeach()
# tsan
# tsan tests
if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_BUILD_TYPE STREQUAL Debug)
add_executable(tsan_driver ConflictSet.cpp FuzzTestDriver.cpp)
target_compile_options(tsan_driver PRIVATE ${TEST_FLAGS} -fsanitize=thread)
@@ -182,24 +248,26 @@ if(BUILD_TESTING)
endforeach()
endif()
# blackbox tests
add_executable(driver TestDriver.cpp)
target_compile_options(driver PRIVATE ${TEST_FLAGS})
target_link_libraries(driver PRIVATE ${PROJECT_NAME})
foreach(TEST ${CORPUS_TESTS})
get_filename_component(hash ${TEST} NAME)
add_test(NAME conflict_set_blackbox_${hash} COMMAND driver ${TEST})
endforeach()
# scripted tests. Written manually to fill in anything libfuzzer couldn't
# find.
add_executable(script_test ScriptTest.cpp)
target_compile_options(script_test PRIVATE ${TEST_FLAGS})
target_link_libraries(script_test PRIVATE ${PROJECT_NAME})
file(GLOB SCRIPT_TESTS ${CMAKE_SOURCE_DIR}/script_tests/*)
foreach(TEST ${SCRIPT_TESTS})
get_filename_component(name ${TEST} NAME)
add_test(NAME conflict_set_script_${name} COMMAND script_test ${TEST})
endforeach()
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)
find_program(VALGRIND_EXE valgrind)
if(VALGRIND_EXE AND NOT CMAKE_CROSSCOMPILING)
add_test(NAME conflict_set_blackbox_valgrind
@@ -207,12 +275,6 @@ if(BUILD_TESTING)
$<TARGET_FILE:driver> ${CORPUS_TESTS})
endif()
foreach(TEST ${CORPUS_TESTS})
get_filename_component(hash ${TEST} NAME)
add_test(NAME conflict_set_blackbox_${hash} COMMAND driver ${TEST})
add_test(NAME skip_list_${hash} COMMAND driver_skip_list ${TEST})
endforeach()
# api smoke tests
# c90
@@ -233,28 +295,41 @@ if(BUILD_TESTING)
PROPERTIES CXX_STANDARD_REQUIRED ON)
add_test(NAME conflict_set_cxx_api_test COMMAND conflict_set_cxx_api_test)
if(NOT APPLE AND NOT CMAKE_BUILD_TYPE STREQUAL Debug)
# symbol visibility tests
if(NOT WASM AND NOT CMAKE_BUILD_TYPE STREQUAL Debug)
if(APPLE)
set(symbol_exports ${CMAKE_SOURCE_DIR}/apple-symbol-exports.txt)
set(symbol_imports ${CMAKE_SOURCE_DIR}/apple-symbol-imports.txt)
else()
set(symbol_exports ${CMAKE_SOURCE_DIR}/symbol-exports.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()
add_test(
NAME conflict_set_shared_symbols
COMMAND ${CMAKE_SOURCE_DIR}/test_symbols.sh
$<TARGET_FILE:${PROJECT_NAME}> ${CMAKE_SOURCE_DIR}/symbols.txt)
COMMAND
${CMAKE_SOURCE_DIR}/test_symbols.sh $<TARGET_FILE:${PROJECT_NAME}>
${symbol_exports} ${symbol_imports})
add_test(
NAME conflict_set_static_symbols
COMMAND
${CMAKE_SOURCE_DIR}/test_symbols.sh
$<TARGET_FILE:${PROJECT_NAME}-static> ${CMAKE_SOURCE_DIR}/symbols.txt)
$<TARGET_FILE:${PROJECT_NAME}-static> ${symbol_exports}
${symbol_imports})
endif()
# bench
add_executable(conflict_set_bench Bench.cpp)
target_link_libraries(conflict_set_bench PRIVATE ${PROJECT_NAME})
set_target_properties(conflict_set_bench PROPERTIES SKIP_BUILD_RPATH ON)
add_executable(real_data_bench RealDataBench.cpp)
target_link_libraries(real_data_bench PRIVATE ${PROJECT_NAME})
set_target_properties(real_data_bench PROPERTIES SKIP_BUILD_RPATH ON)
endif()
# packaging
set(CPACK_PACKAGE_CONTACT andrew@weaselab.dev)
@@ -267,6 +342,16 @@ set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
set(CPACK_RPM_SPEC_INSTALL_POST "/bin/true") # avoid stripping
set(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0")
set(CPACK_RPM_FILE_NAME RPM-DEFAULT)
# deb
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()
include(CPack)
@@ -288,12 +373,12 @@ set_target_properties(
install(
TARGETS ${PROJECT_NAME} ${PROJECT_NAME}-static
EXPORT conflict-setConfig
EXPORT ${PROJECT_NAME}Config
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
install(EXPORT conflict-setConfig
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/conflict-set/cmake)
install(EXPORT ${PROJECT_NAME}Config
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)

View File

@@ -29,6 +29,7 @@ limitations under the License.
#include <span>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#ifdef HAS_AVX
@@ -39,6 +40,8 @@ limitations under the License.
#include <memcheck.h>
using namespace weaselab;
// Use assert for checking potentially complex properties during tests.
// Use assume to hint simple properties to the optimizer.
@@ -558,7 +561,6 @@ template <class T> struct BoundedFreeListAllocator {
}
void release(T *p) {
static_assert(std::is_trivially_destructible_v<T>);
if (freeListBytes >= kFreeListMaxMemory) {
removeNode(p);
return safe_free(p, sizeof(T) + p->partialKeyCapacity);
@@ -953,6 +955,42 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
assert(self->getType() == Type_Node16);
++self->numChildren;
#ifdef HAS_AVX
__m128i key_vec = _mm_set1_epi8(index);
__m128i indices;
memcpy(&indices, self16->index, sizeof(self16->index));
__m128i results = _mm_cmpeq_epi8(key_vec, _mm_min_epu8(key_vec, indices));
int mask = (1 << (self->numChildren - 1)) - 1;
uint32_t bitfield = _mm_movemask_epi8(results) & mask;
bitfield |= uint32_t(1) << (self->numChildren - 1);
int i = std::countr_zero(bitfield);
if (i < self->numChildren - 1) {
memmove(self16->index + i + 1, self16->index + i,
self->numChildren - (i + 1));
memmove(self16->children + i + 1, self16->children + i,
(self->numChildren - (i + 1)) * sizeof(Child));
}
#elif defined(HAS_ARM_NEON)
uint8x16_t indices;
memcpy(&indices, self16->index, sizeof(self16->index));
// 0xff for each leq
auto results = vcleq_u8(vdupq_n_u8(index), indices);
uint64_t mask = (uint64_t(1) << ((self->numChildren - 1) * 4)) - 1;
// 0xf for each 0xff (within mask)
uint64_t bitfield =
vget_lane_u64(
vreinterpret_u64_u8(vshrn_n_u16(vreinterpretq_u16_u8(results), 4)),
0) &
mask;
bitfield |= uint64_t(0xf) << ((self->numChildren - 1) * 4);
int i = std::countr_zero(bitfield) / 4;
if (i < self->numChildren - 1) {
memmove(self16->index + i + 1, self16->index + i,
self->numChildren - (i + 1));
memmove(self16->children + i + 1, self16->children + i,
(self->numChildren - (i + 1)) * sizeof(Child));
}
#else
int i = 0;
for (; i < int(self->numChildren) - 1; ++i) {
if (int(self16->index[i]) > int(index)) {
@@ -963,6 +1001,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
break;
}
}
#endif
self16->index[i] = index;
auto &result = self16->children[i].child;
result = nullptr;
@@ -978,8 +1017,8 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
self = newSelf;
goto insert256;
}
insert48:
insert48:
auto *self48 = static_cast<Node48 *>(self);
self48->bitSet.set(index);
++self->numChildren;
@@ -991,6 +1030,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
return result;
}
case Type_Node256: {
insert256:
auto *self256 = static_cast<Node256 *>(self);
++self->numChildren;
@@ -2574,7 +2614,7 @@ int64_t ConflictSet::getBytes() const { return impl->totalBytes; }
ConflictSet::ConflictSet(int64_t oldestVersion)
: impl((mallocBytesDelta = 0,
new (safe_malloc(sizeof(Impl))) Impl{oldestVersion})) {
new(safe_malloc(sizeof(Impl))) Impl{oldestVersion})) {
impl->totalBytes += mallocBytesDelta;
}
@@ -2857,8 +2897,8 @@ Iterator firstGeq(Node *n, std::string_view key) {
}
}
bool checkCorrectness(Node *node, int64_t oldestVersion,
ConflictSet::Impl *impl) {
[[maybe_unused]] bool checkCorrectness(Node *node, int64_t oldestVersion,
ConflictSet::Impl *impl) {
bool success = true;
checkParentPointers(node, success);

View File

@@ -99,7 +99,7 @@ void ConflictSet::setOldestVersion(int64_t oldestVersion) {
int64_t ConflictSet::getBytes() const { return -1; }
ConflictSet::ConflictSet(int64_t oldestVersion)
: impl(new (safe_malloc(sizeof(Impl))) Impl{oldestVersion}) {}
: impl(new(safe_malloc(sizeof(Impl))) Impl{oldestVersion}) {}
ConflictSet::~ConflictSet() {
if (impl) {

View File

@@ -2,6 +2,8 @@
#include "ConflictSet.h"
using namespace weaselab;
#include <bit>
#include <cassert>
#include <compare>
@@ -60,6 +62,10 @@ inline int64_t peakMallocBytes = 0;
inline thread_local int64_t mallocBytesDelta = 0;
#ifndef NDEBUG
constexpr auto kMallocHeaderSize = 16;
#endif
// malloc that aborts on OOM and thus always returns a non-null pointer. Must be
// paired with `safe_free`.
__attribute__((always_inline)) inline void *safe_malloc(size_t s) {
@@ -69,18 +75,20 @@ __attribute__((always_inline)) inline void *safe_malloc(size_t s) {
if (mallocBytes > peakMallocBytes) {
peakMallocBytes = mallocBytes;
}
void *p = malloc(s);
if (p == nullptr) {
abort();
}
return p;
#else
void *p = malloc(s);
if (p == nullptr) {
abort();
}
return p;
#endif
void *p = malloc(s
#ifndef NDEBUG
+ kMallocHeaderSize
#endif
);
if (p == nullptr) {
abort();
}
#ifndef NDEBUG
memcpy(p, &s, sizeof(s));
(char *&)p += kMallocHeaderSize;
#endif
return p;
}
// Must be paired with `safe_malloc`.
@@ -93,6 +101,12 @@ __attribute__((always_inline)) inline void safe_free(void *p, size_t s) {
mallocBytes -= s;
free(p);
#else
#ifndef NDEBUG
(char *&)p -= kMallocHeaderSize;
size_t expected;
memcpy(&expected, p, sizeof(expected));
assert(s == expected);
#endif
free(p);
#endif
}
@@ -140,6 +154,7 @@ inline void *operator new[](size_t size, std::align_val_t align,
/// align must be a power of two
template <class T> T *align_up(T *t, size_t align) {
assert(std::popcount(align) == 1);
auto unaligned = uintptr_t(t);
auto aligned = (unaligned + align - 1) & ~(align - 1);
return reinterpret_cast<T *>(reinterpret_cast<char *>(t) + aligned -
@@ -148,6 +163,7 @@ template <class T> T *align_up(T *t, size_t align) {
/// align must be a power of two
constexpr inline int align_up(uint32_t unaligned, uint32_t align) {
assert(std::popcount(align) == 1);
return (unaligned + align - 1) & ~(align - 1);
}
@@ -163,12 +179,10 @@ struct Arena::ArenaImpl {
uint8_t *begin() { return reinterpret_cast<uint8_t *>(this + 1); }
};
static_assert(sizeof(Arena::ArenaImpl) == 16);
static_assert(alignof(Arena::ArenaImpl) == 8);
inline Arena::Arena(int initialSize) : impl(nullptr) {
if (initialSize > 0) {
auto allocationSize = align_up(initialSize + sizeof(ArenaImpl), 16);
auto allocationSize =
align_up(initialSize + sizeof(ArenaImpl), alignof(ArenaImpl));
impl = (Arena::ArenaImpl *)safe_malloc(allocationSize);
impl->prev = nullptr;
impl->capacity = allocationSize - sizeof(ArenaImpl);
@@ -204,7 +218,7 @@ inline void *operator new(size_t size, std::align_val_t align, Arena &arena) {
(arena.impl ? std::max<int>(sizeof(Arena::ArenaImpl),
arena.impl->capacity * 2)
: 0)),
16);
alignof(Arena::ArenaImpl));
auto *impl = (Arena::ArenaImpl *)safe_malloc(allocationSize);
impl->prev = arena.impl;
impl->capacity = allocationSize - sizeof(Arena::ArenaImpl);

11
Jenkinsfile vendored
View File

@@ -48,6 +48,17 @@ pipeline {
recordIssues(tools: [clang()])
}
}
stage('SIMD fallback') {
agent {
dockerfile {
args '-v /home/jenkins/ccache:/ccache'
reuseNode true
}
}
steps {
CleanBuildAndTest("-DUSE_SIMD_FALLBACK=ON")
}
}
stage('Release [gcc]') {
agent {
dockerfile {

View File

@@ -9,23 +9,23 @@ Hardware for all benchmarks is a mac m1 2020.
## Skip list
```
New conflict set: 1.962 sec
0.637 Mtransactions/sec
2.548 Mkeys/sec
Detect only: 1.842 sec
0.679 Mtransactions/sec
2.714 Mkeys/sec
Skiplist only: 1.261 sec
0.991 Mtransactions/sec
3.964 Mkeys/sec
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.0597
Add: 0.0587
Build: 0.0546
Add: 0.0563
Detect: 1.84
D.Sort: 0.411
D.Combine: 0.0136
D.CheckRead: 0.67
D.CheckIntraBatch: 0.00671
D.Sort: 0.412
D.Combine: 0.0141
D.CheckRead: 0.671
D.CheckIntraBatch: 0.0068
D.MergeWrite: 0.592
D.RemoveBefore: 0.146
```
@@ -33,25 +33,25 @@ Performance counters:
## Radix tree (this implementation)
```
New conflict set: 1.285 sec
0.973 Mtransactions/sec
3.892 Mkeys/sec
Detect only: 1.196 sec
1.045 Mtransactions/sec
4.180 Mkeys/sec
Skiplist only: 0.539 sec
2.320 Mtransactions/sec
9.281 Mkeys/sec
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.0377
Add: 0.0493
Detect: 1.2
D.Sort: 0.41
D.Combine: 0.0135
D.CheckRead: 0.219
D.CheckIntraBatch: 0.00654
D.MergeWrite: 0.319
D.RemoveBefore: 0.224
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

View File

@@ -1,13 +1,18 @@
#include <ConflictSet.h>
#include <cerrno>
#include <chrono>
#include <cstdio>
#include <cstring>
#include <fcntl.h>
#include <string_view>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <vector>
using namespace weaselab;
double now() {
return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now().time_since_epoch())
@@ -28,7 +33,7 @@ constexpr inline size_t rightAlign(size_t offset, size_t alignment) {
int main(int argc, const char **argv) {
// Use with this dataset https://snap.stanford.edu/data/memetracker9.html
// Preprocess the files with `sed -i '' '/^Q/d'`
// Preprocess the files with `sed -i'' '/^Q/d'`
double checkTime = 0;
double addTime = 0;
@@ -129,4 +134,4 @@ int main(int argc, const char **argv) {
checkTime, checkBytes / checkTime * 1e-6, addTime,
addBytes / addTime * 1e-6, gcTime / (gcTime + addTime) * 1e2,
double(peakMemory));
}
}

View File

@@ -669,7 +669,7 @@ int64_t ConflictSet::getBytes() const { return impl->totalBytes; }
ConflictSet::ConflictSet(int64_t oldestVersion)
: impl((mallocBytesDelta = 0,
new (safe_malloc(sizeof(Impl))) Impl{oldestVersion})) {
new(safe_malloc(sizeof(Impl))) Impl{oldestVersion})) {
impl->totalBytes += mallocBytesDelta;
}

View 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

17
apple-symbol-exports.txt Normal file
View File

@@ -0,0 +1,17 @@
_ConflictSet_addWrites
_ConflictSet_check
_ConflictSet_create
_ConflictSet_destroy
_ConflictSet_getBytes
_ConflictSet_setOldestVersion
__ZN8weaselab11ConflictSet16setOldestVersionEx
__ZN8weaselab11ConflictSet9addWritesEPKNS0_10WriteRangeEix
__ZN8weaselab11ConflictSetC1EOS0_
__ZN8weaselab11ConflictSetC1Ex
__ZN8weaselab11ConflictSetC2EOS0_
__ZN8weaselab11ConflictSetC2Ex
__ZN8weaselab11ConflictSetD1Ev
__ZN8weaselab11ConflictSetD2Ev
__ZN8weaselab11ConflictSetaSEOS0_
__ZNK8weaselab11ConflictSet5checkEPKNS0_9ReadRangeEPNS0_6ResultEi
__ZNK8weaselab11ConflictSet8getBytesEv

7
apple-symbol-imports.txt Normal file
View File

@@ -0,0 +1,7 @@
__tlv_bootstrap
_abort
_bzero
_free
_malloc
_memcpy
_memmove

View File

@@ -2,6 +2,8 @@
#include <cassert>
using namespace weaselab;
int main(void) {
ConflictSet cs(0);
ConflictSet::WriteRange w;

View File

@@ -1,32 +1,19 @@
giff --git a/fdbserver/CMakeLists.txt b/fdbserver/CMakeLists.txt
index 3f353c2ef..cd0834761 100644
diff --git a/fdbserver/CMakeLists.txt b/fdbserver/CMakeLists.txt
index 3f353c2ef..074a18628 100644
--- a/fdbserver/CMakeLists.txt
+++ b/fdbserver/CMakeLists.txt
@@ -22,6 +22,9 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/workloads)
add_flow_target(EXECUTABLE NAME fdbserver SRCS ${FDBSERVER_SRCS})
+find_package(ConflictSet)
+target_link_libraries(fdbserver PRIVATE conflict_set_static)
+find_package(conflict-set)
+target_link_libraries(fdbserver PRIVATE conflict-set-static)
+
if (WITH_SWIFT)
# Setup the Swift sources in FDBServer.
include(FindSwiftLibs)
diff --git a/fdbserver/Resolver.actor.cpp b/fdbserver/Resolver.actor.cpp
index bf4118f5f..d3b4eaad8 100644
--- a/fdbserver/Resolver.actor.cpp
+++ b/fdbserver/Resolver.actor.cpp
@@ -132,7 +132,7 @@ struct Resolver : ReferenceCounted<Resolver> {
AsyncVar<int64_t> totalStateBytes;
AsyncTrigger checkNeededVersion;
std::map<NetworkAddress, ProxyRequestsInfo> proxyInfoMap;
- ConflictSet* conflictSet;
+ ConflictSet2* conflictSet;
TransientStorageMetricSample iopsSample;
// Use LogSystem as backend for txnStateStore. However, the real commit
diff --git a/fdbserver/SkipList.cpp b/fdbserver/SkipList.cpp
index b48d32c6b..da106b5d2 100644
index b48d32c6b..da99e03aa 100644
--- a/fdbserver/SkipList.cpp
+++ b/fdbserver/SkipList.cpp
@@ -25,6 +25,7 @@
@@ -46,50 +33,35 @@ index b48d32c6b..da106b5d2 100644
static std::vector<PerfDoubleCounter*> skc;
static thread_local uint32_t g_seed = 0;
@@ -782,26 +785,34 @@ private:
}
@@ -783,10 +786,14 @@ private:
};
-struct ConflictSet {
struct ConflictSet {
- ConflictSet() : removalKey(makeString(0)), oldestVersion(0) {}
- ~ConflictSet() {}
+struct ConflictSet2 {
+ ConflictSet2() : versionHistory(0), removalKey(makeString(0)), oldestVersion(0) {}
+ ~ConflictSet2() {}
+ ConflictSet() : versionHistory(0), removalKey(makeString(0)), oldestVersion(0) {}
~ConflictSet() {}
+#if USE_RADIX_TREE
+ ConflictSet versionHistory;
+ weaselab::ConflictSet versionHistory;
+#else
SkipList versionHistory;
+#endif
Key removalKey;
Version oldestVersion;
};
-ConflictSet* newConflictSet() {
- return new ConflictSet;
+ConflictSet2* newConflictSet() {
+ return new ConflictSet2;
@@ -795,7 +802,11 @@ ConflictSet* newConflictSet() {
return new ConflictSet;
}
-void clearConflictSet(ConflictSet* cs, Version v) {
void clearConflictSet(ConflictSet* cs, Version v) {
- SkipList(v).swap(cs->versionHistory);
+void clearConflictSet(ConflictSet2* cs, Version v) {
+#if USE_RADIX_TREE
+ cs->versionHistory = ConflictSet{ 0 };
+ cs->versionHistory = weaselab::ConflictSet{ 0 };
+#else
+ SkipList().swap(cs->versionHistory);
+#endif
}
-void destroyConflictSet(ConflictSet* cs) {
+void destroyConflictSet(ConflictSet2* cs) {
void destroyConflictSet(ConflictSet* cs) {
delete cs;
}
-ConflictBatch::ConflictBatch(ConflictSet* cs,
+ConflictBatch::ConflictBatch(ConflictSet2* cs,
std::map<int, VectorRef<int>>* conflictingKeyRangeMap,
Arena* resolveBatchReplyArena)
: cs(cs), transactionCount(0), conflictingKeyRangeMap(conflictingKeyRangeMap),
@@ -971,11 +982,15 @@ void ConflictBatch::detectConflicts(Version now,
t = timer();
if (newOldestVersion > cs->oldestVersion) {
@@ -112,7 +84,7 @@ index b48d32c6b..da106b5d2 100644
+#if USE_RADIX_TREE
+ Arena arena;
+ auto* reads = new (arena) ConflictSet::ReadRange[combinedReadConflictRanges.size()];
+ auto* reads = new (arena) weaselab::ConflictSet::ReadRange[combinedReadConflictRanges.size()];
+
+ for (int i = 0; i < combinedReadConflictRanges.size(); ++i) {
+ auto& read = reads[i];
@@ -122,11 +94,11 @@ index b48d32c6b..da106b5d2 100644
+ read.end.p = combinedReadConflictRanges[i].end.begin();
+ read.end.len = combinedReadConflictRanges[i].end.size();
+ }
+ auto* results = new (arena) ConflictSet::Result[combinedReadConflictRanges.size()];
+ auto* results = new (arena) weaselab::ConflictSet::Result[combinedReadConflictRanges.size()];
+ cs->versionHistory.check(reads, results, combinedReadConflictRanges.size());
+
+ for (int i = 0; i < combinedReadConflictRanges.size(); ++i) {
+ if (results[i] == ConflictSet::Conflict) {
+ if (results[i] == weaselab::ConflictSet::Conflict) {
+ transactionConflictStatus[combinedReadConflictRanges[i].transaction] = true;
+ if (combinedReadConflictRanges[i].conflictingKeyRange != nullptr) {
+ combinedReadConflictRanges[i].conflictingKeyRange->push_back(*combinedReadConflictRanges[i].cKRArena,
@@ -147,7 +119,7 @@ index b48d32c6b..da106b5d2 100644
+#if USE_RADIX_TREE
+ Arena arena;
+ auto* writes = new (arena) ConflictSet::WriteRange[combinedWriteConflictRanges.size()];
+ auto* writes = new (arena) weaselab::ConflictSet::WriteRange[combinedWriteConflictRanges.size()];
+
+ for (int i = 0; i < combinedWriteConflictRanges.size(); ++i) {
+ auto& write = writes[i];
@@ -164,15 +136,6 @@ index b48d32c6b..da106b5d2 100644
}
void ConflictBatch::combineWriteConflictRanges() {
@@ -1115,7 +1171,7 @@ void skipListTest() {
double start;
- ConflictSet* cs = newConflictSet();
+ ConflictSet2* cs = newConflictSet();
Arena testDataArena;
VectorRef<VectorRef<KeyRangeRef>> testData;
@@ -1197,6 +1253,4 @@ void skipListTest() {
for (const auto& counter : skc) {
printf("%20s: %s\n", counter->getMetric().name().c_str(), counter->getMetric().formatted().c_str());
@@ -180,35 +143,3 @@ index b48d32c6b..da106b5d2 100644
-
- printf("%d entries in version history\n", cs->versionHistory.count());
}
diff --git a/fdbserver/include/fdbserver/ConflictSet.h b/fdbserver/include/fdbserver/ConflictSet.h
index 90ed2c406..b7e31217c 100644
--- a/fdbserver/include/fdbserver/ConflictSet.h
+++ b/fdbserver/include/fdbserver/ConflictSet.h
@@ -28,13 +28,13 @@
#include "fdbclient/CommitTransaction.h"
#include "fdbserver/ResolverBug.h"
-struct ConflictSet;
-ConflictSet* newConflictSet();
-void clearConflictSet(ConflictSet*, Version);
-void destroyConflictSet(ConflictSet*);
+struct ConflictSet2;
+ConflictSet2* newConflictSet();
+void clearConflictSet(ConflictSet2*, Version);
+void destroyConflictSet(ConflictSet2*);
struct ConflictBatch {
- explicit ConflictBatch(ConflictSet*,
+ explicit ConflictBatch(ConflictSet2*,
std::map<int, VectorRef<int>>* conflictingKeyRangeMap = nullptr,
Arena* resolveBatchReplyArena = nullptr);
~ConflictBatch();
@@ -54,7 +54,7 @@ struct ConflictBatch {
void GetTooOldTransactions(std::vector<int>& tooOldTransactions);
private:
- ConflictSet* cs;
+ ConflictSet2* cs;
Standalone<VectorRef<struct TransactionInfo*>> transactionInfo;
std::vector<struct KeyInfo> points;
int transactionCount;

View File

@@ -19,6 +19,7 @@ limitations under the License.
#include <stdint.h>
#ifdef __cplusplus
namespace weaselab {
/** A data structure for optimistic concurrency control on ranges of
* bitwise-lexicographically-ordered keys.
*
@@ -100,6 +101,7 @@ struct __attribute__((__visibility__("default"))) ConflictSet {
private:
Impl *impl;
};
} /* namespace weaselab */
#else

6
privatize_symbols_macos.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
# This has the effect of making visibility=hidden symbols private in object files
for obj in "$@" ; do
ld -r "$obj" -o "$obj.tmp" && mv "$obj.tmp" "$obj"
done

17
symbol-exports.txt Normal file
View File

@@ -0,0 +1,17 @@
ConflictSet_addWrites
ConflictSet_check
ConflictSet_create
ConflictSet_destroy
ConflictSet_getBytes
ConflictSet_setOldestVersion
_ZN8weaselab11ConflictSet16setOldestVersionEl
_ZN8weaselab11ConflictSet9addWritesEPKNS0_10WriteRangeEil
_ZN8weaselab11ConflictSetaSEOS0_
_ZN8weaselab11ConflictSetC1El
_ZN8weaselab11ConflictSetC1EOS0_
_ZN8weaselab11ConflictSetC2El
_ZN8weaselab11ConflictSetC2EOS0_
_ZN8weaselab11ConflictSetD1Ev
_ZN8weaselab11ConflictSetD2Ev
_ZNK8weaselab11ConflictSet5checkEPKNS0_9ReadRangeEPNS0_6ResultEi
_ZNK8weaselab11ConflictSet8getBytesEv

9
symbol-imports.txt Normal file
View File

@@ -0,0 +1,9 @@
_GLOBAL_OFFSET_TABLE_
__stack_chk_fail@GLIBC_2.4
__tls_get_addr@GLIBC_2.3
abort@GLIBC_2.2.5
free@GLIBC_2.2.5
malloc@GLIBC_2.2.5
memcpy@GLIBC_2.14
memmove@GLIBC_2.2.5
memset@GLIBC_2.2.5

View File

@@ -1,17 +0,0 @@
ConflictSet_addWrites
ConflictSet_check
ConflictSet_create
ConflictSet_destroy
ConflictSet_getBytes
ConflictSet_setOldestVersion
_ZN11ConflictSet16setOldestVersionEl
_ZN11ConflictSet9addWritesEPKNS_10WriteRangeEil
_ZN11ConflictSetaSEOS_
_ZN11ConflictSetC1El
_ZN11ConflictSetC1EOS_
_ZN11ConflictSetC2El
_ZN11ConflictSetC2EOS_
_ZN11ConflictSetD1Ev
_ZN11ConflictSetD2Ev
_ZNK11ConflictSet5checkEPKNS_9ReadRangeEPNS_6ResultEi
_ZNK11ConflictSet8getBytesEv

View File

@@ -2,5 +2,15 @@
set -euo pipefail
# ./test_symbols.sh <library> <expected exported symbols file> <allowed imported symbols file>
diff -u <(sort < "$2") <(nm "$1" | grep " T " | cut -f3 -d " " | sort)
nm "$1" | grep " U " | (! grep -Pv 'abort|free|malloc|mem[a-z]*|__ashlti3|__stack_chk_[a-z]*|__tls_get_addr|_GLOBAL_OFFSET_TABLE_')
ec=0
for symbol in $(nm "$1" | grep " U " | sed 's/ U //') ; do
if ! grep --fixed-strings "$symbol" "$3" > /dev/null ; then
echo "Imported symbol $symbol not present in $3"
ec=1
fi
done
exit $ec