mirror of https://github.com/grpc/grpc.git
[hpack] Track global hit rate on hpack cache (#37331)
Closes #37331
COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/37331 from ctiller:hpack_hit_rate 1dbfd5c424
PiperOrigin-RevId: 659396510
pull/37399/head
parent
c2f1f929c6
commit
a35ce3d68c
23 changed files with 501 additions and 15 deletions
@ -0,0 +1,84 @@ |
||||
// Copyright 2024 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef GRPC_SRC_CORE_UTIL_UNIQUE_PTR_WITH_BITSET_H |
||||
#define GRPC_SRC_CORE_UTIL_UNIQUE_PTR_WITH_BITSET_H |
||||
|
||||
#include <memory> |
||||
#include <utility> |
||||
|
||||
#include "absl/log/check.h" |
||||
#include "absl/numeric/bits.h" |
||||
|
||||
namespace grpc_core { |
||||
|
||||
// Like std::unique_ptr, but also includes a small bitset stored in the lower
|
||||
// bits of the underlying T*.
|
||||
template <typename T, size_t kBits> |
||||
class UniquePtrWithBitset { |
||||
public: |
||||
UniquePtrWithBitset() : p_(0) {} |
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
UniquePtrWithBitset(std::nullptr_t) : p_(0) {} |
||||
explicit UniquePtrWithBitset(T* p) : p_(reinterpret_cast<uintptr_t>(p)) {} |
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
UniquePtrWithBitset(std::unique_ptr<T>&& p) |
||||
: UniquePtrWithBitset(p.release()) {} |
||||
~UniquePtrWithBitset() { delete get(); } |
||||
UniquePtrWithBitset(const UniquePtrWithBitset&) = delete; |
||||
UniquePtrWithBitset& operator=(const UniquePtrWithBitset&) = delete; |
||||
UniquePtrWithBitset(UniquePtrWithBitset&& other) noexcept |
||||
: p_(std::exchange(other.p_, 0)) {} |
||||
UniquePtrWithBitset& operator=(UniquePtrWithBitset&& other) noexcept { |
||||
p_ = std::exchange(other.p_, 0); |
||||
return *this; |
||||
} |
||||
|
||||
T* get() const { return reinterpret_cast<T*>(p_ & ~kBitMask); } |
||||
T* operator->() const { return get(); } |
||||
T& operator*() const { return *get(); } |
||||
explicit operator bool() const { return get() != nullptr; } |
||||
void reset(T* p = nullptr) { |
||||
uintptr_t bits = p_ & kBitMask; |
||||
delete get(); |
||||
p_ = reinterpret_cast<uintptr_t>(p) | bits; |
||||
} |
||||
|
||||
void SetBit(size_t bit) { |
||||
DCHECK_LT(bit, kBits); |
||||
p_ |= 1 << bit; |
||||
} |
||||
void ClearBit(size_t bit) { |
||||
DCHECK_LT(bit, kBits); |
||||
p_ &= ~(1 << bit); |
||||
} |
||||
bool TestBit(size_t bit) const { |
||||
DCHECK_LT(bit, kBits); |
||||
return p_ & (1 << bit); |
||||
} |
||||
|
||||
friend bool operator==(const UniquePtrWithBitset& a, |
||||
const UniquePtrWithBitset& b) { |
||||
return a.p_ == b.p_; |
||||
} |
||||
|
||||
private: |
||||
static_assert(kBits <= absl::countr_zero(alignof(T)), "kBits too large"); |
||||
static constexpr uintptr_t kBitMask = (1 << kBits) - 1; |
||||
uintptr_t p_; |
||||
}; |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_UTIL_UNIQUE_PTR_WITH_BITSET_H
|
@ -0,0 +1,60 @@ |
||||
//
|
||||
//
|
||||
// Copyright 2015 gRPC authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//
|
||||
|
||||
#include "src/core/util/unique_ptr_with_bitset.h" |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include <limits> |
||||
#include <memory> |
||||
|
||||
#include "gtest/gtest.h" |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
namespace grpc_core { |
||||
|
||||
TEST(UniquePtrWithBitsetTest, Basic) { |
||||
UniquePtrWithBitset<int, 1> ptr; |
||||
EXPECT_EQ(ptr.get(), nullptr); |
||||
EXPECT_EQ(ptr.TestBit(0), false); |
||||
ptr.reset(new int(42)); |
||||
EXPECT_EQ(*ptr, 42); |
||||
EXPECT_EQ(ptr.TestBit(0), false); |
||||
ptr.SetBit(0); |
||||
EXPECT_EQ(ptr.TestBit(0), true); |
||||
ptr.reset(); |
||||
EXPECT_EQ(ptr.get(), nullptr); |
||||
EXPECT_EQ(ptr.TestBit(0), true); |
||||
ptr.ClearBit(0); |
||||
EXPECT_EQ(ptr.TestBit(0), false); |
||||
ptr.reset(new int(43)); |
||||
ptr.SetBit(0); |
||||
|
||||
UniquePtrWithBitset<int, 1> ptr2; |
||||
ptr2 = std::move(ptr); |
||||
EXPECT_EQ(*ptr2, 43); |
||||
EXPECT_EQ(ptr2.TestBit(0), true); |
||||
} |
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
int main(int argc, char** argv) { |
||||
::testing::InitGoogleTest(&argc, argv); |
||||
return RUN_ALL_TESTS(); |
||||
} |
Loading…
Reference in new issue