#pragma once #include #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