Prepare to fully canonicalize views

This commit is contained in:
2024-05-28 21:38:08 -07:00
parent 93ff83e422
commit f1f4d66678
6 changed files with 20 additions and 15 deletions

View File

@@ -54,7 +54,7 @@ void setAndClearPrev() {
auto m = *iter++;
int64_t k = __builtin_bswap64(version);
assert(m.version == version);
assert(m.notModifiedSince == version);
assert(m.param1Len == 8);
assert(m.param2Len == 8);
int64_t zero = __builtin_bswap64(0);
@@ -63,7 +63,7 @@ void setAndClearPrev() {
assert(m.type == weaselab::VersionedMap::Clear);
m = *iter++;
assert(m.version == version);
assert(m.notModifiedSince == version);
assert(m.param1Len == 8);
assert(m.param2Len == 8);
assert(memcmp(m.param1, &k, 8) == 0);

View File

@@ -191,8 +191,8 @@ struct Facade {
for (auto iter = versioned.begin(version), end = versioned.end(version);
iter != end; ++iter) {
auto m = *iter;
assert(m.version <= version);
if (m.version <= unversionedVersion) {
assert(m.notModifiedSince <= version);
if (m.notModifiedSince <= unversionedVersion) {
continue;
}
switch (m.type) {

View File

@@ -1345,7 +1345,7 @@ VersionedMap::Iterator::operator*() const {
result.param2 = impl->iter->getValue().p;
result.param2Len = impl->iter->getValue().len;
}
result.version = impl->iter.insertVersion();
result.notModifiedSince = impl->iter.insertVersion();
return result;
}

View File

@@ -27,7 +27,7 @@ printMutation(const weaselab::VersionedMap::Iterator::VersionedMutation &m) {
printf("x%02x", c);
}
}
printf("' @ %" PRId64 "\n", m.version);
printf("' @ %" PRId64 "\n", m.notModifiedSince);
break;
case weaselab::VersionedMap::Clear:
printf("clear [");
@@ -48,7 +48,7 @@ printMutation(const weaselab::VersionedMap::Iterator::VersionedMutation &m) {
printf("x%02x", c);
}
}
printf(") @ %" PRId64 "\n", m.version);
printf(") @ %" PRId64 "\n", m.notModifiedSince);
break;
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE

View File

@@ -615,10 +615,9 @@ struct __attribute__((__visibility__("hidden"))) VersionedMap::Impl {
// If `val` is set, then this is a point mutation at `latestVersion`.
// Otherwise it's the end of a range mutation at `latestVersion`.
// `finger` becomes the search path of `key`
// `finger` is a valid finger to the insertion path of `key` in the latest
// version (which can be obtained with `search`)
void insert(Key key, std::optional<Val> val, Finger &finger) {
search<std::memory_order_relaxed>(key, latestRoot, latestVersion, finger);
const bool inserted = finger.backNode() == 0;
int64_t pointVersion, rangeVersion;
@@ -878,9 +877,13 @@ struct __attribute__((__visibility__("hidden"))) VersionedMap::Impl {
Finger iter;
switch (m.type) {
case Set: {
search<std::memory_order_relaxed>({m.param1, m.param1Len}, latestRoot,
latestVersion, iter);
insert({m.param1, m.param1Len}, {{m.param2, m.param2Len}}, iter);
} break;
case Clear: {
search<std::memory_order_relaxed>({m.param1, m.param1Len}, latestRoot,
latestVersion, iter);
insert({m.param1, m.param1Len}, {{nullptr, -1}}, iter);
if (m.param2Len > 0) {
move<std::memory_order_relaxed, true>(iter, latestVersion);
@@ -891,6 +894,8 @@ struct __attribute__((__visibility__("hidden"))) VersionedMap::Impl {
}
// TODO reuse finger? It should be one rank away from its insertion
// point
search<std::memory_order_relaxed>({m.param2, m.param2Len}, latestRoot,
latestVersion, iter);
insert({m.param2, m.param2Len}, {}, iter);
}
} break;

View File

@@ -86,16 +86,13 @@ struct __attribute__((__visibility__("default"))) VersionedMap {
/** The version of the most recent call to `setOldestVersion`. */
int64_t getOldestVersion() const;
/** Iterates through a canonicalized[1] view of all the mutations
/** Iterates through a canonicalized view of all the mutations
* from `oldestVersion` to the iterator's version. There may be mutations from
* versions < `oldestVersion`, but they won't affect the result, and can be
* ignored if desired. It's thread-safe to operate on an iterator concurrently
* with any method of `VersionedMap`, as long as it's not invalidated by
* `setOldestVersion`.
* @warning must not outlive its `VersionedMap`.
*
* [1]: Clears at different versions may be adjacent. This is necessary for
* precisely tracking at what version the mutations take effect.
*/
struct Iterator {
@@ -114,7 +111,10 @@ struct __attribute__((__visibility__("default"))) VersionedMap {
int param1Len;
int param2Len;
MutationType type;
int64_t version;
/** The set of keys modified by this mutation have not been modified since
* this version. They were not necessarily modified at this version
* though. */
int64_t notModifiedSince;
};
/** iter must not be `end()`. Memory pointed-to by return value is valid as