diff options
author | ivanmautin <ivanmautin@yandex-team.com> | 2024-05-06 11:33:58 +0300 |
---|---|---|
committer | ivanmautin <ivanmautin@yandex-team.com> | 2024-05-06 11:45:11 +0300 |
commit | db9340f74578f02054d56b136a9faccfe7e29eb4 (patch) | |
tree | 22247474ed2f686c3e8432bfd85661ede5cfc810 | |
parent | 1b5ecadf895a68f8dc21bb0901b78fa1a9b6e347 (diff) | |
download | ydb-db9340f74578f02054d56b136a9faccfe7e29eb4.tar.gz |
Add TotalSize and Size methods
Раньше метод GetTotalSize() был только в TLRUList, хотя TSizeProvider присутствовал также в TLRUList
Добавил GetTotalSize() во все листы (в том числе TLWList), а также метод GetSize(), который возвращает текущее количество
Также добавил эти методы в сами TCache и TThreadSafeCache
c103617d7259841e1c273cadd8dbf0bb019e52dc
-rw-r--r-- | library/cpp/cache/cache.h | 36 | ||||
-rw-r--r-- | library/cpp/cache/thread_safe_cache.h | 10 | ||||
-rw-r--r-- | library/cpp/cache/ut/cache_ut.cpp | 75 |
3 files changed, 109 insertions, 12 deletions
diff --git a/library/cpp/cache/cache.h b/library/cpp/cache/cache.h index ee65c30d41..9fe98d5366 100644 --- a/library/cpp/cache/cache.h +++ b/library/cpp/cache/cache.h @@ -124,11 +124,11 @@ public: List.PushBack(item); } - size_t GetSize() const { + [[nodiscard]] size_t GetSize() const { return ItemsAmount; } - size_t GetTotalSize() const { + [[nodiscard]] size_t GetTotalSize() const { return TotalSize; } @@ -157,7 +157,8 @@ public: TLFUList(size_t maxSize, const TSizeProvider& sizeProvider = TSizeProvider()) : List() , SizeProvider(sizeProvider) - , ListSize(0) + , ItemsAmount(0) + , TotalSize(0) , MaxSize(maxSize) { } @@ -228,14 +229,15 @@ public: public: TItem* Insert(TItem* item) { List.PushBack(item); // give a chance for promotion - ListSize += SizeProvider(item->Value); + ++ItemsAmount; + TotalSize += SizeProvider(item->Value); return RemoveIfOverflown(); } TItem* RemoveIfOverflown() { TItem* deleted = nullptr; - if (ListSize > MaxSize) { + if (TotalSize > MaxSize && ItemsAmount > 1) { deleted = GetLeastFrequentlyUsed(); Erase(deleted); } @@ -250,7 +252,8 @@ public: void Erase(TItem* item) { item->Unlink(); - ListSize -= SizeProvider(item->Value); + --ItemsAmount; + TotalSize -= SizeProvider(item->Value); } void Promote(TItem* item) { @@ -262,8 +265,12 @@ public: item->LinkBefore(&*it); } - size_t GetSize() const { - return ListSize; + [[nodiscard]] size_t GetSize() const { + return ItemsAmount; + } + + [[nodiscard]] size_t GetTotalSize() const { + return TotalSize; } size_t GetMaxSize() const { @@ -280,7 +287,8 @@ private: typedef TIntrusiveList<TItem> TListType; TListType List; TSizeProvider SizeProvider; - size_t ListSize; + size_t ItemsAmount; + size_t TotalSize; size_t MaxSize; }; @@ -413,6 +421,10 @@ public: return Size; } + [[nodiscard]] size_t GetTotalSize() const { + return Size; + } + size_t GetMaxSize() const { return MaxSize; } @@ -515,10 +527,14 @@ public: Clear(); } - size_t Size() const { + [[nodiscard]] size_t Size() const { return Index.size(); } + [[nodiscard]] size_t TotalSize() const { + return List.GetTotalSize(); + } + TIterator Begin() const { return TIterator(Index.begin()); } diff --git a/library/cpp/cache/thread_safe_cache.h b/library/cpp/cache/thread_safe_cache.h index 71e1442717..2699c8f7b7 100644 --- a/library/cpp/cache/thread_safe_cache.h +++ b/library/cpp/cache/thread_safe_cache.h @@ -96,6 +96,16 @@ namespace NPrivate { return TThreadSafeCacheSingleton<TCallbacks>::Clear(); } + size_t Size() const { + TReadGuard r(Mutex); + return Cache.Size(); + } + + size_t TotalSize() const { + TReadGuard r(Mutex); + return Cache.TotalSize(); + } + size_t GetMaxSize() const { TReadGuard w(Mutex); return Cache.GetMaxSize(); diff --git a/library/cpp/cache/ut/cache_ut.cpp b/library/cpp/cache/ut/cache_ut.cpp index 33731988c1..36a3eff094 100644 --- a/library/cpp/cache/ut/cache_ut.cpp +++ b/library/cpp/cache/ut/cache_ut.cpp @@ -15,10 +15,14 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x1(1, "ttt"); list.Insert(&x1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 1); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); TListType::TItem x2(2, "yyy"); list.Insert(&x2); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); list.Promote(list.GetOldest()); @@ -26,6 +30,8 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x3(3, "zzz"); list.Insert(&x3); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); } @@ -39,12 +45,16 @@ Y_UNIT_TEST_SUITE(TCacheTest) { list.Insert(&x1); while (list.RemoveIfOverflown()) { } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 3); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); TListType::TItem x2(2, "yyy"); list.Insert(&x2); while (list.RemoveIfOverflown()) { } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 6); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); list.Promote(list.GetOldest()); @@ -56,13 +66,25 @@ Y_UNIT_TEST_SUITE(TCacheTest) { list.Insert(&x3); while (list.RemoveIfOverflown()) { } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 6); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 1); TListType::TItem x4(4, "longlong"); list.Insert(&x4); while (list.RemoveIfOverflown()) { } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 8); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 4); + + TListType::TItem x5(5, "xxx"); + list.Insert(&x5); + while (list.RemoveIfOverflown()) { + } + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 3); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); + UNIT_ASSERT_EQUAL(list.GetOldest()->Key, 5); } Y_UNIT_TEST(LFUListTest) { @@ -71,10 +93,14 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x1(1, "ttt"); list.Insert(&x1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 1); + UNIT_ASSERT_EQUAL(list.GetSize(), 1); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); TListType::TItem x2(2, "yyy"); list.Insert(&x2); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); list.Promote(list.GetLeastFrequentlyUsed()); @@ -82,6 +108,8 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x3(3, "zzz"); list.Insert(&x3); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); + UNIT_ASSERT_EQUAL(list.GetSize(), 2); UNIT_ASSERT_EQUAL(list.GetLeastFrequentlyUsed()->Key, 1); } @@ -92,25 +120,30 @@ Y_UNIT_TEST_SUITE(TCacheTest) { TListType::TItem x1(1, "tt"); list.Insert(&x1); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 1); UNIT_ASSERT_EQUAL(list.GetSize(), 1); TListType::TItem x2(2, "yyyy"); list.Insert(&x2); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); UNIT_ASSERT_EQUAL(list.GetSize(), 2); TListType::TItem x3(3, "z"); list.Insert(&x3); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 1); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); UNIT_ASSERT_EQUAL(list.GetSize(), 2); TListType::TItem x4(4, "xxxxxx"); list.Insert(&x4); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 2); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 2); UNIT_ASSERT_EQUAL(list.GetSize(), 2); list.Erase(&x2); UNIT_ASSERT_EQUAL(list.GetLightest()->Key, 4); + UNIT_ASSERT_EQUAL(list.GetTotalSize(), 1); UNIT_ASSERT_EQUAL(list.GetSize(), 1); } @@ -118,11 +151,17 @@ Y_UNIT_TEST_SUITE(TCacheTest) { typedef TLRUCache<int, TString> TCache; TCache s(2); // size 2 s.Insert(1, "abcd"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 1); + UNIT_ASSERT_EQUAL(s.Size(), 1); UNIT_ASSERT(s.Find(1) != s.End()); UNIT_ASSERT_EQUAL(*s.Find(1), "abcd"); s.Insert(2, "defg"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 2); + UNIT_ASSERT_EQUAL(s.Size(), 2); UNIT_ASSERT(s.GetOldest() == "abcd"); s.Insert(3, "hjkl"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 2); + UNIT_ASSERT_EQUAL(s.Size(), 2); UNIT_ASSERT(s.GetOldest() == "defg"); // key 1 will be deleted UNIT_ASSERT(s.Find(1) == s.End()); @@ -135,9 +174,13 @@ Y_UNIT_TEST_SUITE(TCacheTest) { UNIT_ASSERT(*s.Find(3) == "hjkl"); s.Update(3, "abcd"); UNIT_ASSERT(*s.Find(3) == "abcd"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 2); + UNIT_ASSERT_EQUAL(s.Size(), 2); TCache::TIterator it = s.Find(3); s.Erase(it); + UNIT_ASSERT_EQUAL(s.TotalSize(), 1); + UNIT_ASSERT_EQUAL(s.Size(), 1); UNIT_ASSERT(s.Find(3) == s.End()); } @@ -145,13 +188,21 @@ Y_UNIT_TEST_SUITE(TCacheTest) { typedef TLRUCache<int, TString, TNoopDelete, size_t(*)(const TString&)> TCache; TCache s(10, false, [](auto& string) { return string.size(); }); // size 10 s.Insert(1, "abcd"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 4); + UNIT_ASSERT_EQUAL(s.Size(), 1); UNIT_ASSERT(s.Find(1) != s.End()); UNIT_ASSERT_EQUAL(*s.Find(1), "abcd"); s.Insert(2, "defg"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 8); + UNIT_ASSERT_EQUAL(s.Size(), 2); UNIT_ASSERT(s.GetOldest() == "abcd"); s.Insert(3, "2c"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 10); + UNIT_ASSERT_EQUAL(s.Size(), 3); UNIT_ASSERT(s.GetOldest() == "abcd"); s.Insert(4, "hjkl"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 10); + UNIT_ASSERT_EQUAL(s.Size(), 3); UNIT_ASSERT(s.GetOldest() == "defg"); // key 1 will be deleted UNIT_ASSERT(s.Find(1) == s.End()); @@ -165,10 +216,14 @@ Y_UNIT_TEST_SUITE(TCacheTest) { UNIT_ASSERT(!s.Insert(3, "abcd")); UNIT_ASSERT(*s.Find(3) == "2c"); s.Update(3, "abcd"); + UNIT_ASSERT_EQUAL(s.TotalSize(), 8); + UNIT_ASSERT_EQUAL(s.Size(), 2); UNIT_ASSERT(*s.Find(3) == "abcd"); TCache::TIterator it = s.Find(3); s.Erase(it); + UNIT_ASSERT_EQUAL(s.TotalSize(), 4); + UNIT_ASSERT_EQUAL(s.Size(), 1); UNIT_ASSERT(s.Find(3) == s.End()); } @@ -317,10 +372,14 @@ Y_UNIT_TEST_SUITE(TCacheTest) { UNIT_ASSERT(s.Insert(1, "abcd")); UNIT_ASSERT(s.Insert(1, "bcde")); UNIT_ASSERT(s.Insert(2, "fghi")); - UNIT_ASSERT(s.Insert(2, "ghij")); // (1, "abcd") will be deleted - UNIT_ASSERT(*s.Find(1) == "bcde"); + UNIT_ASSERT(s.Insert(2, "ghij")); + + UNIT_ASSERT_EQUAL(s.TotalSize(), 3); + UNIT_ASSERT_EQUAL(s.Size(), 3); + // (1, "bcde") will be promoted + UNIT_ASSERT(*s.Find(1) == "bcde"); UNIT_ASSERT(*s.FindOldest() == "fghi"); } @@ -449,6 +508,8 @@ Y_UNIT_TEST_SUITE(TThreadSafeCacheTest) { cache.Update(2, MakeAtomicShared<TString>("hjk")); item = cache.Get(2); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 1); + UNIT_ASSERT_EQUAL(cache.Size(), 1); UNIT_ASSERT(callbacks.Creations == 0); UNIT_ASSERT(*item == "hjk"); } @@ -484,6 +545,8 @@ Y_UNIT_TEST_SUITE(TThreadSafeCacheUnsafeTest) { UNIT_ASSERT(*data == VALS[i]); } } + UNIT_ASSERT_EQUAL(cache.TotalSize(), Y_ARRAY_SIZE(VALS) - 1); + UNIT_ASSERT_EQUAL(cache.Size(), Y_ARRAY_SIZE(VALS) - 1); } } @@ -532,6 +595,8 @@ Y_UNIT_TEST_SUITE(TThreadSafeLRUCacheTest) { cache.Update(2, MakeAtomicShared<TString>("hjk")); item = cache.Get(2); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 1); + UNIT_ASSERT_EQUAL(cache.Size(), 1); UNIT_ASSERT(callbacks.Creations == 0); UNIT_ASSERT(*item == "hjk"); } @@ -630,17 +695,23 @@ Y_UNIT_TEST_SUITE(TThreadSafeLRUCacheTest) { UNIT_ASSERT_EQUAL(callbacks.Creations, expectedCreations); UNIT_ASSERT(*item == "one"); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 3); + UNIT_ASSERT_EQUAL(cache.Size(), 3); cache.SetMaxSize(4); item = cache.Get(0); expectedCreations++; UNIT_ASSERT_EQUAL(callbacks.Creations, expectedCreations); UNIT_ASSERT(*item == "zero"); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 4); + UNIT_ASSERT_EQUAL(cache.Size(), 4); item = cache.Get(4); expectedCreations++; UNIT_ASSERT_EQUAL(callbacks.Creations, expectedCreations); UNIT_ASSERT(*item == "four"); + UNIT_ASSERT_EQUAL(cache.TotalSize(), 4); + UNIT_ASSERT_EQUAL(cache.Size(), 4); item = cache.Get(3); expectedCreations++; |