[channel-args] Do not mutate the AVL if there is no change (#33905)

Inserts and removals create `O(log(n))` new nodes with a persistent AVL
- which is nice - but if there's ultimately no mutation even this is
wasteful. Do some extra work in channel args to verify that there is
indeed a mutation, otherwise continue to share the same underlying
object.
pull/33907/head
Craig Tiller 1 year ago committed by GitHub
parent 2b3400052d
commit e5438767e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      src/core/lib/channel/channel_args.cc

@ -191,6 +191,9 @@ ChannelArgs ChannelArgs::Set(absl::string_view name, int value) const {
} }
ChannelArgs ChannelArgs::Set(absl::string_view name, Value value) const { ChannelArgs ChannelArgs::Set(absl::string_view name, Value value) const {
if (const auto* p = args_.Lookup(name)) {
if (*p == value) return *this; // already have this value for this key
}
return ChannelArgs(args_.Add(std::string(name), std::move(value))); return ChannelArgs(args_.Add(std::string(name), std::move(value)));
} }
@ -208,18 +211,17 @@ ChannelArgs ChannelArgs::Set(absl::string_view name, std::string value) const {
} }
ChannelArgs ChannelArgs::Remove(absl::string_view name) const { ChannelArgs ChannelArgs::Remove(absl::string_view name) const {
if (args_.Lookup(name) == nullptr) return *this;
return ChannelArgs(args_.Remove(name)); return ChannelArgs(args_.Remove(name));
} }
ChannelArgs ChannelArgs::RemoveAllKeysWithPrefix( ChannelArgs ChannelArgs::RemoveAllKeysWithPrefix(
absl::string_view prefix) const { absl::string_view prefix) const {
ChannelArgs result; auto args = args_;
args_.ForEach([&](const std::string& key, const Value& value) { args_.ForEach([&args, prefix](const std::string& key, const Value&) {
if (!absl::StartsWith(key, prefix)) { if (absl::StartsWith(key, prefix)) args = args.Remove(key);
result.args_ = result.args_.Add(key, value);
}
}); });
return result; return ChannelArgs(std::move(args));
} }
absl::optional<int> ChannelArgs::GetInt(absl::string_view name) const { absl::optional<int> ChannelArgs::GetInt(absl::string_view name) const {

Loading…
Cancel
Save