C89, C++98 api smoke tests
This commit is contained in:
@@ -3,9 +3,11 @@ project(
|
|||||||
conflict-set
|
conflict-set
|
||||||
VERSION 0.0.1
|
VERSION 0.0.1
|
||||||
DESCRIPTION "A data structure for detecting mvcc read-write conflicts in a keyspace of lexicographically-ordered byte sequences."
|
DESCRIPTION "A data structure for detecting mvcc read-write conflicts in a keyspace of lexicographically-ordered byte sequences."
|
||||||
LANGUAGES CXX)
|
LANGUAGES C CXX)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_C_STANDARD 11)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
add_library(conflict_set SHARED ConflictSet.cpp ConflictSet.h)
|
add_library(conflict_set SHARED ConflictSet.cpp ConflictSet.h)
|
||||||
target_compile_options(conflict_set PRIVATE -fno-exceptions -fvisibility=hidden)
|
target_compile_options(conflict_set PRIVATE -fno-exceptions -fvisibility=hidden)
|
||||||
@@ -17,9 +19,25 @@ target_compile_definitions(conflict_set_test PRIVATE ENABLE_TESTS)
|
|||||||
# keep asserts for test
|
# keep asserts for test
|
||||||
target_compile_options(conflict_set_test PRIVATE -UNDEBUG)
|
target_compile_options(conflict_set_test PRIVATE -UNDEBUG)
|
||||||
# Only emit compile warnings for test
|
# Only emit compile warnings for test
|
||||||
target_compile_options(conflict_set_test PRIVATE -Wall -Wextra -Wpedantic -Wunreachable-code)
|
target_compile_options(conflict_set_test PRIVATE -Wall -Wextra -Wpedantic -Wunreachable-code -Werror)
|
||||||
|
|
||||||
# TODO add a smoke test for the public api (c++11, c99)?
|
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
add_test(NAME conflict_set_test COMMAND conflict_set_test)
|
add_test(NAME conflict_set_test COMMAND conflict_set_test)
|
||||||
|
|
||||||
|
# api smoke tests
|
||||||
|
|
||||||
|
# c89
|
||||||
|
add_executable(conflict_set_c_api_test conflict_set_c_api_test.c ConflictSet.h)
|
||||||
|
target_link_libraries(conflict_set_c_api_test PRIVATE conflict_set)
|
||||||
|
target_compile_options(conflict_set_c_api_test PRIVATE -UNDEBUG)
|
||||||
|
set_property(TARGET conflict_set_c_api_test PROPERTY C_STANDARD 90)
|
||||||
|
add_test(NAME conflict_set_c_api_test COMMAND conflict_set_c_api_test)
|
||||||
|
target_compile_options(conflict_set_c_api_test PRIVATE -Wall -Wextra -Wpedantic -Wunreachable-code -Werror)
|
||||||
|
|
||||||
|
# c++98
|
||||||
|
add_executable(conflict_set_cxx_api_test conflict_set_cxx_api_test.cpp ConflictSet.h)
|
||||||
|
target_link_libraries(conflict_set_cxx_api_test PRIVATE conflict_set)
|
||||||
|
target_compile_options(conflict_set_cxx_api_test PRIVATE -UNDEBUG)
|
||||||
|
set_property(TARGET conflict_set_cxx_api_test PROPERTY CXX_STANDARD 98)
|
||||||
|
add_test(NAME conflict_set_cxx_api_test COMMAND conflict_set_cxx_api_test)
|
||||||
|
target_compile_options(conflict_set_cxx_api_test PRIVATE -Wall -Wextra -Wpedantic -Wunreachable-code -Werror)
|
@@ -15,7 +15,7 @@ struct __attribute__((__visibility__("default"))) ConflictSet {
|
|||||||
Conflict,
|
Conflict,
|
||||||
/// The result of a check with a readVersion older than the highest call to
|
/// The result of a check with a readVersion older than the highest call to
|
||||||
/// `setOldestVersion`
|
/// `setOldestVersion`
|
||||||
TooOld,
|
TooOld
|
||||||
};
|
};
|
||||||
/// Bytes ordered lexicographically
|
/// Bytes ordered lexicographically
|
||||||
struct Key {
|
struct Key {
|
||||||
@@ -57,10 +57,12 @@ struct __attribute__((__visibility__("default"))) ConflictSet {
|
|||||||
explicit ConflictSet(int64_t oldestVersion);
|
explicit ConflictSet(int64_t oldestVersion);
|
||||||
~ConflictSet();
|
~ConflictSet();
|
||||||
|
|
||||||
|
#if __cplusplus > 199711L
|
||||||
ConflictSet(ConflictSet &&) noexcept;
|
ConflictSet(ConflictSet &&) noexcept;
|
||||||
ConflictSet &operator=(ConflictSet &&) noexcept;
|
ConflictSet &operator=(ConflictSet &&) noexcept;
|
||||||
ConflictSet(const ConflictSet &) = delete;
|
ConflictSet(const ConflictSet &) = delete;
|
||||||
ConflictSet &operator=(const ConflictSet &) = delete;
|
ConflictSet &operator=(const ConflictSet &) = delete;
|
||||||
|
#endif
|
||||||
|
|
||||||
/// @private
|
/// @private
|
||||||
struct Impl;
|
struct Impl;
|
||||||
@@ -75,7 +77,7 @@ private:
|
|||||||
|
|
||||||
typedef struct ConflictSet ConflictSet;
|
typedef struct ConflictSet ConflictSet;
|
||||||
|
|
||||||
enum ConflictSet_Result {
|
typedef enum {
|
||||||
/// The result of a check which does not intersect any conflicting writes
|
/// The result of a check which does not intersect any conflicting writes
|
||||||
ConflictSet_Commit,
|
ConflictSet_Commit,
|
||||||
/// The result of a check which intersects a write at a version >
|
/// The result of a check which intersects a write at a version >
|
||||||
@@ -83,23 +85,23 @@ enum ConflictSet_Result {
|
|||||||
ConflictSet_Conflict,
|
ConflictSet_Conflict,
|
||||||
/// The result of a check with a readVersion older than the highest call to
|
/// The result of a check with a readVersion older than the highest call to
|
||||||
/// `setOldestVersion`
|
/// `setOldestVersion`
|
||||||
ConflictSet_TooOld,
|
ConflictSet_TooOld
|
||||||
};
|
} ConflictSet_Result;
|
||||||
/// Bytes ordered lexicographically
|
/// Bytes ordered lexicographically
|
||||||
struct ConflictSet_Key {
|
typedef struct {
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
int len;
|
int len;
|
||||||
};
|
} ConflictSet_Key;
|
||||||
/// Denotes a set of keys to be checked for conflicts
|
/// Denotes a set of keys to be checked for conflicts
|
||||||
struct ConflictSet_ReadRange {
|
typedef struct {
|
||||||
ConflictSet_Key begin;
|
ConflictSet_Key begin;
|
||||||
/// `end` having length 0 denotes that this range is the single key {begin}.
|
/// `end` having length 0 denotes that this range is the single key {begin}.
|
||||||
/// Otherwise this denotes the range [begin, end)
|
/// Otherwise this denotes the range [begin, end)
|
||||||
ConflictSet_Key end;
|
ConflictSet_Key end;
|
||||||
int64_t readVersion;
|
int64_t readVersion;
|
||||||
};
|
} ConflictSet_ReadRange;
|
||||||
/// Denotes a set of keys to be considered written at `writeVersion`
|
/// Denotes a set of keys to be considered written at `writeVersion`
|
||||||
struct ConflictSet_WriteRange {
|
typedef struct {
|
||||||
ConflictSet_Key begin;
|
ConflictSet_Key begin;
|
||||||
/// `end` having length 0 denotes that this range is the single key {begin}.
|
/// `end` having length 0 denotes that this range is the single key {begin}.
|
||||||
/// Otherwise this denotes the range [begin, end)
|
/// Otherwise this denotes the range [begin, end)
|
||||||
@@ -107,7 +109,7 @@ struct ConflictSet_WriteRange {
|
|||||||
/// Write version must be greater than all write versions in all previous
|
/// Write version must be greater than all write versions in all previous
|
||||||
/// calls to `addWrites`
|
/// calls to `addWrites`
|
||||||
int64_t writeVersion;
|
int64_t writeVersion;
|
||||||
};
|
} ConflictSet_WriteRange;
|
||||||
|
|
||||||
/// `reads` must be sorted ascending, and must not have adjacent or
|
/// `reads` must be sorted ascending, and must not have adjacent or
|
||||||
/// overlapping ranges. The result of checking reads[i] is written in
|
/// overlapping ranges. The result of checking reads[i] is written in
|
||||||
@@ -127,4 +129,4 @@ void ConflictSet_setOldestVersion(ConflictSet *cs, int64_t oldestVersion);
|
|||||||
ConflictSet *ConflictSet_create(int64_t oldestVersion);
|
ConflictSet *ConflictSet_create(int64_t oldestVersion);
|
||||||
void ConflictSet_destroy(ConflictSet *cs);
|
void ConflictSet_destroy(ConflictSet *cs);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
22
conflict_set_c_api_test.c
Normal file
22
conflict_set_c_api_test.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "ConflictSet.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
ConflictSet *cs = ConflictSet_create(0);
|
||||||
|
ConflictSet_WriteRange w;
|
||||||
|
ConflictSet_Result result;
|
||||||
|
ConflictSet_ReadRange r;
|
||||||
|
w.begin.p = (const uint8_t *)"0000";
|
||||||
|
w.begin.len = 4;
|
||||||
|
w.end.len = 0;
|
||||||
|
w.writeVersion = 1;
|
||||||
|
ConflictSet_addWrites(cs, &w, 1);
|
||||||
|
r.begin.p = (const uint8_t *)"0000";
|
||||||
|
r.begin.len = 4;
|
||||||
|
r.end.len = 0;
|
||||||
|
r.readVersion = 0;
|
||||||
|
ConflictSet_check(cs, &r, &result, 1);
|
||||||
|
assert(result == ConflictSet_Conflict);
|
||||||
|
ConflictSet_destroy(cs);
|
||||||
|
}
|
21
conflict_set_cxx_api_test.cpp
Normal file
21
conflict_set_cxx_api_test.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include "ConflictSet.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
ConflictSet cs(0);
|
||||||
|
ConflictSet::WriteRange w;
|
||||||
|
w.begin.p = (const uint8_t *)"0000";
|
||||||
|
w.begin.len = 4;
|
||||||
|
w.end.len = 0;
|
||||||
|
w.writeVersion = 1;
|
||||||
|
cs.addWrites(&w, 1);
|
||||||
|
ConflictSet::Result result;
|
||||||
|
ConflictSet::ReadRange r;
|
||||||
|
r.begin.p = (const uint8_t *)"0000";
|
||||||
|
r.begin.len = 4;
|
||||||
|
r.end.len = 0;
|
||||||
|
r.readVersion = 0;
|
||||||
|
cs.check(&r, &result, 1);
|
||||||
|
assert(result == ConflictSet::Conflict);
|
||||||
|
}
|
Reference in New Issue
Block a user