Skip to content

Commit 73a7f12

Browse files
committed
[yugabyte#25403] docdb: Add helpers for defining hash functions
Summary: Defining hash functions for structs requires a lot of boilerplate. For example, to make `boost::hash` work with `YsqlFullTableName`, we have: ``` inline size_t hash_value(const YsqlFullTableName& table) { size_t value = 0; boost::hash_combine(value, table.namespace_name); boost::hash_combine(value, table.schema_name); boost::hash_combine(value, table.table_name); return value; } ``` This diff adds helper macros to eliminate much of the boilerplate needed to make std::hash and boost::hash work with structs, e.g. ``` YB_STRUCT_DEFINE_HASH(yb, YsqlFullTableName, namespace_name, schema_name, table_name); ``` will allow both `std::hash<YsqlFullTableName>` and `boost::hash<YsqlFullTableName>` to work and hash over `namespace_name`, `schema_name`, and `table_name`. Jira: DB-14634 Test Plan: Jenkins Reviewers: hsunder, sergei, xCluster Reviewed By: hsunder Subscribers: svc_phabricator, ycdcxcluster, bkolagani, ybase Differential Revision: https://phorge.dev.yugabyte.com/D40837
1 parent e9bc92d commit 73a7f12

File tree

14 files changed

+93
-152
lines changed

14 files changed

+93
-152
lines changed

src/yb/cdc/cdc_service.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,7 +2088,7 @@ void CDCServiceImpl::ProcessMetricsForEmptyChildrenTablets(
20882088

20892089
// Need to work our way up the hierarchy until we find a tablet with a valid value.
20902090
auto parent_tablet = child_tablet_meta.parent_tablet_info;
2091-
std::unordered_set<TabletStreamInfo, TabletStreamInfo::Hash> tablet_hierarchy;
2091+
std::unordered_set<TabletStreamInfo> tablet_hierarchy;
20922092
tablet_hierarchy.insert(child_tablet);
20932093

20942094
while (!parent_tablet.tablet_id.empty()) {
@@ -2137,7 +2137,7 @@ void CDCServiceImpl::ProcessMetricsForEmptyChildrenTablets(
21372137
void CDCServiceImpl::UpdateMetrics() {
21382138
auto tablet_checkpoints = impl_->TabletCheckpointsCopy();
21392139
TabletInfoToLastReplicationTimeMap cdc_state_tablets_to_last_replication_time;
2140-
std::unordered_set<TabletStreamInfo, TabletStreamInfo::Hash> expired_entries;
2140+
std::unordered_set<TabletStreamInfo> expired_entries;
21412141
EmptyChildrenTabletMap empty_children_tablets;
21422142

21432143
Status iteration_status;

src/yb/cdc/cdc_service.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,9 +413,9 @@ class CDCServiceImpl : public CDCServiceIf {
413413
std::shared_ptr<yb::xrepl::XClusterTabletMetrics> tablet_metric;
414414
};
415415
using EmptyChildrenTabletMap =
416-
std::unordered_map<TabletStreamInfo, ChildrenTabletMeta, TabletStreamInfo::Hash>;
416+
std::unordered_map<TabletStreamInfo, ChildrenTabletMeta>;
417417
using TabletInfoToLastReplicationTimeMap =
418-
std::unordered_map<TabletStreamInfo, std::optional<uint64_t>, TabletStreamInfo::Hash>;
418+
std::unordered_map<TabletStreamInfo, std::optional<uint64_t>>;
419419
// Helper function for processing metrics of children tablets. We need to find an ancestor tablet
420420
// that has a last replicated time and use that with our latest op's time to find the full lag.
421421
void ProcessMetricsForEmptyChildrenTablets(

src/yb/cdc/cdc_util.cc

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
#include "yb/cdc/cdc_util.h"
1515

16-
#include <boost/functional/hash.hpp>
17-
1816
#include "yb/gutil/strings/stringpiece.h"
1917
#include "yb/util/format.h"
2018

@@ -24,12 +22,4 @@ std::string TabletStreamInfo::ToString() const {
2422
return Format("{ stream_id: $1 tablet_id: $2 }", stream_id, tablet_id);
2523
}
2624

27-
std::size_t TabletStreamInfo::Hash::operator()(const TabletStreamInfo& p) const noexcept {
28-
std::size_t hash = 0;
29-
boost::hash_combine(hash, p.stream_id);
30-
boost::hash_combine(hash, p.tablet_id);
31-
32-
return hash;
33-
}
34-
3525
} // namespace yb::cdc

src/yb/cdc/cdc_util.h

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
#pragma once
1515

1616
#include <string>
17+
1718
#include "yb/cdc/xrepl_types.h"
1819
#include "yb/common/entity_ids_types.h"
20+
#include "yb/util/hash_util.h"
1921

2022
namespace yb::cdc {
2123

@@ -24,15 +26,11 @@ struct TabletStreamInfo {
2426
xrepl::StreamId stream_id;
2527
TabletId tablet_id;
2628

27-
bool operator==(const TabletStreamInfo& other) const {
28-
return stream_id == other.stream_id && tablet_id == other.tablet_id;
29-
}
29+
bool operator==(const TabletStreamInfo& other) const = default;
3030

31-
std::string ToString() const;
31+
YB_STRUCT_DEFINE_HASH(TabletStreamInfo, stream_id, tablet_id);
3232

33-
struct Hash {
34-
std::size_t operator()(const TabletStreamInfo& p) const noexcept;
35-
};
33+
std::string ToString() const;
3634
};
3735

3836

@@ -46,6 +44,4 @@ struct CDCCreationState {
4644
}
4745
};
4846

49-
inline size_t hash_value(const TabletStreamInfo& p) noexcept { return TabletStreamInfo::Hash()(p); }
50-
5147
} // namespace yb::cdc

src/yb/cdc/xcluster_types.cc

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
#include "yb/cdc/xcluster_types.h"
1515

16-
#include <boost/container_hash/hash_fwd.hpp>
17-
1816
#include "yb/util/format.h"
1917

2018
namespace yb::xcluster {
@@ -23,16 +21,6 @@ std::string ProducerTabletInfo::ToString() const {
2321
return YB_STRUCT_TO_STRING(replication_group_id, stream_id, tablet_id, table_id);
2422
}
2523

26-
std::size_t ProducerTabletInfo::Hash::operator()(const ProducerTabletInfo& p) const noexcept {
27-
std::size_t hash = 0;
28-
boost::hash_combine(hash, p.replication_group_id);
29-
boost::hash_combine(hash, p.stream_id);
30-
boost::hash_combine(hash, p.tablet_id);
31-
boost::hash_combine(hash, p.table_id);
32-
33-
return hash;
34-
}
35-
3624
std::string ConsumerTabletInfo::ToString() const {
3725
return Format("{ consumer tablet ID: $0 table ID: $1 }", tablet_id, table_id);
3826
}

src/yb/cdc/xcluster_types.h

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "yb/cdc/xrepl_types.h"
1717
#include "yb/common/common_types.pb.h"
1818
#include "yb/common/entity_ids_types.h"
19+
#include "yb/util/hash_util.h"
1920

2021
namespace yb::xcluster {
2122

@@ -44,22 +45,13 @@ struct ProducerTabletInfo {
4445
TabletId tablet_id;
4546
TableId table_id;
4647

47-
bool operator==(const ProducerTabletInfo& other) const {
48-
return replication_group_id == other.replication_group_id && stream_id == other.stream_id &&
49-
tablet_id == other.tablet_id && table_id == other.table_id;
50-
}
48+
bool operator==(const ProducerTabletInfo& other) const = default;
5149

52-
std::string ToString() const;
50+
YB_STRUCT_DEFINE_HASH(ProducerTabletInfo, replication_group_id, stream_id, tablet_id, table_id);
5351

54-
struct Hash {
55-
std::size_t operator()(const ProducerTabletInfo& p) const noexcept;
56-
};
52+
std::string ToString() const;
5753
};
5854

59-
inline size_t hash_value(const ProducerTabletInfo& p) noexcept {
60-
return ProducerTabletInfo::Hash()(p);
61-
}
62-
6355
struct ConsumerTabletInfo {
6456
std::string tablet_id;
6557
TableId table_id;

src/yb/common/opid.cc

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717

1818
#include <algorithm>
1919

20-
#include <boost/functional/hash.hpp>
21-
20+
#include "yb/util/hash_util.h"
2221
#include "yb/util/stol_utils.h"
2322

2423
namespace yb {
@@ -70,12 +69,7 @@ std::ostream& operator<<(std::ostream& out, const OpId& op_id) {
7069
}
7170

7271
size_t hash_value(const OpId& op_id) noexcept {
73-
size_t result = 0;
74-
75-
boost::hash_combine(result, op_id.term);
76-
boost::hash_combine(result, op_id.index);
77-
78-
return result;
72+
return YB_STRUCT_HASH_VALUE(op_id, term, index);
7973
}
8074

8175
} // namespace yb

src/yb/common/pg_types.h

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313

1414
#pragma once
1515

16-
#include <boost/functional/hash/hash.hpp>
17-
1816
#include "yb/common/entity_ids.h"
1917
#include "yb/common/schema.h"
2018

19+
#include "yb/util/hash_util.h"
20+
2121
namespace yb {
2222

2323
class Slice;
@@ -83,6 +83,10 @@ struct PgObjectId {
8383
static NamespaceId GetYbNamespaceIdFromPB(const PB& pb) {
8484
return FromPB(pb).GetYbNamespaceId();
8585
}
86+
87+
constexpr std::strong_ordering operator<=>(const PgObjectId&) const = default;
88+
89+
YB_STRUCT_DEFINE_HASH(PgObjectId, database_oid, object_oid);
8690
};
8791

8892
using PgObjectIdHash = boost::hash<PgObjectId>;
@@ -91,49 +95,19 @@ inline std::ostream& operator<<(std::ostream& out, const PgObjectId& id) {
9195
return out << id.ToString();
9296
}
9397

94-
inline bool operator==(const PgObjectId& lhs, const PgObjectId& rhs) {
95-
return lhs.database_oid == rhs.database_oid && lhs.object_oid == rhs.object_oid;
96-
}
97-
98-
inline bool operator<(const PgObjectId& lhs, const PgObjectId& rhs) {
99-
return lhs.database_oid == rhs.database_oid
100-
? (lhs.object_oid < rhs.object_oid)
101-
: (lhs.database_oid < rhs.database_oid);
102-
}
103-
104-
inline size_t hash_value(const PgObjectId& id) {
105-
size_t value = 0;
106-
boost::hash_combine(value, id.database_oid);
107-
boost::hash_combine(value, id.object_oid);
108-
return value;
109-
}
110-
11198
// A struct for complete PG table names.
11299
struct YsqlFullTableName {
113100
NamespaceName namespace_name;
114101
PgSchemaName schema_name;
115102
TableName table_name;
116103

117-
bool operator==(const YsqlFullTableName& other) const {
118-
return namespace_name == other.namespace_name && schema_name == other.schema_name &&
119-
table_name == other.table_name;
120-
}
104+
bool operator==(const YsqlFullTableName& other) const = default;
121105

122-
std::string ToString() const;
106+
YB_STRUCT_DEFINE_HASH(YsqlFullTableName, namespace_name, schema_name, table_name);
123107

124-
struct Hash {
125-
std::size_t operator()(const YsqlFullTableName& p) const noexcept;
126-
};
108+
std::string ToString() const;
127109
};
128110

129111
using YsqlFullTableNameHash = boost::hash<YsqlFullTableName>;
130112

131-
inline size_t hash_value(const YsqlFullTableName& table) {
132-
size_t value = 0;
133-
boost::hash_combine(value, table.namespace_name);
134-
boost::hash_combine(value, table.schema_name);
135-
boost::hash_combine(value, table.table_name);
136-
return value;
137-
}
138-
139113
} // namespace yb

src/yb/docdb/object_lock_data.h

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,11 @@
1313

1414
#pragma once
1515

16-
#include <boost/functional/hash.hpp>
17-
1816
#include "yb/common/transaction.h"
1917
#include "yb/dockv/dockv_fwd.h"
2018
#include "yb/tserver/tserver.pb.h"
2119
#include "yb/util/compare_util.h"
20+
#include "yb/util/hash_util.h"
2221

2322
namespace yb::docdb {
2423

@@ -30,6 +29,8 @@ struct VersionedTransaction {
3029
const TransactionId& txn_id_, TxnReuseVersion txn_version_) : txn_id(txn_id_),
3130
txn_version(txn_version_) {}
3231

32+
YB_STRUCT_DEFINE_HASH(VersionedTransaction, txn_id, txn_version);
33+
3334
std::string ToString() const {
3435
return YB_STRUCT_TO_STRING(txn_id, txn_version);
3536
}
@@ -46,13 +47,6 @@ inline bool operator<(const VersionedTransaction& lhs, const VersionedTransactio
4647
return lhs.txn_version < rhs.txn_version;
4748
}
4849

49-
inline size_t hash_value(const VersionedTransaction object) noexcept {
50-
size_t seed = 0;
51-
boost::hash_combine(seed, object.txn_id);
52-
boost::hash_combine(seed, object.txn_version);
53-
return seed;
54-
}
55-
5650
struct ObjectLockOwner {
5751
VersionedTransaction versioned_txn;
5852
SubTransactionId subtxn_id;
@@ -70,6 +64,8 @@ struct ObjectLockOwner {
7064
req->set_subtxn_id(subtxn_id);
7165
}
7266

67+
YB_STRUCT_DEFINE_HASH(ObjectLockOwner, versioned_txn, subtxn_id);
68+
7369
std::string ToString() const {
7470
return YB_STRUCT_TO_STRING(versioned_txn, subtxn_id);
7571
}
@@ -86,13 +82,6 @@ inline bool operator<(const ObjectLockOwner& lhs, const ObjectLockOwner& rhs) {
8682
return lhs.subtxn_id < rhs.subtxn_id;
8783
}
8884

89-
inline size_t hash_value(const ObjectLockOwner object) noexcept {
90-
size_t seed = 0;
91-
boost::hash_combine(seed, object.versioned_txn);
92-
boost::hash_combine(seed, object.subtxn_id);
93-
return seed;
94-
}
95-
9685
// ObjectLockPrefix is the entity for which the ts_local_lock_manager acquires locks. In context of
9786
// object/table locks, when a session requests lock(s) on an object oid corresponding to a database
9887
// oid, an 'ObjectLockPrefix' in formed which is then passed to the ObjectLockManager.
@@ -105,6 +94,8 @@ struct ObjectLockPrefix {
10594
return YB_STRUCT_TO_STRING(database_oid, object_oid, lock_type);
10695
}
10796

97+
YB_STRUCT_DEFINE_HASH(ObjectLockPrefix, database_oid, object_oid, lock_type);
98+
10899
uint64_t database_oid;
109100
uint64_t object_oid;
110101
dockv::KeyEntryType lock_type;
@@ -124,12 +115,4 @@ inline bool operator<(const ObjectLockPrefix& lhs, const ObjectLockPrefix& rhs)
124115
return lhs.lock_type < rhs.lock_type;
125116
}
126117

127-
inline size_t hash_value(const ObjectLockPrefix object) noexcept {
128-
size_t seed = 0;
129-
boost::hash_combine(seed, object.database_oid);
130-
boost::hash_combine(seed, object.object_oid);
131-
boost::hash_combine(seed, object.lock_type);
132-
return seed;
133-
}
134-
135118
} // namespace yb::docdb

src/yb/master/xcluster/xcluster_outbound_replication_group.cc

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "yb/common/xcluster_util.h"
1919
#include "yb/master/catalog_entity_info.h"
2020
#include "yb/master/xcluster/xcluster_outbound_replication_group_tasks.h"
21+
#include "yb/util/hash_util.h"
2122
#include "yb/util/is_operation_done_result.h"
2223
#include "yb/util/status_log.h"
2324
#include "yb/util/sync_point.h"
@@ -35,10 +36,7 @@ namespace {
3536

3637
struct TableSchemaNamePairHash {
3738
std::size_t operator()(const XClusterOutboundReplicationGroup::TableSchemaNamePair& elem) const {
38-
std::size_t hash = 0;
39-
boost::hash_combine(hash, elem.first);
40-
boost::hash_combine(hash, elem.second);
41-
return hash;
39+
return YB_STRUCT_HASH_VALUE(elem, first, second);
4240
}
4341
};
4442

0 commit comments

Comments
 (0)