Implement firstGeq
This commit is contained in:
@@ -352,6 +352,12 @@ auto operator<=>(const VersionedMap::Key &lhs, const Node &rhs) {
|
|||||||
return lhs.len <=> rhs.entry->keyLen;
|
return lhs.len <=> rhs.entry->keyLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr int orderToInt(std::strong_ordering o) {
|
||||||
|
return o == std::strong_ordering::less ? -1
|
||||||
|
: o == std::strong_ordering::equal ? 0
|
||||||
|
: 1;
|
||||||
|
}
|
||||||
|
|
||||||
struct Finger {
|
struct Finger {
|
||||||
void push(uint32_t node, bool dir) {
|
void push(uint32_t node, bool dir) {
|
||||||
searchPath[searchPathSize_] = node;
|
searchPath[searchPathSize_] = node;
|
||||||
@@ -413,8 +419,10 @@ private:
|
|||||||
|
|
||||||
struct VersionedMap::Impl {
|
struct VersionedMap::Impl {
|
||||||
|
|
||||||
|
// The last node is allowed to be 0, in which case this is the search path of
|
||||||
|
// where an entry would exist
|
||||||
template <std::memory_order kOrder>
|
template <std::memory_order kOrder>
|
||||||
void move(Finger &finger, int64_t at, bool direction) {
|
void move(Finger &finger, int64_t at, bool direction) const {
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
if (finger.backNode() != 0 &&
|
if (finger.backNode() != 0 &&
|
||||||
(c = child<kOrder>(finger.backNode(), direction, at)) != 0) {
|
(c = child<kOrder>(finger.backNode(), direction, at)) != 0) {
|
||||||
@@ -431,7 +439,7 @@ struct VersionedMap::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <std::memory_order kOrder>
|
template <std::memory_order kOrder>
|
||||||
uint32_t child(uint32_t node, bool which, int64_t at) {
|
uint32_t child(uint32_t node, bool which, int64_t at) const {
|
||||||
static_assert(kOrder == std::memory_order_acquire ||
|
static_assert(kOrder == std::memory_order_acquire ||
|
||||||
kOrder == std::memory_order_relaxed);
|
kOrder == std::memory_order_relaxed);
|
||||||
auto &n = mm.base[node];
|
auto &n = mm.base[node];
|
||||||
@@ -522,7 +530,7 @@ struct VersionedMap::Impl {
|
|||||||
int len;
|
int len;
|
||||||
};
|
};
|
||||||
|
|
||||||
Finger search(Key key, int64_t at) {
|
Finger search(Key key, int64_t at) const {
|
||||||
Finger finger;
|
Finger finger;
|
||||||
bool ignored;
|
bool ignored;
|
||||||
finger.push(latestRoot, ignored);
|
finger.push(latestRoot, ignored);
|
||||||
@@ -712,6 +720,7 @@ struct VersionedMap::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setOldestVersion(int64_t oldestVersion) {
|
void setOldestVersion(int64_t oldestVersion) {
|
||||||
|
this->oldestVersion = oldestVersion;
|
||||||
roots.setOldestVersion(oldestVersion);
|
roots.setOldestVersion(oldestVersion);
|
||||||
mm.gc(roots.roots(), roots.rootCount(), oldestVersion);
|
mm.gc(roots.roots(), roots.rootCount(), oldestVersion);
|
||||||
}
|
}
|
||||||
@@ -752,10 +761,14 @@ struct VersionedMap::Impl {
|
|||||||
roots.add(latestRoot, latestVersion);
|
roots.add(latestRoot, latestVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void firstGeq(const Key *key, const int64_t *version, Iterator *iterator,
|
||||||
|
int count) const;
|
||||||
|
|
||||||
MemManager mm;
|
MemManager mm;
|
||||||
RootSet roots;
|
RootSet roots;
|
||||||
// Only meaningful within the callstack of `addMutations`
|
// Only meaningful within the callstack of `addMutations`
|
||||||
uint32_t latestRoot;
|
uint32_t latestRoot;
|
||||||
|
int64_t oldestVersion = 0;
|
||||||
int64_t latestVersion = 0;
|
int64_t latestVersion = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -787,7 +800,7 @@ void VersionedMap::addMutations(const Mutation *mutations, int numMutations,
|
|||||||
struct VersionedMap::Iterator::Impl {
|
struct VersionedMap::Iterator::Impl {
|
||||||
Finger finger;
|
Finger finger;
|
||||||
int64_t version;
|
int64_t version;
|
||||||
VersionedMap::Impl *map;
|
const VersionedMap::Impl *map;
|
||||||
int cmp;
|
int cmp;
|
||||||
// True if this is a point mutation and a range mutation, and we're
|
// True if this is a point mutation and a range mutation, and we're
|
||||||
// materializing the range mutation instead of the point mutation.
|
// materializing the range mutation instead of the point mutation.
|
||||||
@@ -907,12 +920,46 @@ bool VersionedMap::Iterator::operator==(const Iterator &other) const {
|
|||||||
other.impl->materializeClearEndingHere;
|
other.impl->materializeClearEndingHere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VersionedMap::Impl::firstGeq(const Key *key, const int64_t *version,
|
||||||
|
Iterator *iterator, int count) const {
|
||||||
|
// TODO ILP!
|
||||||
|
for (int i = 0; i < count; ++i) {
|
||||||
|
// TODO re-use root if passed-in iterator version matches
|
||||||
|
auto finger = search(key[i], version[i]);
|
||||||
|
if (iterator[i].impl != nullptr) {
|
||||||
|
iterator[i].impl->~Impl();
|
||||||
|
}
|
||||||
|
iterator[i].impl = new (malloc(sizeof(Iterator::Impl))) Iterator::Impl();
|
||||||
|
|
||||||
|
if (finger.searchPathSize() == 0) {
|
||||||
|
iterator[i].impl->cmp = 1;
|
||||||
|
} else if (finger.backNode() == 0) {
|
||||||
|
iterator[i].impl->cmp = 1;
|
||||||
|
move<std::memory_order_acquire>(finger, version[i], true);
|
||||||
|
const auto &entry = *mm.base[finger.backNode()].entry;
|
||||||
|
iterator[i].impl->materializeClearEndingHere =
|
||||||
|
entry.clearTo() && entry.pointMutation();
|
||||||
|
} else {
|
||||||
|
iterator[i].impl->cmp = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator[i].impl->finger = finger;
|
||||||
|
iterator[i].impl->version = version[i];
|
||||||
|
iterator[i].impl->map = this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool VersionedMap::Iterator::operator!=(const Iterator &other) const {
|
bool VersionedMap::Iterator::operator!=(const Iterator &other) const {
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
int VersionedMap::Iterator::cmp() const { return impl->cmp; }
|
int VersionedMap::Iterator::cmp() const { return impl->cmp; }
|
||||||
|
|
||||||
|
void VersionedMap::firstGeq(const Key *key, const int64_t *version,
|
||||||
|
Iterator *iterator, int count) const {
|
||||||
|
impl->firstGeq(key, version, iterator, count);
|
||||||
|
}
|
||||||
|
|
||||||
VersionedMap::Iterator VersionedMap::begin(int64_t version) const {
|
VersionedMap::Iterator VersionedMap::begin(int64_t version) const {
|
||||||
VersionedMap::Iterator result;
|
VersionedMap::Iterator result;
|
||||||
result.impl = new (malloc(sizeof(Iterator::Impl))) Iterator::Impl();
|
result.impl = new (malloc(sizeof(Iterator::Impl))) Iterator::Impl();
|
||||||
@@ -1023,8 +1070,10 @@ int main() {
|
|||||||
}
|
}
|
||||||
const int64_t v = 3;
|
const int64_t v = 3;
|
||||||
cast(versionedMap)->printInOrder(v);
|
cast(versionedMap)->printInOrder(v);
|
||||||
for (auto iter = versionedMap.begin(v), end = versionedMap.end(v);
|
weaselab::VersionedMap::Key k = {(const uint8_t *)"aa", 2};
|
||||||
iter != end; ++iter) {
|
weaselab::VersionedMap::Iterator iter;
|
||||||
|
versionedMap.firstGeq(&k, &v, &iter, 1);
|
||||||
|
for (auto end = versionedMap.end(v); iter != end; ++iter) {
|
||||||
const auto &m = *iter;
|
const auto &m = *iter;
|
||||||
switch (m.type) {
|
switch (m.type) {
|
||||||
case weaselab::VersionedMap::Set:
|
case weaselab::VersionedMap::Set:
|
||||||
|
Reference in New Issue
Block a user