diff options
author | kvk1920 <kvk1920@yandex-team.com> | 2023-09-22 00:20:05 +0300 |
---|---|---|
committer | kvk1920 <kvk1920@yandex-team.com> | 2023-09-22 00:34:09 +0300 |
commit | e74e887de43ac6520b91832a062ff9478c3167c9 (patch) | |
tree | f16130b0aa7b87405c117e920a7bfb88cc4b663d | |
parent | 509d5166f4a73f954e28835885226e7f4a1635f0 (diff) | |
download | ydb-e74e887de43ac6520b91832a062ff9478c3167c9.tar.gz |
Get rid of TClusterResourceLimits::operator+()
-rw-r--r-- | library/cpp/yt/misc/property.h | 24 | ||||
-rw-r--r-- | yt/yt/core/misc/collection_helpers-inl.h | 1 | ||||
-rw-r--r-- | yt/yt/core/misc/collection_helpers.h | 4 | ||||
-rw-r--r-- | yt/yt/core/misc/default_map-inl.h | 40 | ||||
-rw-r--r-- | yt/yt/core/misc/default_map.h | 45 | ||||
-rw-r--r-- | yt/yt/core/misc/maybe_inf-inl.h | 109 | ||||
-rw-r--r-- | yt/yt/core/misc/maybe_inf.h | 47 | ||||
-rw-r--r-- | yt/yt/core/misc/serialize-inl.h | 17 | ||||
-rw-r--r-- | yt/yt/core/misc/serialize.h | 4 | ||||
-rw-r--r-- | yt/yt/core/misc/unittests/default_map_ut.cpp | 1 | ||||
-rw-r--r-- | yt/yt/core/misc/unittests/maybe_inf_ut.cpp | 24 |
11 files changed, 241 insertions, 75 deletions
diff --git a/library/cpp/yt/misc/property.h b/library/cpp/yt/misc/property.h index eb8264968e..d172fcdcfb 100644 --- a/library/cpp/yt/misc/property.h +++ b/library/cpp/yt/misc/property.h @@ -7,8 +7,8 @@ //! Declares a trivial public read-write property that is passed by reference. #define DECLARE_BYREF_RW_PROPERTY(type, name) \ public: \ - type& name(); \ - const type& name() const + type& name() noexcept; \ + const type& name() const noexcept //! Defines a trivial public read-write property that is passed by reference. //! All arguments after name are used as default value (via braced-init-list). @@ -17,12 +17,12 @@ protected: \ type name##_ { __VA_ARGS__ }; \ \ public: \ - Y_FORCE_INLINE type& name() \ + Y_FORCE_INLINE type& name() noexcept \ { \ return name##_; \ } \ \ - Y_FORCE_INLINE const type& name() const \ + Y_FORCE_INLINE const type& name() const noexcept \ { \ return name##_; \ } \ @@ -35,12 +35,12 @@ protected: \ type name##_; \ \ public: \ - Y_FORCE_INLINE type& name() \ + Y_FORCE_INLINE type& name() noexcept \ { \ return name##_; \ } \ \ - Y_FORCE_INLINE const type& name() const \ + Y_FORCE_INLINE const type& name() const noexcept \ { \ return name##_; \ } \ @@ -48,12 +48,12 @@ public: \ //! Forwards a trivial public read-write property that is passed by reference. #define DELEGATE_BYREF_RW_PROPERTY(declaringType, type, name, delegateTo) \ - type& declaringType::name() \ + type& declaringType::name() noexcept \ { \ return (delegateTo).name(); \ } \ \ - const type& declaringType::name() const \ + const type& declaringType::name() const noexcept \ { \ return (delegateTo).name(); \ } \ @@ -64,7 +64,7 @@ public: \ //! Declares a trivial public read-only property that is passed by reference. #define DECLARE_BYREF_RO_PROPERTY(type, name) \ public: \ - const type& name() const + const type& name() const noexcept //! Defines a trivial public read-only property that is passed by reference. //! All arguments after name are used as default value (via braced-init-list). @@ -73,7 +73,7 @@ protected: \ type name##_ { __VA_ARGS__ }; \ \ public: \ - Y_FORCE_INLINE const type& name() const \ + Y_FORCE_INLINE const type& name() const noexcept \ { \ return name##_; \ } \ @@ -86,7 +86,7 @@ protected: \ type name##_; \ \ public: \ - Y_FORCE_INLINE const type& name() const \ + Y_FORCE_INLINE const type& name() const noexcept \ { \ return name##_; \ } \ @@ -94,7 +94,7 @@ public: \ //! Forwards a trivial public read-only property that is passed by reference. #define DELEGATE_BYREF_RO_PROPERTY(declaringType, type, name, delegateTo) \ - const type& declaringType::name() const \ + const type& declaringType::name() const noexcept \ { \ return (delegateTo).name(); \ } \ diff --git a/yt/yt/core/misc/collection_helpers-inl.h b/yt/yt/core/misc/collection_helpers-inl.h index 81b615158a..0b50ba117a 100644 --- a/yt/yt/core/misc/collection_helpers-inl.h +++ b/yt/yt/core/misc/collection_helpers-inl.h @@ -217,6 +217,7 @@ typename TMap::mapped_type GetOrDefault( const TMap& map, const TKey& key, const typename TMap::mapped_type& defaultValue) + requires (!TIsDefaultMap<TMap>::Value) { auto it = map.find(key); return it == map.end() ? defaultValue : it->second; diff --git a/yt/yt/core/misc/collection_helpers.h b/yt/yt/core/misc/collection_helpers.h index 01e82a31b0..9719a5da6c 100644 --- a/yt/yt/core/misc/collection_helpers.h +++ b/yt/yt/core/misc/collection_helpers.h @@ -1,6 +1,7 @@ #pragma once #include "common.h" +#include "default_map.h" namespace NYT { @@ -111,7 +112,8 @@ template <class TMap, class TKey> typename TMap::mapped_type GetOrDefault( const TMap& map, const TKey& key, - const typename TMap::mapped_type& defaultValue = {}); + const typename TMap::mapped_type& defaultValue = {}) + requires (!TIsDefaultMap<TMap>::Value); template <class TMap, class TKey, class TCtor> auto& GetOrInsert(TMap&& map, const TKey& key, TCtor&& ctor); diff --git a/yt/yt/core/misc/default_map-inl.h b/yt/yt/core/misc/default_map-inl.h index e4eb0fd496..08b105fc4a 100644 --- a/yt/yt/core/misc/default_map-inl.h +++ b/yt/yt/core/misc/default_map-inl.h @@ -8,19 +8,47 @@ namespace NYT { //////////////////////////////////////////////////////////////////////////////// -template <class TUnderlying> -TDefaultMap<TUnderlying>::TDefaultMap(mapped_type defaultValue) +template <class T> +TDefaultMap<T>::TDefaultMap(mapped_type defaultValue) : DefaultValue_(std::move(defaultValue)) { } -template <class TUnderlying> +template <class T> template <class K> -typename TDefaultMap<TUnderlying>::mapped_type& TDefaultMap<TUnderlying>::operator[](const K& key) +typename TDefaultMap<T>::mapped_type& TDefaultMap<T>::operator[](const K& key) { - if (auto it = TUnderlying::find(key); it != TUnderlying::end()) { + if (auto it = T::find(key); it != T::end()) { return it->second; } - return TUnderlying::insert({key, DefaultValue_}).first->second; + return T::insert({key, DefaultValue_}).first->second; +} + +template <class T> +template <class K> +const typename TDefaultMap<T>::mapped_type& TDefaultMap<T>::GetOrDefault(const K& key) const +{ + auto it = T::find(key); + return it == T::end() ? DefaultValue_ : it->second; +} + +template <class T> +T& TDefaultMap<T>::AsUnderlying() noexcept +{ + return static_cast<T&>(*this); +} + +template <class T> +const T& TDefaultMap<T>::AsUnderlying() const noexcept +{ + return static_cast<const T&>(*this); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +void FormatValue(TStringBuilderBase* builder, const TDefaultMap<T>& map, TStringBuf format) +{ + FormatValue(builder, static_cast<const T&>(map), format); } //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/misc/default_map.h b/yt/yt/core/misc/default_map.h index dec954c09b..be20fc6a6e 100644 --- a/yt/yt/core/misc/default_map.h +++ b/yt/yt/core/misc/default_map.h @@ -1,25 +1,58 @@ #pragma once -#include <utility> +#include "property.h" + +#include <library/cpp/yt/string/string_builder.h> namespace NYT { //////////////////////////////////////////////////////////////////////////////// -template <class TUnderlying> +template <class T> class TDefaultMap - : public TUnderlying + : public T { public: - using mapped_type = typename TUnderlying::mapped_type; + using TUnderlying = T; + using mapped_type = typename T::mapped_type; + + DEFINE_BYREF_RO_PROPERTY(mapped_type, DefaultValue); + + TDefaultMap() = default; explicit TDefaultMap(mapped_type defaultValue); template <class K> mapped_type& operator[](const K& key); -private: - mapped_type DefaultValue_; + template <class K> + const mapped_type& GetOrDefault(const K& key) const; + + T& AsUnderlying() noexcept; + const T& AsUnderlying() const noexcept; + + // NB: There are no Save()/Load() since it can be easiliy (de)serialized + // manually. Moreover, it's easy to forget write compats when replacing + // THashTable to this one since Save()/Load() works out of the box. +}; + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +void FormatValue(TStringBuilderBase* builder, const TDefaultMap<T>& map, TStringBuf format); + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +struct TIsDefaultMap +{ + constexpr static bool Value = false; +}; + +template <class T> +struct TIsDefaultMap<TDefaultMap<T>> +{ + constexpr static bool Value = true; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/misc/maybe_inf-inl.h b/yt/yt/core/misc/maybe_inf-inl.h index 4c0111e337..cb8c46ea5c 100644 --- a/yt/yt/core/misc/maybe_inf-inl.h +++ b/yt/yt/core/misc/maybe_inf-inl.h @@ -4,84 +4,131 @@ #include "maybe_inf.h" #endif -#include <library/cpp/yt/assert/assert.h> - namespace NYT { //////////////////////////////////////////////////////////////////////////////// template <std::unsigned_integral T> -TMaybeInf<T>::TMaybeInf(T value) noexcept - : Value_(value) +template <std::unsigned_integral U> +TMaybeInf<T>::TMaybeInf(TMaybeInf<U> that) noexcept + : Value_(that.Value_) +{ + YT_ASSERT(that.Value_ < TTraits::Infinity); +} + +template <std::unsigned_integral T> +template <std::integral U> +TMaybeInf<T>::TMaybeInf(U value) noexcept + : Value_(static_cast<std::make_unsigned_t<U>>(value)) { - YT_ASSERT(value != TTraits::InfiniteValue); + if constexpr (std::is_signed_v<U>) { + YT_ASSERT(value >= 0); + } + YT_ASSERT(static_cast<std::make_unsigned_t<U>>(value) < TTraits::Infinity); } template <std::unsigned_integral T> TMaybeInf<T> TMaybeInf<T>::Infinity() noexcept { - // NB: Avoid using public constructor which prohibits infinity. + // NB: Public constructor does not accept infinity. TMaybeInf result; - result.Value_ = TTraits::InfiniteValue; + result.Value_ = TTraits::Infinity; return result; } template <std::unsigned_integral T> T TMaybeInf<T>::ToUnderlying() const noexcept { - YT_ASSERT(!IsInfinity()); + YT_ASSERT(IsFinite()); return Value_; } template <std::unsigned_integral T> -bool TMaybeInf<T>::IsInfinity() const noexcept +bool TMaybeInf<T>::IsInfinite() const noexcept { - return Value_ == TTraits::InfiniteValue; + return Value_ == TTraits::Infinity; } template <std::unsigned_integral T> -bool TMaybeInf<T>::CanBeIncreased(TMaybeInf delta) const noexcept +bool TMaybeInf<T>::IsFinite() const noexcept { - return (!IsInfinity() && !delta.IsInfinity()) || Value_ == 0 || delta.Value_ == 0; + return !IsInfinite(); } template <std::unsigned_integral T> -bool TMaybeInf<T>::CanBeDecreased(TMaybeInf delta) const noexcept +bool TMaybeInf<T>::CanIncrease(TMaybeInf delta) const noexcept { return - !delta.IsInfinity() && - (IsInfinity() ? delta.Value_ == 0 : Value_ >= delta.Value_); + delta.IsFinite() && + (IsFinite() || delta.Value_ == 0) && + Value_ + delta.Value_ >= Value_ && + Value_ + delta.Value_ < TTraits::Infinity; +} + +template <std::unsigned_integral T> +bool TMaybeInf<T>::CanDecrease(TMaybeInf delta) const noexcept +{ + return + delta.IsFinite() && + (IsFinite() || delta.Value_ == 0) && + Value_ >= delta.Value_; +} + +template <std::unsigned_integral T> +void TMaybeInf<T>::Increase(T delta) noexcept +{ + YT_ASSERT(CanIncrease(delta)); + Value_ += delta; } template <std::unsigned_integral T> -void TMaybeInf<T>::IncreaseBy(TMaybeInf delta) noexcept +void TMaybeInf<T>::Decrease(T delta) noexcept { - YT_ASSERT(CanBeIncreased(delta)); + YT_ASSERT(CanDecrease(delta)); + Value_ -= delta; +} - if (IsInfinity() || delta.IsInfinity()) { - Value_ = TTraits::InfiniteValue; +template <std::unsigned_integral T> +void TMaybeInf<T>::IncreaseWithInfinityAllowed(TMaybeInf that) noexcept +{ + YT_ASSERT(IsInfinite() || that.IsInfinite() || (Value_ + that.Value_ >= Value_)); + if (IsInfinite() || that.IsInfinite()) [[unlikely]] { + Value_ = TTraits::Infinity; } else { - auto newValue = Value_ + delta.ToUnderlying(); - // Check overflow. - YT_ASSERT(newValue != TTraits::InfiniteValue); - YT_ASSERT(newValue >= Value_); - Value_ = newValue; + Value_ += that.Value_; } } template <std::unsigned_integral T> -void TMaybeInf<T>::DecreaseBy(TMaybeInf delta) noexcept +void TMaybeInf<T>::UnsafeAssign(T value) noexcept { - YT_ASSERT(CanBeDecreased(delta)); - - Value_ -= delta.Value_; + Value_ = value; } template <std::unsigned_integral T> -std::strong_ordering TMaybeInf<T>::operator<=>(TMaybeInf that) const noexcept +T TMaybeInf<T>::UnsafeToUnderlying() const noexcept +{ + return Value_; +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +void FormatValue(TStringBuilderBase* builder, TMaybeInf<T> value, TStringBuf format) +{ + if (value.IsFinite()) { + FormatValue(builder, value.ToUnderlying(), format); + } else { + FormatValue(builder, "inf", format); + } +} + +template <class T> +TString ToString(TMaybeInf<T> value) { - // It works because infinity is represented as `numeric_limits<T>::max()`. - return Value_ <=> that.Value_; + TStringBuilder builder; + FormatValue(&builder, value); + return builder.Flush(); } //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/misc/maybe_inf.h b/yt/yt/core/misc/maybe_inf.h index b40e6bb8f8..3c77c9cf4d 100644 --- a/yt/yt/core/misc/maybe_inf.h +++ b/yt/yt/core/misc/maybe_inf.h @@ -1,5 +1,6 @@ #pragma once +#include <library/cpp/yt/string/format.h> #include <compare> #include <concepts> #include <limits> @@ -11,9 +12,14 @@ namespace NYT { template <std::unsigned_integral T> struct TMaybeInfTraits { - constexpr static T InfiniteValue = std::numeric_limits<T>::max(); + constexpr static T Infinity = std::numeric_limits<T>::max(); }; +//! Represents possibly infinite unsigned integer. +/*! + * This class represents possible infinite integer with some basic arithmetic. + * The main usage of it is transferring quotas which can be infinite. + */ template <std::unsigned_integral T> class TMaybeInf { @@ -22,23 +28,40 @@ public: TMaybeInf() noexcept = default; - explicit TMaybeInf(T value) noexcept; TMaybeInf(const TMaybeInf&) noexcept = default; TMaybeInf& operator=(const TMaybeInf&) noexcept = default; + template <std::unsigned_integral U> + explicit(std::numeric_limits<U>::max() > TTraits::Infinity) + TMaybeInf(TMaybeInf<U> that) noexcept; + + template <std::integral U> + explicit(std::is_signed_v<U>) + TMaybeInf(U value) noexcept; + static TMaybeInf Infinity() noexcept; + // Requires underlying value to be finite. T ToUnderlying() const noexcept; - bool IsInfinity() const noexcept; + bool IsInfinite() const noexcept; + bool IsFinite() const noexcept; + + //! Returns `false` on overflow or infinity-related operation. + bool CanIncrease(TMaybeInf delta) const noexcept; + bool CanDecrease(TMaybeInf delta) const noexcept; + + void Increase(T delta) noexcept; + void Decrease(T delta) noexcept; - bool CanBeIncreased(TMaybeInf delta) const noexcept; - bool CanBeDecreased(TMaybeInf delta) const noexcept; + void IncreaseWithInfinityAllowed(TMaybeInf that) noexcept; - void IncreaseBy(TMaybeInf delta) noexcept; - void DecreaseBy(TMaybeInf delta) noexcept; + // NB: It works since `InfiniteValue` is greater than all other possible values. + friend std::strong_ordering operator<=>(TMaybeInf lhs, TMaybeInf rhs) noexcept = default; - std::strong_ordering operator<=>(TMaybeInf that) const noexcept; + // Needed for Save()/Load(). + T UnsafeToUnderlying() const noexcept; + void UnsafeAssign(T value) noexcept; protected: T Value_ = 0; @@ -46,6 +69,14 @@ protected: //////////////////////////////////////////////////////////////////////////////// +template <class T> +void FormatValue(TStringBuilderBase* builder, TMaybeInf<T> value, TStringBuf format); + +template <class T> +TString ToString(TMaybeInf<T> value); + +//////////////////////////////////////////////////////////////////////////////// + } // namespace NYT #define MAYBE_INF_INL_H_ diff --git a/yt/yt/core/misc/serialize-inl.h b/yt/yt/core/misc/serialize-inl.h index db38f68fbd..4546621a37 100644 --- a/yt/yt/core/misc/serialize-inl.h +++ b/yt/yt/core/misc/serialize-inl.h @@ -1998,6 +1998,23 @@ struct TSerializerTraits<TStrongTypedef<T, TTag>, C, void> using TComparer = TValueBoundComparer; }; +template <class T, class C> +struct TSerializerTraits<TMaybeInf<T>, C, void> +{ + struct TSerializer + { + static void Save(C& context, TMaybeInf<T> value) + { + NYT::Save(context, value.UnsafeToUnderlying()); + } + + static void Load(C& context, TMaybeInf<T>& value) + { + value.UnsafeAssign(NYT::Load<T>(context)); + } + }; +}; + //////////////////////////////////////////////////////////////////////////////// } // namespace NYT diff --git a/yt/yt/core/misc/serialize.h b/yt/yt/core/misc/serialize.h index 165a4442d2..751b5fcac3 100644 --- a/yt/yt/core/misc/serialize.h +++ b/yt/yt/core/misc/serialize.h @@ -6,10 +6,12 @@ #include "property.h" #include "serialize_dump.h" -#include <library/cpp/yt/memory/ref.h> +#include "maybe_inf.h" #include <library/cpp/yt/assert/assert.h> +#include <library/cpp/yt/memory/ref.h> + #include <util/stream/buffered.h> #include <util/stream/file.h> #include <util/stream/zerocopy_output.h> diff --git a/yt/yt/core/misc/unittests/default_map_ut.cpp b/yt/yt/core/misc/unittests/default_map_ut.cpp index f40d3719f1..07884ca1dc 100644 --- a/yt/yt/core/misc/unittests/default_map_ut.cpp +++ b/yt/yt/core/misc/unittests/default_map_ut.cpp @@ -18,6 +18,7 @@ TEST(TDefaultMap, Common) defaultMap.insert({2, "abc"}); EXPECT_EQ(defaultMap[2], "abc"); EXPECT_EQ(defaultMap.find(3), defaultMap.end()); + EXPECT_EQ(defaultMap.GetOrDefault(7), "Hello"); } //////////////////////////////////////////////////////////////////////////////// diff --git a/yt/yt/core/misc/unittests/maybe_inf_ut.cpp b/yt/yt/core/misc/unittests/maybe_inf_ut.cpp index ac2d3ce9d8..27504f1f4f 100644 --- a/yt/yt/core/misc/unittests/maybe_inf_ut.cpp +++ b/yt/yt/core/misc/unittests/maybe_inf_ut.cpp @@ -7,11 +7,15 @@ namespace { //////////////////////////////////////////////////////////////////////////////// -TEST(TMaybeInf, IncreaseBy) +TEST(TMaybeInf, Increase) { using TLimit = TMaybeInf<ui32>; TLimit a(1); - EXPECT_FALSE(a.CanBeIncreased(TLimit::Infinity())); + EXPECT_FALSE(a.CanIncrease(TLimit::Infinity())); + EXPECT_TRUE(a.CanIncrease(TLimit(1))); + a.Increase(TLimit(1).ToUnderlying()); + EXPECT_EQ(a.ToUnderlying(), ui32(2)); + EXPECT_TRUE(a.IsFinite()); } TEST(TMaybeInf, DecreaseBy) @@ -19,22 +23,22 @@ TEST(TMaybeInf, DecreaseBy) using TLimit = TMaybeInf<ui32>; TLimit a(1); auto b = TLimit::Infinity(); - EXPECT_FALSE(a.CanBeDecreased(b)); + EXPECT_FALSE(a.CanDecrease(b)); a = TLimit::Infinity(); - EXPECT_FALSE(a.CanBeDecreased(b)); + EXPECT_FALSE(a.CanDecrease(b)); b = TLimit(); - EXPECT_TRUE(a.CanBeDecreased(b)); + EXPECT_TRUE(a.CanDecrease(b)); b = TLimit(1); - EXPECT_FALSE(a.CanBeDecreased(b)); + EXPECT_FALSE(a.CanDecrease(b)); a = TLimit(4); - EXPECT_TRUE(a.CanBeDecreased(b)); + EXPECT_TRUE(a.CanDecrease(b)); b = TLimit(4); - EXPECT_TRUE(a.CanBeDecreased(b)); - a.DecreaseBy(b); + EXPECT_TRUE(a.CanDecrease(b)); + a.Decrease(b.ToUnderlying()); EXPECT_EQ(a.ToUnderlying(), 0u); a = TLimit(4); b = TLimit(5); - EXPECT_FALSE(a.CanBeDecreased(b)); + EXPECT_FALSE(a.CanDecrease(b)); } //////////////////////////////////////////////////////////////////////////////// |