Add hash to StringRef. Use unordered maps for storing tags. Create some helpful typedefs.

This commit is contained in:
A.J. Beamon 2020-04-10 12:54:59 -07:00
parent 55a0d00ad4
commit 29b2c2f3aa
9 changed files with 49 additions and 14 deletions

View File

@ -167,7 +167,7 @@ public:
UID dbId; UID dbId;
bool internal; // Only contexts created through the C client and fdbcli are non-internal bool internal; // Only contexts created through the C client and fdbcli are non-internal
std::map<TagThrottleInfo::Priority, std::map<Standalone<StringRef>, TagThrottleInfo>> throttledTags; PrioritizedTagThrottleMap throttledTags;
CounterCollection cc; CounterCollection cc;

View File

@ -165,7 +165,7 @@ struct GetReadVersionReply {
bool locked; bool locked;
Optional<Value> metadataVersion; Optional<Value> metadataVersion;
std::map<Standalone<StringRef>, TagThrottleInfo> tagThrottleInfo; TagThrottleMap tagThrottleInfo;
GetReadVersionReply() : version(invalidVersion), locked(false) {} GetReadVersionReply() : version(invalidVersion), locked(false) {}

View File

@ -86,6 +86,8 @@ struct TagThrottleInfo {
} }
}; };
BINARY_SERIALIZABLE(TagThrottleInfo::Priority);
class TagSet { class TagSet {
public: public:
typedef std::set<StringRef>::const_iterator const_iterator; typedef std::set<StringRef>::const_iterator const_iterator;
@ -148,7 +150,8 @@ struct dynamic_size_traits<TagSet> : std::true_type {
} }
}; };
BINARY_SERIALIZABLE(TagThrottleInfo::Priority); typedef std::unordered_map<Standalone<StringRef>, TagThrottleInfo, std::hash<StringRef>> TagThrottleMap;
typedef std::map<TagThrottleInfo::Priority, TagThrottleMap> PrioritizedTagThrottleMap;
namespace ThrottleApi { namespace ThrottleApi {
// Currently, only 1 tag in a key is supported // Currently, only 1 tag in a key is supported

View File

@ -99,7 +99,7 @@ struct ProxyStats {
ACTOR Future<Void> getRate(UID myID, Reference<AsyncVar<ServerDBInfo>> db, int64_t* inTransactionCount, int64_t* inBatchTransactionCount, double* outTransactionRate, ACTOR Future<Void> getRate(UID myID, Reference<AsyncVar<ServerDBInfo>> db, int64_t* inTransactionCount, int64_t* inBatchTransactionCount, double* outTransactionRate,
double* outBatchTransactionRate, GetHealthMetricsReply* healthMetricsReply, GetHealthMetricsReply* detailedHealthMetricsReply, double* outBatchTransactionRate, GetHealthMetricsReply* healthMetricsReply, GetHealthMetricsReply* detailedHealthMetricsReply,
std::map<TagThrottleInfo::Priority, std::map<Standalone<StringRef>, TagThrottleInfo>> *throttledTags) { PrioritizedTagThrottleMap *throttledTags) {
state Future<Void> nextRequestTimer = Never(); state Future<Void> nextRequestTimer = Never();
state Future<Void> leaseTimeout = Never(); state Future<Void> leaseTimeout = Never();
state Future<GetRateInfoReply> reply = Never(); state Future<GetRateInfoReply> reply = Never();
@ -1292,7 +1292,7 @@ ACTOR Future<GetReadVersionReply> getLiveCommittedVersion(ProxyCommitData* commi
} }
ACTOR Future<Void> sendGrvReplies(Future<GetReadVersionReply> replyFuture, std::vector<GetReadVersionRequest> requests, ACTOR Future<Void> sendGrvReplies(Future<GetReadVersionReply> replyFuture, std::vector<GetReadVersionRequest> requests,
ProxyStats* stats, Version minKnownCommittedVersion, std::map<TagThrottleInfo::Priority, std::map<Standalone<StringRef>, TagThrottleInfo>> throttledTags) { ProxyStats* stats, Version minKnownCommittedVersion, PrioritizedTagThrottleMap throttledTags) {
GetReadVersionReply _baseReply = wait(replyFuture); GetReadVersionReply _baseReply = wait(replyFuture);
GetReadVersionReply baseReply = _baseReply; GetReadVersionReply baseReply = _baseReply;
double end = g_network->timer(); double end = g_network->timer();
@ -1353,7 +1353,7 @@ ACTOR static Future<Void> transactionStarter(
state Deque<GetReadVersionRequest> batchQueue; state Deque<GetReadVersionRequest> batchQueue;
state vector<MasterProxyInterface> otherProxies; state vector<MasterProxyInterface> otherProxies;
state std::map<TagThrottleInfo::Priority, std::map<Standalone<StringRef>, TagThrottleInfo>> throttledTags; state PrioritizedTagThrottleMap throttledTags;
state PromiseStream<double> replyTimes; state PromiseStream<double> replyTimes;
addActor.send(getRate(proxy.id(), db, &transactionCount, &batchTransactionCount, &normalRateInfo.rate, &batchRateInfo.rate, healthMetricsReply, detailedHealthMetricsReply, &throttledTags)); addActor.send(getRate(proxy.id(), db, &transactionCount, &batchTransactionCount, &normalRateInfo.rate, &batchRateInfo.rate, healthMetricsReply, detailedHealthMetricsReply, &throttledTags));

View File

@ -187,8 +187,7 @@ struct RatekeeperData {
double lastWarning; double lastWarning;
double lastSSListFetchedTimestamp; double lastSSListFetchedTimestamp;
typedef std::map<Standalone<StringRef>, TagThrottleInfo> ThrottleMap; PrioritizedTagThrottleMap tagThrottles;
std::map<TagThrottleInfo::Priority, ThrottleMap> tagThrottles;
RatekeeperLimits normalLimits; RatekeeperLimits normalLimits;
RatekeeperLimits batchLimits; RatekeeperLimits batchLimits;
@ -417,8 +416,8 @@ ACTOR Future<Void> monitorThrottlingChanges(RatekeeperData *self) {
} }
TraceEvent("RatekeeperReadThrottles").detail("NumThrottledTags", throttledTags.get().size()); TraceEvent("RatekeeperReadThrottles").detail("NumThrottledTags", throttledTags.get().size());
std::map<TagThrottleInfo::Priority, RatekeeperData::ThrottleMap> newThrottles; PrioritizedTagThrottleMap newThrottles;
std::map<TagThrottleInfo::Priority, std::pair<RatekeeperData::ThrottleMap::iterator, RatekeeperData::ThrottleMap::iterator>> oldThrottleIterators; std::map<TagThrottleInfo::Priority, std::pair<TagThrottleMap::iterator, TagThrottleMap::iterator>> oldThrottleIterators;
for(auto t : self->tagThrottles) { for(auto t : self->tagThrottles) {
oldThrottleIterators[t.first] = std::make_pair(t.second.begin(), t.second.end()); oldThrottleIterators[t.first] = std::make_pair(t.second.begin(), t.second.end());
} }
@ -473,7 +472,7 @@ ACTOR Future<Void> monitorThrottlingChanges(RatekeeperData *self) {
} }
} }
void updateRate(RatekeeperData* self, RatekeeperLimits* limits, RatekeeperData::ThrottleMap& throttledTags) { void updateRate(RatekeeperData* self, RatekeeperLimits* limits, TagThrottleMap& throttledTags) {
//double controlFactor = ; // dt / eFoldingTime //double controlFactor = ; // dt / eFoldingTime
double actualTps = self->smoothReleasedTransactions.smoothRate(); double actualTps = self->smoothReleasedTransactions.smoothRate();

View File

@ -59,7 +59,7 @@ struct GetRateInfoReply {
double leaseDuration; double leaseDuration;
HealthMetrics healthMetrics; HealthMetrics healthMetrics;
std::map<TagThrottleInfo::Priority, std::map<Standalone<StringRef>, TagThrottleInfo>> throttledTags; PrioritizedTagThrottleMap throttledTags;
template <class Ar> template <class Ar>
void serialize(Ar& ar) { void serialize(Ar& ar) {

View File

@ -460,7 +460,7 @@ public:
: tag(tag), count(count), fractionalBusyness((double)count/totalCount), elapsed(elapsed) {} : tag(tag), count(count), fractionalBusyness((double)count/totalCount), elapsed(elapsed) {}
}; };
std::map<Standalone<StringRef>, int64_t> intervalCounts; // TODO: use a hash for performance std::unordered_map<Standalone<StringRef>, int64_t, std::hash<StringRef>> intervalCounts;
int64_t intervalTotalCount = 0; int64_t intervalTotalCount = 0;
Standalone<StringRef> busiestTag; Standalone<StringRef> busiestTag;
int64_t busiestTagCount = 0; int64_t busiestTagCount = 0;

View File

@ -585,7 +585,17 @@ private:
}; };
#pragma pack( pop ) #pragma pack( pop )
template<> namespace std {
template <>
struct hash<StringRef> {
static constexpr std::hash<std::string_view> hashFunc{};
std::size_t operator()(StringRef const& tag) const {
return hashFunc(std::string_view((const char*)tag.begin(), tag.size()));
}
};
}
template <>
struct TraceableString<StringRef> { struct TraceableString<StringRef> {
static const char* begin(StringRef value) { static const char* begin(StringRef value) {
return reinterpret_cast<const char*>(value.begin()); return reinterpret_cast<const char*>(value.begin());

View File

@ -174,6 +174,29 @@ struct vector_like_traits<std::map<Key, T, Compare, Allocator>> : std::true_type
return v.begin(); return v.begin();
} }
}; };
template <class Key, class T, class Hash, class Pred, class Allocator>
struct vector_like_traits<std::unordered_map<Key, T, Hash, Pred, Allocator>> : std::true_type {
using Vec = std::unordered_map<Key, T, Hash, Pred, Allocator>;
using value_type = std::pair<Key, T>;
using iterator = typename Vec::const_iterator;
using insert_iterator = std::insert_iterator<Vec>;
template <class Context>
static size_t num_entries(const Vec& v, Context&) {
return v.size();
}
template <class Context>
static void reserve(Vec& v, size_t size, Context&) {}
template <class Context>
static insert_iterator insert(Vec& v, Context&) {
return std::inserter(v, v.end());
}
template <class Context>
static iterator begin(const Vec& v, Context&) {
return v.begin();
}
};
template <class Key, class Compare, class Allocator> template <class Key, class Compare, class Allocator>
struct vector_like_traits<std::set<Key, Compare, Allocator>> : std::true_type { struct vector_like_traits<std::set<Key, Compare, Allocator>> : std::true_type {