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;
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;

View File

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

View File

@ -86,6 +86,8 @@ struct TagThrottleInfo {
}
};
BINARY_SERIALIZABLE(TagThrottleInfo::Priority);
class TagSet {
public:
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 {
// 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,
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> leaseTimeout = 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,
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 = _baseReply;
double end = g_network->timer();
@ -1353,7 +1353,7 @@ ACTOR static Future<Void> transactionStarter(
state Deque<GetReadVersionRequest> batchQueue;
state vector<MasterProxyInterface> otherProxies;
state std::map<TagThrottleInfo::Priority, std::map<Standalone<StringRef>, TagThrottleInfo>> throttledTags;
state PrioritizedTagThrottleMap throttledTags;
state PromiseStream<double> replyTimes;
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 lastSSListFetchedTimestamp;
typedef std::map<Standalone<StringRef>, TagThrottleInfo> ThrottleMap;
std::map<TagThrottleInfo::Priority, ThrottleMap> tagThrottles;
PrioritizedTagThrottleMap tagThrottles;
RatekeeperLimits normalLimits;
RatekeeperLimits batchLimits;
@ -417,8 +416,8 @@ ACTOR Future<Void> monitorThrottlingChanges(RatekeeperData *self) {
}
TraceEvent("RatekeeperReadThrottles").detail("NumThrottledTags", throttledTags.get().size());
std::map<TagThrottleInfo::Priority, RatekeeperData::ThrottleMap> newThrottles;
std::map<TagThrottleInfo::Priority, std::pair<RatekeeperData::ThrottleMap::iterator, RatekeeperData::ThrottleMap::iterator>> oldThrottleIterators;
PrioritizedTagThrottleMap newThrottles;
std::map<TagThrottleInfo::Priority, std::pair<TagThrottleMap::iterator, TagThrottleMap::iterator>> oldThrottleIterators;
for(auto t : self->tagThrottles) {
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 actualTps = self->smoothReleasedTransactions.smoothRate();

View File

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

View File

@ -460,7 +460,7 @@ public:
: 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;
Standalone<StringRef> busiestTag;
int64_t busiestTagCount = 0;

View File

@ -585,7 +585,17 @@ private:
};
#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> {
static const char* begin(StringRef value) {
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();
}
};
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>
struct vector_like_traits<std::set<Key, Compare, Allocator>> : std::true_type {