Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BlobRoute : Comparison and Hash can be made much cheaper without string formatting. #66

Merged
merged 5 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/lib/blob_route.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <functional>

#include <boost/functional/hash.hpp>

#include "homeobject/common.hpp"

namespace homeobject {

///
// A Key used in the IndexService (BTree). The inclusion of Shard allows BlobRoutes
// to appear in a different Index should the Blob (Shard) be moved between Pgs.
struct BlobRoute {
shard_id shard;
blob_id blob;
auto operator<=>(BlobRoute const&) const = default;
};

} // namespace homeobject

namespace fmt {
template <>
struct formatter< homeobject::BlobRoute > {
template < typename ParseContext >
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template < typename FormatContext >
auto format(homeobject::BlobRoute const& r, FormatContext& ctx) {
return format_to(ctx.out(), "{:04x}:{:012x}:{:016x}", (r.shard >> homeobject::shard_width),
(r.shard & homeobject::shard_mask), r.blob);
}
};
} // namespace fmt

template <>
struct std::hash< homeobject::BlobRoute > {
std::size_t operator()(homeobject::BlobRoute const& r) const noexcept {
return boost::hash_value< homeobject::blob_id >(std::make_pair(r.shard, r.blob));
}
};
6 changes: 6 additions & 0 deletions src/lib/homeobject_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ class ReplicationService;

namespace homeobject {

constexpr size_t pg_width = sizeof(pg_id) * 8;
constexpr size_t shard_width = (sizeof(shard_id) * 8) - pg_width;
constexpr size_t shard_mask = std::numeric_limits< homeobject::shard_id >::max() >> pg_width;

inline shard_id make_new_shard_id(pg_id pg, shard_id next_shard) { return ((uint64_t)pg << shard_width) | next_shard; }

inline bool operator<(ShardInfo const& lhs, ShardInfo const& rhs) { return lhs.id < rhs.id; }
inline bool operator==(ShardInfo const& lhs, ShardInfo const& rhs) { return lhs.id == rhs.id; }

Expand Down
1 change: 0 additions & 1 deletion src/lib/homestore/homeobject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class HSHomeObject : public HomeObjectImpl {

private:
shard_id generate_new_shard_id(pg_id pg);
shard_id make_new_shard_id(pg_id pg, uint64_t sequence_num) const;
uint64_t get_sequence_num_from_shard_id(uint64_t shard_id);
szmyd marked this conversation as resolved.
Show resolved Hide resolved
std::string serialize_shard(const Shard& shard) const;
Shard deserialize_shard(const std::string& shard_info_str) const;
Expand Down
11 changes: 3 additions & 8 deletions src/lib/homestore/shard_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@

namespace homeobject {

static constexpr uint32_t SEQUENCE_BIT_NUM_IN_SHARD{48};

uint64_t ShardManager::max_shard_size() { return Gi; }

uint64_t ShardManager::max_shard_num_in_pg() { return ((uint64_t)0x01) << SEQUENCE_BIT_NUM_IN_SHARD; }
uint64_t ShardManager::max_shard_num_in_pg() { return ((uint64_t)0x01) << shard_width; }

shard_id HSHomeObject::generate_new_shard_id(pg_id pg) {
std::scoped_lock lock_guard(_pg_lock);
Expand All @@ -23,10 +21,6 @@ shard_id HSHomeObject::generate_new_shard_id(pg_id pg) {
return make_new_shard_id(pg, new_sequence_num);
}

shard_id HSHomeObject::make_new_shard_id(pg_id pg, uint64_t sequence_num) const {
return ((uint64_t)pg << SEQUENCE_BIT_NUM_IN_SHARD) | sequence_num;
}

uint64_t HSHomeObject::get_sequence_num_from_shard_id(uint64_t shard_id) {
return shard_id & (max_shard_num_in_pg() - 1);
}
Expand Down Expand Up @@ -99,7 +93,8 @@ ShardManager::Result< ShardInfo > HSHomeObject::_create_shard(pg_id pg_owner, ui
replica_set->write(sisl::blob(buf->data_begin(), needed_size), sisl::blob(), value, static_cast< void* >(&p));
auto info = std::move(sf).get();
if (!bool(info)) {
LOGWARN("create new shard [{}] on pg [{}] is failed with error:{}", new_shard_id, pg_owner, info.error());
LOGWARN("create new shard [{}] on pg [{}] is failed with error:{}", new_shard_id & shard_mask, pg_owner,
info.error());
}
header->~ReplicationMessageHeader();
return info;
Expand Down
43 changes: 3 additions & 40 deletions src/lib/memory/homeobject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,9 @@
#include "mocks/repl_service.h"

#include "lib/homeobject_impl.hpp"
#include "lib/blob_route.hpp"

namespace homeobject {
struct BlobRoute {
shard_id shard;
blob_id blob;
};
} // namespace homeobject

namespace fmt {
template <>
struct formatter< homeobject::BlobRoute > {
template < typename ParseContext >
constexpr auto parse(ParseContext& ctx) {
return ctx.begin();
}

template < typename FormatContext >
auto format(const homeobject::BlobRoute& r, FormatContext& ctx) {
return format_to(ctx.out(), "{}:{:012x}", r.shard, r.blob);
}
};
} // namespace fmt

template <>
struct std::hash< homeobject::BlobRoute > {
std::size_t operator()(homeobject::BlobRoute const& r) const noexcept {
return std::hash< std::string >()(fmt::format("{}", r));
}
};

namespace homeobject {

inline bool operator<(BlobRoute const& lhs, BlobRoute const& rhs) {
return fmt::format("{}", lhs) < fmt::format("{}", rhs);
}
inline bool operator==(BlobRoute const& lhs, BlobRoute const& rhs) {
return fmt::format("{}", lhs) == fmt::format("{}", rhs);
}

///
// Used to TombStone Blob's in the Index to defer for GC.
Expand All @@ -55,13 +20,11 @@ struct BlobExt {
Blob* _blob;

explicit operator bool() const { return _state == BlobState::ALIVE; }
bool operator==(const BlobExt& rhs) const { return _blob == rhs._blob; }
};
inline bool operator==(BlobExt const& lhs, BlobExt const& rhs) { return lhs._blob == rhs._blob; }

using btree = folly::ConcurrentHashMap< BlobRoute, BlobExt >;

struct ShardIndex {
btree _btree;
folly::ConcurrentHashMap< BlobRoute, BlobExt > _btree;
std::atomic< blob_id > _shard_seq_num{0ull};
~ShardIndex();
};
Expand Down
4 changes: 2 additions & 2 deletions src/lib/memory/shard_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ ShardManager::Result< ShardInfo > MemoryHomeObject::_create_shard(pg_id pg_owner
if (_pg_map.end() == pg_it) return folly::makeUnexpected(ShardError::UNKNOWN_PG);

auto& s_list = pg_it->second.shards;
info.id = (((uint64_t)pg_owner) << 48) + s_list.size();
info.id = make_new_shard_id(pg_owner, s_list.size());
auto iter = s_list.emplace(s_list.end(), Shard(info));
LOGDEBUG("Creating Shard [{}]: in Pg [{}] of Size [{}b]", info.id, pg_owner, size_bytes);
LOGDEBUG("Creating Shard [{}]: in Pg [{}] of Size [{}b]", info.id & shard_mask, pg_owner, size_bytes);
auto [_, s_happened] = _shard_map.emplace(info.id, iter);
RELEASE_ASSERT(s_happened, "Duplicate Shard insertion!");
}
Expand Down