133 lines
4.6 KiB
C++
133 lines
4.6 KiB
C++
#pragma once
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
|
|
// c++ api
|
|
|
|
struct __attribute__((__visibility__("default"))) ConflictSet {
|
|
enum Result {
|
|
/// The result of a check which does not intersect any conflicting writes
|
|
Commit,
|
|
/// The result of a check which intersects a write at a version >
|
|
/// readVersion
|
|
Conflict,
|
|
/// The result of a check with a readVersion older than the highest call to
|
|
/// `setOldestVersion`
|
|
TooOld
|
|
};
|
|
/// Bytes ordered lexicographically
|
|
struct Key {
|
|
const uint8_t *p;
|
|
int len;
|
|
};
|
|
/// Denotes a set of keys to be checked for conflicts
|
|
struct ReadRange {
|
|
Key begin;
|
|
/// `end` having length 0 denotes that this range is the single key {begin}.
|
|
/// Otherwise this denotes the range [begin, end)
|
|
Key end;
|
|
int64_t readVersion;
|
|
};
|
|
/// Denotes a set of keys to be considered written at `writeVersion`
|
|
struct WriteRange {
|
|
Key begin;
|
|
/// `end` having length 0 denotes that this range is the single key {begin}.
|
|
/// Otherwise this denotes the range [begin, end)
|
|
Key end;
|
|
/// Write version must be greater than all write versions in all previous
|
|
/// calls to `addWrites`
|
|
int64_t writeVersion;
|
|
};
|
|
/// `reads` must be sorted ascending, and must not have adjacent or
|
|
/// overlapping ranges. The result of checking reads[i] is written in
|
|
/// results[i].
|
|
void check(const ReadRange *reads, Result *results, int count) const;
|
|
/// `writes` must be sorted ascending, and must not have adjacent or
|
|
/// overlapping ranges. Reads intersecting writes where readVersion <
|
|
/// writeVersion will result in `Conflict` (or `TooOld`, eventually)
|
|
void addWrites(const WriteRange *writes, int count);
|
|
/// Reads where readVersion < oldestVersion will result in `TooOld`. Must be
|
|
/// greater than any previous oldestVersion.
|
|
void setOldestVersion(int64_t oldestVersion);
|
|
|
|
/// Reads where readVersion < oldestVersion will result in `TooOld`. There are
|
|
/// no writes initially.
|
|
explicit ConflictSet(int64_t oldestVersion, uint64_t seed);
|
|
~ConflictSet();
|
|
|
|
#if __cplusplus > 199711L
|
|
ConflictSet(ConflictSet &&) noexcept;
|
|
ConflictSet &operator=(ConflictSet &&) noexcept;
|
|
ConflictSet(const ConflictSet &) = delete;
|
|
ConflictSet &operator=(const ConflictSet &) = delete;
|
|
#endif
|
|
|
|
/// @private
|
|
struct Impl;
|
|
|
|
private:
|
|
Impl *impl;
|
|
};
|
|
|
|
#else
|
|
|
|
// c api
|
|
|
|
typedef struct ConflictSet ConflictSet;
|
|
|
|
typedef enum {
|
|
/// The result of a check which does not intersect any conflicting writes
|
|
ConflictSet_Commit,
|
|
/// The result of a check which intersects a write at a version >
|
|
/// readVersion
|
|
ConflictSet_Conflict,
|
|
/// The result of a check with a readVersion older than the highest call to
|
|
/// `setOldestVersion`
|
|
ConflictSet_TooOld
|
|
} ConflictSet_Result;
|
|
/// Bytes ordered lexicographically
|
|
typedef struct {
|
|
const uint8_t *p;
|
|
int len;
|
|
} ConflictSet_Key;
|
|
/// Denotes a set of keys to be checked for conflicts
|
|
typedef struct {
|
|
ConflictSet_Key begin;
|
|
/// `end` having length 0 denotes that this range is the single key {begin}.
|
|
/// Otherwise this denotes the range [begin, end)
|
|
ConflictSet_Key end;
|
|
int64_t readVersion;
|
|
} ConflictSet_ReadRange;
|
|
/// Denotes a set of keys to be considered written at `writeVersion`
|
|
typedef struct {
|
|
ConflictSet_Key begin;
|
|
/// `end` having length 0 denotes that this range is the single key {begin}.
|
|
/// Otherwise this denotes the range [begin, end)
|
|
ConflictSet_Key end;
|
|
/// Write version must be greater than all write versions in all previous
|
|
/// calls to `addWrites`
|
|
int64_t writeVersion;
|
|
} ConflictSet_WriteRange;
|
|
|
|
/// `reads` must be sorted ascending, and must not have adjacent or
|
|
/// overlapping ranges. The result of checking reads[i] is written in
|
|
/// results[i].
|
|
void ConflictSet_check(ConflictSet *cs, const ConflictSet_ReadRange *reads,
|
|
ConflictSet_Result *results, int count);
|
|
/// `writes` must be sorted ascending, and must not have adjacent or
|
|
/// overlapping ranges. Reads intersecting writes where readVersion <
|
|
/// writeVersion will result in `Conflict` (or `TooOld`, eventually)
|
|
void ConflictSet_addWrites(ConflictSet *cs,
|
|
const ConflictSet_WriteRange *writes, int count);
|
|
/// Reads where readVersion < oldestVersion will result in `TooOld`. Must be
|
|
/// greater than any previous oldestVersion.
|
|
void ConflictSet_setOldestVersion(ConflictSet *cs, int64_t oldestVersion);
|
|
/// Reads where readVersion < oldestVersion will result in `TooOld`. There are
|
|
/// no writes initially.
|
|
ConflictSet *ConflictSet_create(int64_t oldestVersion, uint64_t seed);
|
|
void ConflictSet_destroy(ConflictSet *cs);
|
|
|
|
#endif
|