diff options
author | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-02-18 16:35:49 +0300 |
---|---|---|
committer | arcadia-devtools <arcadia-devtools@yandex-team.ru> | 2022-02-18 16:35:49 +0300 |
commit | edefa564e11987d4aa60fff0a2378785deb03b54 (patch) | |
tree | 66e32a4d0284fb784a73d76f5531b708cd72be44 /library | |
parent | 04182a7d083f485a3364f570da83470e580c78ac (diff) | |
download | ydb-edefa564e11987d4aa60fff0a2378785deb03b54.tar.gz |
intermediate changes
ref:5a427ceffcbeddcbaed23c62818445bd98632b96
Diffstat (limited to 'library')
-rw-r--r-- | library/cpp/cache/cache.h | 165 | ||||
-rw-r--r-- | library/cpp/cache/ut/cache_ut.cpp | 48 | ||||
-rw-r--r-- | library/cpp/http/misc/httpreqdata.cpp | 2 | ||||
-rw-r--r-- | library/cpp/string_utils/quote/quote.cpp | 6 |
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); |