Merge pull request #20443 from markdroth/lb_policy_metadata_api

Use a more standard iteration interface for LB policy metadata API.
reviewable/pr20475/r1
Mark D. Roth 5 years ago committed by GitHub
commit ae566a15e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 44
      src/core/ext/filters/client_channel/client_channel.cc
  2. 56
      src/core/ext/filters/client_channel/lb_policy.h
  3. 9
      test/core/util/test_lb_policies.cc

@ -376,35 +376,39 @@ class CallData {
GRPC_ERROR_NONE);
}
Iterator Begin() const override {
static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(Iterator),
iterator begin() const override {
static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(intptr_t),
"iterator size too large");
return reinterpret_cast<Iterator>(batch_->list.head);
return iterator(this, reinterpret_cast<intptr_t>(batch_->list.head));
}
bool IsEnd(Iterator it) const override {
return reinterpret_cast<grpc_linked_mdelem*>(it) == nullptr;
}
void Next(Iterator* it) const override {
*it = reinterpret_cast<Iterator>(
reinterpret_cast<grpc_linked_mdelem*>(*it)->next);
}
StringView Key(Iterator it) const override {
return StringView(
GRPC_MDKEY(reinterpret_cast<grpc_linked_mdelem*>(it)->md));
}
StringView Value(Iterator it) const override {
return StringView(
GRPC_MDVALUE(reinterpret_cast<grpc_linked_mdelem*>(it)->md));
iterator end() const override {
static_assert(sizeof(grpc_linked_mdelem*) <= sizeof(intptr_t),
"iterator size too large");
return iterator(this, 0);
}
void Erase(Iterator* it) override {
iterator erase(iterator it) override {
grpc_linked_mdelem* linked_mdelem =
reinterpret_cast<grpc_linked_mdelem*>(*it);
*it = reinterpret_cast<Iterator>(linked_mdelem->next);
reinterpret_cast<grpc_linked_mdelem*>(GetIteratorHandle(it));
intptr_t handle = reinterpret_cast<intptr_t>(linked_mdelem->next);
grpc_metadata_batch_remove(batch_, linked_mdelem);
return iterator(this, handle);
}
private:
intptr_t IteratorHandleNext(intptr_t handle) const override {
grpc_linked_mdelem* linked_mdelem =
reinterpret_cast<grpc_linked_mdelem*>(handle);
return reinterpret_cast<intptr_t>(linked_mdelem->next);
}
std::pair<StringView, StringView> IteratorHandleGet(
intptr_t handle) const override {
grpc_linked_mdelem* linked_mdelem =
reinterpret_cast<grpc_linked_mdelem*>(handle);
return std::make_pair(StringView(GRPC_MDKEY(linked_mdelem->md)),
StringView(GRPC_MDVALUE(linked_mdelem->md)));
}
CallData* calld_;
grpc_metadata_batch* batch_;
};

@ -21,6 +21,8 @@
#include <grpc/support/port_platform.h>
#include <iterator>
#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/ext/filters/client_channel/subchannel_interface.h"
@ -119,10 +121,31 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
/// Implemented by the client channel and used by the SubchannelPicker.
class MetadataInterface {
public:
// Implementations whose iterators fit in intptr_t may internally
// cast this directly to their iterator type. Otherwise, they may
// dynamically allocate their iterators and store the address here.
typedef intptr_t Iterator;
class iterator
: public std::iterator<std::input_iterator_tag,
std::pair<StringView, StringView>, // value_type
std::ptrdiff_t, // difference_type
std::pair<StringView, StringView>*, // pointer
std::pair<StringView, StringView>& // reference
> {
public:
iterator(const MetadataInterface* md, intptr_t handle)
: md_(md), handle_(handle) {}
iterator& operator++() {
handle_ = md_->IteratorHandleNext(handle_);
return *this;
}
bool operator==(iterator other) const {
return md_ == other.md_ && handle_ == other.handle_;
}
bool operator!=(iterator other) const { return !(*this == other); }
value_type operator*() const { return md_->IteratorHandleGet(handle_); }
private:
friend class MetadataInterface;
const MetadataInterface* md_;
intptr_t handle_;
};
virtual ~MetadataInterface() = default;
@ -134,15 +157,22 @@ class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
virtual void Add(StringView key, StringView value) = 0;
/// Iteration interface.
virtual Iterator Begin() const = 0;
virtual bool IsEnd(Iterator it) const = 0;
virtual void Next(Iterator* it) const = 0;
virtual StringView Key(Iterator it) const = 0;
virtual StringView Value(Iterator it) const = 0;
/// Removes the element pointed to by \a it, which is modified to
/// point to the next element.
virtual void Erase(Iterator* it) = 0;
virtual iterator begin() const = 0;
virtual iterator end() const = 0;
/// Removes the element pointed to by \a it.
/// Returns an iterator pointing to the next element.
virtual iterator erase(iterator it) = 0;
protected:
intptr_t GetIteratorHandle(const iterator& it) const { return it.handle_; }
private:
friend class iterator;
virtual intptr_t IteratorHandleNext(intptr_t handle) const = 0;
virtual std::pair<StringView /*key*/, StringView /*value */>
IteratorHandleGet(intptr_t handle) const = 0;
};
/// Arguments used when picking a subchannel for a call.

@ -201,13 +201,10 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy
};
static void LogMetadata(MetadataInterface* metadata) {
for (MetadataInterface::Iterator it = metadata->Begin();
!metadata->IsEnd(it); metadata->Next(&it)) {
for (const auto& p : *metadata) {
gpr_log(GPR_INFO, " \"%.*s\"=>\"%.*s\"",
static_cast<int>(metadata->Key(it).size()),
metadata->Key(it).data(),
static_cast<int>(metadata->Value(it).size()),
metadata->Value(it).data());
static_cast<int>(p.first.size()), p.first.data(),
static_cast<int>(p.second.size()), p.second.data());
}
}
};

Loading…
Cancel
Save