Avoid copies in Facade

This commit is contained in:
2024-05-23 17:27:55 -07:00
parent 2764a049a8
commit b5dbf4a049
3 changed files with 48 additions and 15 deletions

View File

@@ -1,14 +1,12 @@
#pragma once #pragma once
#include "KeyCompare.h"
#include "VersionedMap.h" #include "VersionedMap.h"
#include <assert.h> #include <assert.h>
#include <map> #include <map>
#include <string>
#include <vector> #include <vector>
using String = std::basic_string<uint8_t>;
struct Facade { struct Facade {
explicit Facade(int64_t version) explicit Facade(int64_t version)
@@ -58,11 +56,12 @@ struct Facade {
do { do {
--iter; --iter;
auto m = *iter; auto m = *iter;
const auto mBegin = String(m.param1, m.param1Len); const auto mBegin =
weaselab::VersionedMap::Key{m.param1, m.param1Len};
const auto mEnd = const auto mEnd =
m.type == weaselab::VersionedMap::Set || m.param2Len == 0 m.type == weaselab::VersionedMap::Set || m.param2Len == 0
? String(m.param1, m.param1Len) + zero ? weaselab::VersionedMap::Key{m.param1, m.param1Len + 1}
: String(m.param2, m.param2Len); : weaselab::VersionedMap::Key{m.param2, m.param2Len};
if (unversionedIter != beginIter) { if (unversionedIter != beginIter) {
--unversionedIter; --unversionedIter;
for (; unversionedIter->first >= mEnd && limit > 0; for (; unversionedIter->first >= mEnd && limit > 0;
@@ -79,7 +78,8 @@ struct Facade {
} }
switch (m.type) { switch (m.type) {
case weaselab::VersionedMap::Set: { case weaselab::VersionedMap::Set: {
result.emplace_back(mBegin, String(m.param2, m.param2Len)); result.emplace_back(String(mBegin.p, mBegin.len),
String(m.param2, m.param2Len));
--limit; --limit;
if (limit == 0) { if (limit == 0) {
return result; return result;
@@ -93,9 +93,11 @@ struct Facade {
unversionedIter->first < mBegin) { unversionedIter->first < mBegin) {
++unversionedIter; ++unversionedIter;
} }
assert(unversionedIter == facade->unversioned.lower_bound(mBegin)); assert(unversionedIter == facade->unversioned.lower_bound(
String(mBegin.p, mBegin.len)));
} else { } else {
unversionedIter = facade->unversioned.lower_bound(mBegin); unversionedIter =
facade->unversioned.lower_bound(String(mBegin.p, mBegin.len));
} }
} while (iter != endIter); } while (iter != endIter);
@@ -115,11 +117,12 @@ struct Facade {
auto unversionedIter = facade->unversioned.lower_bound(begin); auto unversionedIter = facade->unversioned.lower_bound(begin);
for (auto iter = versionedIter[0]; iter != versionedIter[1]; ++iter) { for (auto iter = versionedIter[0]; iter != versionedIter[1]; ++iter) {
auto m = *iter; auto m = *iter;
const auto mBegin = String(m.param1, m.param1Len); const auto mBegin =
weaselab::VersionedMap::Key{m.param1, m.param1Len};
const auto mEnd = const auto mEnd =
m.type == weaselab::VersionedMap::Set || m.param2Len == 0 m.type == weaselab::VersionedMap::Set || m.param2Len == 0
? String(m.param1, m.param1Len) + zero ? weaselab::VersionedMap::Key{m.param1, m.param1Len + 1}
: String(m.param2, m.param2Len); : weaselab::VersionedMap::Key{m.param2, m.param2Len};
auto c = unversionedIter->first <=> mBegin; auto c = unversionedIter->first <=> mBegin;
for (; unversionedIter != facade->unversioned.end() && c < 0 && for (; unversionedIter != facade->unversioned.end() && c < 0 &&
limit > 0;) { limit > 0;) {
@@ -133,7 +136,8 @@ struct Facade {
} }
switch (m.type) { switch (m.type) {
case weaselab::VersionedMap::Set: { case weaselab::VersionedMap::Set: {
result.emplace_back(mBegin, String(m.param2, m.param2Len)); result.emplace_back(String(mBegin.p, mBegin.len),
String(m.param2, m.param2Len));
--limit; --limit;
if (limit == 0) { if (limit == 0) {
return result; return result;
@@ -146,9 +150,11 @@ struct Facade {
if (unversionedIter != facade->unversioned.end() && c == 0) { if (unversionedIter != facade->unversioned.end() && c == 0) {
++unversionedIter; ++unversionedIter;
} }
assert(unversionedIter == facade->unversioned.lower_bound(mEnd)); assert(unversionedIter ==
facade->unversioned.lower_bound(String(mEnd.p, mEnd.len)));
} else { } else {
unversionedIter = facade->unversioned.lower_bound(mEnd); unversionedIter =
facade->unversioned.lower_bound(String(mEnd.p, mEnd.len));
} }
} }

View File

@@ -5,6 +5,9 @@
#include <algorithm> #include <algorithm>
#include <string.h> #include <string.h>
#include <string>
using String = std::basic_string<uint8_t>;
inline auto operator<=>(const weaselab::VersionedMap::Key &lhs, inline auto operator<=>(const weaselab::VersionedMap::Key &lhs,
const weaselab::VersionedMap::Key &rhs) { const weaselab::VersionedMap::Key &rhs) {
int cl = std::min(lhs.len, rhs.len); int cl = std::min(lhs.len, rhs.len);
@@ -16,3 +19,25 @@ inline auto operator<=>(const weaselab::VersionedMap::Key &lhs,
} }
return lhs.len <=> rhs.len; return lhs.len <=> rhs.len;
} }
inline auto operator<=>(const String &lhs,
const weaselab::VersionedMap::Key &rhs) {
int cl = std::min<int>(lhs.size(), rhs.len);
if (cl > 0) {
int c = memcmp(lhs.data(), rhs.p, cl);
if (c != 0) {
return c <=> 0;
}
}
return int(lhs.size()) <=> rhs.len;
}
inline auto operator==(const weaselab::VersionedMap::Key &lhs,
const weaselab::VersionedMap::Key &rhs) {
return (lhs <=> rhs) == 0;
}
inline auto operator!=(const weaselab::VersionedMap::Key &lhs,
const weaselab::VersionedMap::Key &rhs) {
return (lhs <=> rhs) != 0;
}

View File

@@ -107,6 +107,8 @@ struct __attribute__((__visibility__("default"))) VersionedMap {
Iterator &operator=(Iterator &&) noexcept; Iterator &operator=(Iterator &&) noexcept;
struct VersionedMutation { struct VersionedMutation {
/** param1 is guaranteed to have an addressable null byte at
* param1[param1Len] */
const uint8_t *param1; const uint8_t *param1;
const uint8_t *param2; const uint8_t *param2;
int param1Len; int param1Len;