aboutsummaryrefslogtreecommitdiffstats
path: root/library
diff options
context:
space:
mode:
authorarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-02-18 16:35:49 +0300
committerarcadia-devtools <arcadia-devtools@yandex-team.ru>2022-02-18 16:35:49 +0300
commitedefa564e11987d4aa60fff0a2378785deb03b54 (patch)
tree66e32a4d0284fb784a73d76f5531b708cd72be44 /library
parent04182a7d083f485a3364f570da83470e580c78ac (diff)
downloadydb-edefa564e11987d4aa60fff0a2378785deb03b54.tar.gz
intermediate changes
ref:5a427ceffcbeddcbaed23c62818445bd98632b96
Diffstat (limited to 'library')
-rw-r--r--library/cpp/cache/cache.h165
-rw-r--r--library/cpp/cache/ut/cache_ut.cpp48
-rw-r--r--library/cpp/http/misc/httpreqdata.cpp2
-rw-r--r--library/cpp/string_utils/quote/quote.cpp6
4 files changed, 188 insertions, 33 deletions
diff --git a/library/cpp/cache/cache.h b/library/cpp/cache/cache.h
index 6dc997076d..22075fd94f 100644
--- a/library/cpp/cache/cache.h
+++ b/library/cpp/cache/cache.h
@@ -30,20 +30,32 @@ public:
public:
struct TItem: public TIntrusiveListItem<TItem> {
typedef TIntrusiveListItem<TItem> TBase;
- TItem(const TKey& key, const TValue& value = TValue())
+ // universal reference for TKey here prevents TItem(TItem&) from compiling,
+ // so explicitly specify const TKey& and TKey&&
+ TItem(const TKey& key)
: TBase()
, Key(key)
- , Value(value)
+ , Value()
+ {
+ }
+ TItem(TKey&& key)
+ : TBase()
+ , Key(std::move(key))
+ , Value()
{
}
- TItem(const TItem& rhs)
+ template<typename TKeyRef, typename TValueRef>
+ TItem(TKeyRef&& key, TValueRef&& value)
: TBase()
- , Key(rhs.Key)
- , Value(rhs.Value)
+ , Key(std::forward<TKeyRef>(key))
+ , Value(std::forward<TValueRef>(value))
{
}
+ TItem(const TItem&) = default;
+ TItem(TItem&&) = default;
+
bool operator<(const TItem& rhs) const {
return Key < rhs.Key;
}
@@ -59,6 +71,21 @@ public:
size_t operator()(const TItem& item) const {
return ::THash<TKey>()(item.Key);
}
+ size_t operator()(const TKey& key) const {
+ return ::THash<TKey>()(key);
+ }
+ };
+
+ struct TEqualTo {
+ bool operator()(const TItem& lhs, const TItem& rhs) const {
+ return lhs.Key == rhs.Key;
+ }
+ bool operator()(const TItem& lhs, const TKey& rhs) const {
+ return lhs.Key == rhs;
+ }
+ bool operator()(const TKey& lhs, const TItem& rhs) const {
+ return lhs == rhs.Key;
+ }
};
};
@@ -136,22 +163,33 @@ public:
struct TItem: public TIntrusiveListItem<TItem> {
typedef TIntrusiveListItem<TItem> TBase;
- TItem(const TKey& key, const TValue& value = TValue())
+ explicit TItem(const TKey& key)
: TBase()
, Key(key)
- , Value(value)
+ , Value()
+ , Counter(0)
+ {
+ }
+ explicit TItem(TKey&& key)
+ : TBase()
+ , Key(std::move(key))
+ , Value()
, Counter(0)
{
}
- TItem(const TItem& rhs)
+ template<typename TKeyRef, typename TValueRef>
+ TItem(TKeyRef&& key, TValueRef&& value)
: TBase()
- , Key(rhs.Key)
- , Value(rhs.Value)
- , Counter(rhs.Counter)
+ , Key(std::forward<TKeyRef>(key))
+ , Value(std::forward<TValueRef>(value))
+ , Counter(0)
{
}
+ TItem(const TItem&) = default;
+ TItem(TItem&&) = default;
+
bool operator<(const TItem& rhs) const {
return Key < rhs.Key;
}
@@ -168,6 +206,21 @@ public:
size_t operator()(const TItem& item) const {
return ::THash<TKey>()(item.Key);
}
+ size_t operator()(const TKey& key) const {
+ return ::THash<TKey>()(key);
+ }
+ };
+
+ struct TEqualTo {
+ bool operator()(const TItem& lhs, const TItem& rhs) const {
+ return lhs.Key == rhs.Key;
+ }
+ bool operator()(const TItem& lhs, const TKey& rhs) const {
+ return lhs.Key == rhs;
+ }
+ bool operator()(const TKey& lhs, const TItem& rhs) const {
+ return lhs == rhs.Key;
+ }
};
};
@@ -242,20 +295,30 @@ public:
}
struct TItem {
- TItem(const TKey& key, const TValue& value = TValue())
+ TItem(const TKey& key)
: Key(key)
- , Value(value)
- , Weight(TWeighter::Weight(value))
+ , Value()
+ , Weight(TWeighter::Weight(Value))
+ {
+ }
+ TItem(TKey&& key)
+ : Key(std::move(key))
+ , Value()
+ , Weight(TWeighter::Weight(Value))
{
}
- TItem(const TItem& rhs)
- : Key(rhs.Key)
- , Value(rhs.Value)
- , Weight(rhs.Weight)
+ template<typename TKeyRef, typename TValueRef>
+ TItem(TKeyRef&& key, TValueRef&& value)
+ : Key(std::forward<TKeyRef>(key))
+ , Value(std::forward<TValueRef>(value))
+ , Weight(TWeighter::Weight(Value))
{
}
+ TItem(const TItem&) = default;
+ TItem(TItem&&) = default;
+
bool operator<(const TItem& rhs) const {
return Key < rhs.Key;
}
@@ -272,6 +335,21 @@ public:
size_t operator()(const TItem& item) const {
return ::THash<TKey>()(item.Key);
}
+ size_t operator()(const TKey& key) const {
+ return ::THash<TKey>()(key);
+ }
+ };
+
+ struct TEqualTo {
+ bool operator()(const TItem& lhs, const TItem& rhs) const {
+ return lhs.Key == rhs.Key;
+ }
+ bool operator()(const TItem& lhs, const TKey& rhs) const {
+ return lhs.Key == rhs;
+ }
+ bool operator()(const TKey& lhs, const TItem& rhs) const {
+ return lhs == rhs.Key;
+ }
};
};
@@ -377,7 +455,7 @@ template <typename TKey, typename TValue, typename TListType, typename TDeleter>
class TCache {
typedef typename TListType::TItem TItem;
typedef typename TItem::THash THash;
- typedef THashMultiSet<TItem, THash> TIndex;
+ typedef THashMultiSet<TItem, THash, typename TItem::TEqualTo> TIndex;
typedef typename TIndex::iterator TIndexIterator;
typedef typename TIndex::const_iterator TIndexConstIterator;
@@ -448,23 +526,23 @@ public:
}
TIterator Find(const TKey& key) {
- TIndexIterator it = Index.find(TItem(key));
+ TIndexIterator it = Index.find(key);
if (it != Index.end())
List.Promote(const_cast<TItem*>(&*it));
return TIterator(it);
}
TIterator FindWithoutPromote(const TKey& key) const {
- return TIterator(Index.find(TItem(key)));
+ return TIterator(Index.find(key));
}
// note: it shouldn't touch 'value' if it returns false.
bool PickOut(const TKey& key, TValue* value) {
Y_ASSERT(value);
- TIndexIterator it = Index.find(TItem(key));
+ TIndexIterator it = Index.find(key);
if (it == Index.end())
return false;
- *value = it->Value;
+ *value = std::move(it->Value);
List.Erase(const_cast<TItem*>(&*it));
Index.erase(it);
Y_ASSERT(Index.size() == List.GetSize());
@@ -475,11 +553,11 @@ public:
return Insert(p.first, p.second);
}
- bool Insert(const TKey& key, const TValue& value) {
- TItem tmpItem(key, value);
- if (!MultiValue && Index.find(tmpItem) != Index.end())
+ template<typename TKeyRef, typename TValueRef>
+ bool InsertImpl(TKeyRef&& key, TValueRef&& value) {
+ if (!MultiValue && Index.find(key) != Index.end())
return false;
- TIndexIterator it = Index.insert(tmpItem);
+ TIndexIterator it = Index.emplace(std::forward<TKeyRef>(key), std::forward<TValueRef>(value));
TItem* insertedItem = const_cast<TItem*>(&*it);
auto removedItem = List.Insert(insertedItem);
@@ -496,18 +574,47 @@ public:
return !insertedWasRemoved;
}
- void Update(const TKey& key, const TValue& value) {
+ // a lot of code calls Insert(key, {arguments for TValue constructor})
+ // template version InsertImpl can not process this
+ bool Insert(const TKey& key, const TValue& value) {
+ return InsertImpl(key, value);
+ }
+ bool Insert(const TKey& key, TValue&& value) {
+ return InsertImpl(key, std::move(value));
+ }
+ bool Insert(TKey&& key, const TValue& value) {
+ return InsertImpl(std::move(key), value);
+ }
+ bool Insert(TKey&& key, TValue&& value) {
+ return InsertImpl(std::move(key), std::move(value));
+ }
+
+ template<typename TKeyRef, typename TValueRef>
+ void UpdateImpl(TKeyRef&& key, TValueRef&& value) {
if (MultiValue)
ythrow yexception() << "TCache: can't \"Update\" in multicache";
TIterator it = Find(key);
if (it != End()) {
Erase(it);
}
- Insert(key, value);
+ InsertImpl(std::forward<TKeyRef>(key), std::forward<TValueRef>(value));
Y_ASSERT(Index.size() == List.GetSize());
}
+ void Update(const TKey& key, const TValue& value) {
+ UpdateImpl(key, value);
+ }
+ void Update(const TKey& key, TValue&& value) {
+ UpdateImpl(key, std::move(value));
+ }
+ void Update(TKey&& key, const TValue& value) {
+ UpdateImpl(std::move(key), value);
+ }
+ void Update(TKey&& key, TValue&& value) {
+ UpdateImpl(std::move(key), std::move(value));
+ }
+
void Erase(TIterator it) {
TItem* item = const_cast<TItem*>(&*it.Iter);
List.Erase(item);
diff --git a/library/cpp/cache/ut/cache_ut.cpp b/library/cpp/cache/ut/cache_ut.cpp
index 329872cfde..33731988c1 100644
--- a/library/cpp/cache/ut/cache_ut.cpp
+++ b/library/cpp/cache/ut/cache_ut.cpp
@@ -355,6 +355,54 @@ Y_UNIT_TEST_SUITE(TCacheTest) {
s.Insert(3, "789");
UNIT_ASSERT(s.Find(1) != s.End()); // Key 2 should have been deleted
}
+
+ class TMoveOnlyInt {
+ public:
+ ui32 Value = 0;
+
+ explicit TMoveOnlyInt(ui32 value = 0) : Value(value) {}
+ TMoveOnlyInt(TMoveOnlyInt&&) = default;
+ TMoveOnlyInt& operator=(TMoveOnlyInt&&) = default;
+
+ TMoveOnlyInt(const TMoveOnlyInt&) = delete;
+ TMoveOnlyInt& operator=(const TMoveOnlyInt&) = delete;
+
+ bool operator==(const TMoveOnlyInt& rhs) const {
+ return Value == rhs.Value;
+ }
+
+ explicit operator size_t() const {
+ return Value;
+ }
+ };
+
+ Y_UNIT_TEST(MoveOnlySimpleTest) {
+ typedef TLRUCache<TMoveOnlyInt, TMoveOnlyInt> TCache;
+ TCache s(2); // size 2
+ s.Insert(TMoveOnlyInt(1), TMoveOnlyInt(0x11111111));
+ TMoveOnlyInt lookup1(1), lookup2(2), lookup3(3);
+ UNIT_ASSERT(s.Find(lookup1) != s.End());
+ UNIT_ASSERT_EQUAL(s.Find(lookup1)->Value, 0x11111111);
+ s.Insert(TMoveOnlyInt(2), TMoveOnlyInt(0x22222222));
+ UNIT_ASSERT(s.GetOldest().Value == 0x11111111);
+ s.Insert(TMoveOnlyInt(3), TMoveOnlyInt(0x33333333));
+ UNIT_ASSERT(s.GetOldest().Value == 0x22222222);
+ // key 1 will be deleted
+ UNIT_ASSERT(s.Find(lookup1) == s.End());
+ UNIT_ASSERT(s.Find(lookup2) != s.End());
+ UNIT_ASSERT(s.Find(lookup2)->Value == 0x22222222);
+ UNIT_ASSERT(s.Find(lookup3) != s.End());
+ UNIT_ASSERT(s.Find(lookup3)->Value == 0x33333333);
+
+ UNIT_ASSERT(!s.Insert(TMoveOnlyInt(3), TMoveOnlyInt(0x11111111)));
+ UNIT_ASSERT(s.Find(lookup3)->Value == 0x33333333);
+ s.Update(TMoveOnlyInt(3), TMoveOnlyInt(0x11111111));
+ UNIT_ASSERT(s.Find(lookup3)->Value == 0x11111111);
+
+ TCache::TIterator it = s.Find(lookup3);
+ s.Erase(it);
+ UNIT_ASSERT(s.Find(lookup3) == s.End());
+ }
}
Y_UNIT_TEST_SUITE(TThreadSafeCacheTest) {
diff --git a/library/cpp/http/misc/httpreqdata.cpp b/library/cpp/http/misc/httpreqdata.cpp
index f02611bc58..38bdad3996 100644
--- a/library/cpp/http/misc/httpreqdata.cpp
+++ b/library/cpp/http/misc/httpreqdata.cpp
@@ -35,7 +35,7 @@ TStringBuf TBaseServerRequestData::RemoteAddr() const {
if (!Addr_) {
auto& addr = Addr_.ConstructInPlace();
addr.ReserveAndResize(INET6_ADDRSTRLEN);
- if (GetRemoteAddr(Socket_, addr.begin(), sizeof(INET6_ADDRSTRLEN))) {
+ if (GetRemoteAddr(Socket_, addr.begin(), addr.size())) {
if (auto pos = addr.find('\0'); pos != TString::npos) {
addr.resize(pos);
}
diff --git a/library/cpp/string_utils/quote/quote.cpp b/library/cpp/string_utils/quote/quote.cpp
index e523350b80..bac72d07fc 100644
--- a/library/cpp/string_utils/quote/quote.cpp
+++ b/library/cpp/string_utils/quote/quote.cpp
@@ -48,7 +48,7 @@ namespace {
class TFromHexLenLimited {
public:
- TFromHexLenLimited(const char* end)
+ explicit TFromHexLenLimited(const char* end)
: End(end)
{
}
@@ -189,11 +189,11 @@ static inline It1 Quote(It1 to, It2 from, It3 end, const char* safe) {
// lists following reserved characters:
const char* reserved = ":/?#[]@!$&\'()*+,;=";
for (const char* p = reserved; *p; ++p) {
- escape_map[(unsigned char)*p] = 1;
+ escape_map[(unsigned char)*p] = true;
}
// characters we think are safe at the moment
for (const char* p = safe; *p; ++p) {
- escape_map[(unsigned char)*p] = 0;
+ escape_map[(unsigned char)*p] = false;
}
return Escape(to, from, end, escape_map);