aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkvk1920 <kvk1920@yandex-team.com>2023-09-22 00:20:05 +0300
committerkvk1920 <kvk1920@yandex-team.com>2023-09-22 00:34:09 +0300
commite74e887de43ac6520b91832a062ff9478c3167c9 (patch)
treef16130b0aa7b87405c117e920a7bfb88cc4b663d
parent509d5166f4a73f954e28835885226e7f4a1635f0 (diff)
downloadydb-e74e887de43ac6520b91832a062ff9478c3167c9.tar.gz
Get rid of TClusterResourceLimits::operator+()
-rw-r--r--library/cpp/yt/misc/property.h24
-rw-r--r--yt/yt/core/misc/collection_helpers-inl.h1
-rw-r--r--yt/yt/core/misc/collection_helpers.h4
-rw-r--r--yt/yt/core/misc/default_map-inl.h40
-rw-r--r--yt/yt/core/misc/default_map.h45
-rw-r--r--yt/yt/core/misc/maybe_inf-inl.h109
-rw-r--r--yt/yt/core/misc/maybe_inf.h47
-rw-r--r--yt/yt/core/misc/serialize-inl.h17
-rw-r--r--yt/yt/core/misc/serialize.h4
-rw-r--r--yt/yt/core/misc/unittests/default_map_ut.cpp1
-rw-r--r--yt/yt/core/misc/unittests/maybe_inf_ut.cpp24
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));
}
////////////////////////////////////////////////////////////////////////////////