gcc fixes
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#define DEBUG_VERBOSE 0
|
#define DEBUG_VERBOSE 0
|
||||||
|
|
||||||
__attribute__((always_inline)) void *safe_malloc(size_t s) {
|
__attribute__((always_inline)) inline void *safe_malloc(size_t s) {
|
||||||
if (void *p = malloc(s)) {
|
if (void *p = malloc(s)) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -853,7 +853,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index) {
|
|||||||
}
|
}
|
||||||
if (self->numChildren == 4) {
|
if (self->numChildren == 4) {
|
||||||
auto *newSelf = new (safe_malloc(sizeof(Node16))) Node16;
|
auto *newSelf = new (safe_malloc(sizeof(Node16))) Node16;
|
||||||
memcpy(newSelf, self, offsetof(Node, type));
|
memcpy((void*)newSelf, self, offsetof(Node, type));
|
||||||
memcpy(newSelf->index, self4->index, 4);
|
memcpy(newSelf->index, self4->index, 4);
|
||||||
memcpy(newSelf->children, self4->children, 4 * sizeof(void *));
|
memcpy(newSelf->children, self4->children, 4 * sizeof(void *));
|
||||||
free(std::exchange(self, newSelf));
|
free(std::exchange(self, newSelf));
|
||||||
|
@@ -19,4 +19,5 @@ int main(void) {
|
|||||||
ConflictSet_check(cs, &r, &result, 1);
|
ConflictSet_check(cs, &r, &result, 1);
|
||||||
assert(result == ConflictSet_Conflict);
|
assert(result == ConflictSet_Conflict);
|
||||||
ConflictSet_destroy(cs);
|
ConflictSet_destroy(cs);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -4,56 +4,54 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
// c++ api
|
|
||||||
|
|
||||||
struct __attribute__((__visibility__("default"))) ConflictSet {
|
struct __attribute__((__visibility__("default"))) ConflictSet {
|
||||||
enum Result {
|
enum Result {
|
||||||
/// The result of a check which does not intersect any conflicting writes
|
/** The result of a check which does not intersect any conflicting writes */
|
||||||
Commit,
|
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 >
|
||||||
/// readVersion
|
readVersion */
|
||||||
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 {
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
int len;
|
int len;
|
||||||
};
|
};
|
||||||
/// Denotes a set of keys to be checked for conflicts
|
/** Denotes a set of keys to be checked for conflicts */
|
||||||
struct ReadRange {
|
struct ReadRange {
|
||||||
Key begin;
|
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) */
|
||||||
Key end;
|
Key end;
|
||||||
int64_t readVersion;
|
int64_t readVersion;
|
||||||
};
|
};
|
||||||
/// Denotes a set of keys to be considered written at `writeVersion`
|
/** Denotes a set of keys to be considered written at `writeVersion` */
|
||||||
struct WriteRange {
|
struct WriteRange {
|
||||||
Key begin;
|
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) */
|
||||||
Key end;
|
Key end;
|
||||||
/// 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;
|
||||||
};
|
};
|
||||||
/// `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
|
||||||
/// results[i].
|
* results[i]. */
|
||||||
void check(const ReadRange *reads, Result *results, int count) const;
|
void check(const ReadRange *reads, Result *results, int count) const;
|
||||||
/// `writes` must be sorted ascending, and must not have adjacent or
|
/** `writes` must be sorted ascending, and must not have adjacent or
|
||||||
/// overlapping ranges. Reads intersecting writes where readVersion <
|
* overlapping ranges. Reads intersecting writes where readVersion <
|
||||||
/// writeVersion will result in `Conflict` (or `TooOld`, eventually)
|
* writeVersion will result in `Conflict` (or `TooOld`, eventually) */
|
||||||
void addWrites(const WriteRange *writes, int count);
|
void addWrites(const WriteRange *writes, int count);
|
||||||
/// Reads where readVersion < oldestVersion will result in `TooOld`. Must be
|
/** Reads where readVersion < oldestVersion will result in `TooOld`. Must be
|
||||||
/// greater than any previous oldestVersion.
|
* greater than any previous oldestVersion. */
|
||||||
void setOldestVersion(int64_t oldestVersion);
|
void setOldestVersion(int64_t oldestVersion);
|
||||||
|
|
||||||
/// Reads where readVersion < oldestVersion will result in `TooOld`. There are
|
/** Reads where readVersion < oldestVersion will result in `TooOld`. There are
|
||||||
/// no writes initially.
|
* no writes initially. */
|
||||||
explicit ConflictSet(int64_t oldestVersion, uint64_t seed);
|
explicit ConflictSet(int64_t oldestVersion, uint64_t seed);
|
||||||
~ConflictSet();
|
~ConflictSet();
|
||||||
|
|
||||||
@@ -64,7 +62,7 @@ struct __attribute__((__visibility__("default"))) ConflictSet {
|
|||||||
ConflictSet &operator=(const ConflictSet &) = delete;
|
ConflictSet &operator=(const ConflictSet &) = delete;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// @private
|
/** @private */
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -73,59 +71,56 @@ private:
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// c api
|
|
||||||
|
|
||||||
typedef struct ConflictSet ConflictSet;
|
typedef struct ConflictSet ConflictSet;
|
||||||
|
|
||||||
typedef enum {
|
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 > readVersion
|
||||||
/* readVersion */
|
*/
|
||||||
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;
|
} ConflictSet_Result;
|
||||||
/* Bytes ordered lexicographically */
|
/** Bytes ordered lexicographically */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
int len;
|
int len;
|
||||||
} ConflictSet_Key;
|
} ConflictSet_Key;
|
||||||
/* Denotes a set of keys to be checked for conflicts */
|
/** Denotes a set of keys to be checked for conflicts */
|
||||||
typedef struct {
|
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;
|
} ConflictSet_ReadRange;
|
||||||
/* Denotes a set of keys to be considered written at `writeVersion` */
|
/** Denotes a set of keys to be considered written at `writeVersion` */
|
||||||
typedef struct {
|
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;
|
||||||
/* 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;
|
} 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
|
||||||
/* overlapping ranges. The result of checking reads[i] is written in */
|
* ranges. The result of checking reads[i] is written in results[i]. */
|
||||||
/* results[i]. */
|
|
||||||
void ConflictSet_check(ConflictSet *cs, const ConflictSet_ReadRange *reads,
|
void ConflictSet_check(ConflictSet *cs, const ConflictSet_ReadRange *reads,
|
||||||
ConflictSet_Result *results, int count);
|
ConflictSet_Result *results, int count);
|
||||||
/* `writes` must be sorted ascending, and must not have adjacent or */
|
/** `writes` must be sorted ascending, and must not have adjacent or overlapping
|
||||||
/* overlapping ranges. Reads intersecting writes where readVersion < */
|
* ranges. Reads intersecting writes where readVersion < writeVersion will
|
||||||
/* writeVersion will result in `Conflict` (or `TooOld`, eventually) */
|
* result in `Conflict` (or `TooOld`, eventually) */
|
||||||
void ConflictSet_addWrites(ConflictSet *cs,
|
void ConflictSet_addWrites(ConflictSet *cs,
|
||||||
const ConflictSet_WriteRange *writes, int count);
|
const ConflictSet_WriteRange *writes, int count);
|
||||||
/* Reads where readVersion < oldestVersion will result in `TooOld`. Must be */
|
/** Reads where readVersion < oldestVersion will result in `TooOld`. Must be
|
||||||
/* greater than any previous oldestVersion. */
|
* greater than any previous oldestVersion. */
|
||||||
void ConflictSet_setOldestVersion(ConflictSet *cs, int64_t oldestVersion);
|
void ConflictSet_setOldestVersion(ConflictSet *cs, int64_t oldestVersion);
|
||||||
/* Reads where readVersion < oldestVersion will result in `TooOld`. There are */
|
/** Reads where readVersion < oldestVersion will result in `TooOld`. There are
|
||||||
/* no writes initially. */
|
* no writes initially. */
|
||||||
ConflictSet *ConflictSet_create(int64_t oldestVersion, uint64_t seed);
|
ConflictSet *ConflictSet_create(int64_t oldestVersion, uint64_t seed);
|
||||||
void ConflictSet_destroy(ConflictSet *cs);
|
void ConflictSet_destroy(ConflictSet *cs);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user