From 160bb77d58163a522efdccd75de5b22088cb70ba Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Wed, 15 Feb 2023 19:44:16 -0800 Subject: [PATCH 01/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/wangle/commit/43e56205514ee4d77e483f4f52ff27dac3216514 https://github.com/facebookexperimental/edencommon/commit/3934bece13d925ae5dd99bd993caa0258f480fcc https://github.com/facebookincubator/katran/commit/a4c94aa4b0899c5480f803b557fb894c4e0a5ac3 Reviewed By: jurajh-fb fbshipit-source-id: 720310662068e4aa245198d817666700c9dde1d5 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/wangle | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 33a9fbc25..1dea97776 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 33a9fbc258f21818f20ea03a55c979014882e84d +Subproject commit 1dea977766b157ff2f5df9922534361b44f9698e diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 9198ca6e7..2716439e6 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 9198ca6e7daa50fae6b8413d745b4faaf97dfd10 +Subproject commit 2716439e6d0efdeec3c27d75793249bd42accdf0 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 6bc77c8d4..43e562055 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 6bc77c8d46b5ef68d77e921bb1e3d1e576adb8fe +Subproject commit 43e56205514ee4d77e483f4f52ff27dac3216514 From ba8d6b003a4f5856d88af02b09fac74d7f12ae07 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Thu, 16 Feb 2023 13:23:03 -0800 Subject: [PATCH 02/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fb303/commit/c51a2906c5be9f12223b2314501b7cc3e9f801d9 https://github.com/facebook/fbthrift/commit/5e97023405d6bddc686e836e9a6d1117947cd9dd https://github.com/facebook/proxygen/commit/3710a3267346e43095e1f140e72706538ac22f23 https://github.com/facebook/wangle/commit/fd298004026d8f72fcfc37e6b4ff1749a88ea4d1 https://github.com/facebook/watchman/commit/fca53d2d93d8fc2f256aa99b4ebecc4e9bb5ac1a https://github.com/facebookexperimental/edencommon/commit/3d8a6d905c416ff7b8ae6c70765d34231d747a9d https://github.com/facebookexperimental/rust-shed/commit/75c5d75f7ec67dacf44db3dcf444b7511f038c58 https://github.com/facebookincubator/fizz/commit/bae2d7ebe3b348679e832102b65d47aceb4ac2f8 https://github.com/facebookincubator/katran/commit/139c75dfb61626dea75951ec1097a1373b5a182e https://github.com/facebookincubator/mvfst/commit/001332d5e9c5a8ee47e9c932e640474037832abf https://github.com/facebookincubator/velox/commit/ec0ea1fd5ffcf6dec60d2e53831478cbaf2ca4a0 Reviewed By: jurajh-fb fbshipit-source-id: a8a8ff6a7fddeaa7bbccb3faa6a737c50d22cfe2 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 1dea97776..5e9702340 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 1dea977766b157ff2f5df9922534361b44f9698e +Subproject commit 5e97023405d6bddc686e836e9a6d1117947cd9dd diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 2716439e6..bae2d7ebe 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 2716439e6d0efdeec3c27d75793249bd42accdf0 +Subproject commit bae2d7ebe3b348679e832102b65d47aceb4ac2f8 diff --git a/cachelib/external/folly b/cachelib/external/folly index 128cfac6a..9aeeaf493 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 128cfac6ac3d69825bad2af852fced3f63d87411 +Subproject commit 9aeeaf4933c271559c995df862b52af5bd9645c2 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 43e562055..fd2980040 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 43e56205514ee4d77e483f4f52ff27dac3216514 +Subproject commit fd298004026d8f72fcfc37e6b4ff1749a88ea4d1 From ba9dd68a1bbae05676d332e9aa4c1a6d6b79348e Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Fri, 17 Feb 2023 10:09:28 -0800 Subject: [PATCH 03/92] Change some of the stats to rate Summary: As mentioned in the tasks, these stats make more sense in rates. Reviewed By: jiayuebao Differential Revision: D43243498 fbshipit-source-id: 556b0b4a062235bb3b34dd076e5f7a5a88316f8c --- cachelib/navy/block_cache/BlockCache.cpp | 9 ++++++--- cachelib/navy/driver/Driver.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cachelib/navy/block_cache/BlockCache.cpp b/cachelib/navy/block_cache/BlockCache.cpp index f34605b68..84dadd13e 100644 --- a/cachelib/navy/block_cache/BlockCache.cpp +++ b/cachelib/navy/block_cache/BlockCache.cpp @@ -723,9 +723,11 @@ void BlockCache::getCounters(const CounterVisitor& visitor) const { reclaimValueChecksumErrorCount_.get(), CounterVisitor::CounterType::RATE); visitor("navy_bc_cleanup_entry_header_checksum_errors", - cleanupEntryHeaderChecksumErrorCount_.get()); + cleanupEntryHeaderChecksumErrorCount_.get(), + CounterVisitor::CounterType::RATE); visitor("navy_bc_cleanup_value_checksum_errors", - cleanupValueChecksumErrorCount_.get()); + cleanupValueChecksumErrorCount_.get(), + CounterVisitor::CounterType::RATE); visitor("navy_bc_succ_lookups", succLookupCount_.get(), CounterVisitor::CounterType::RATE); visitor("navy_bc_removes", removeCount_.get(), @@ -750,7 +752,8 @@ void BlockCache::getCounters(const CounterVisitor& visitor) const { visitor("navy_bc_reinsertion_errors", reinsertionErrorCount_.get(), CounterVisitor::CounterType::RATE); visitor("navy_bc_lookup_for_item_destructor_errors", - lookupForItemDestructorErrorCount_.get()); + lookupForItemDestructorErrorCount_.get(), + CounterVisitor::CounterType::RATE); visitor("navy_bc_remove_attempt_collisions", removeAttemptCollisions_.get(), CounterVisitor::CounterType::RATE); // Allocator visits region manager diff --git a/cachelib/navy/driver/Driver.cpp b/cachelib/navy/driver/Driver.cpp index 1615d1cc4..29215cc16 100644 --- a/cachelib/navy/driver/Driver.cpp +++ b/cachelib/navy/driver/Driver.cpp @@ -273,8 +273,10 @@ void Driver::getCounters(const CounterVisitor& visitor) const { CounterVisitor::CounterType::RATE); visitor("navy_rejected_bytes", rejectedBytes_.get(), CounterVisitor::CounterType::RATE); - visitor("navy_accepted_bytes", acceptedBytes_.get()); - visitor("navy_accepted", acceptedCount_.get()); + visitor("navy_accepted_bytes", acceptedBytes_.get(), + CounterVisitor::CounterType::RATE); + visitor("navy_accepted", acceptedCount_.get(), + CounterVisitor::CounterType::RATE); visitor("navy_parcel_memory", parcelMemory_.get()); visitor("navy_concurrent_inserts", concurrentInserts_.get()); From ad8bfd693f824f904cdcab4f2319aa68a6bf7e4b Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Fri, 17 Feb 2023 11:40:50 -0800 Subject: [PATCH 04/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/cachelib/commit/ba9dd68a1bbae05676d332e9aa4c1a6d6b79348e https://github.com/facebook/fbthrift/commit/23208ff909ee751de695e6806f14820137045803 https://github.com/facebookincubator/velox/commit/68b8a45ff019bb20ed204451c29ac34352760840 Reviewed By: jurajh-fb fbshipit-source-id: f8581e13cd1c0a2510d87f42c813ca2c65eaef1d --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 5e9702340..23208ff90 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 5e97023405d6bddc686e836e9a6d1117947cd9dd +Subproject commit 23208ff909ee751de695e6806f14820137045803 From bdad762aa2bc38e97c9afc45c4edb9186750b1d3 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sat, 18 Feb 2023 11:28:38 -0800 Subject: [PATCH 05/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/3b00d58af9a028db696e2034c54cf9500fda53a7 Reviewed By: jurajh-fb fbshipit-source-id: 23ecb07e7e9ebd4dfbf3980de141ea1ebe36bb12 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 23208ff90..3b00d58af 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 23208ff909ee751de695e6806f14820137045803 +Subproject commit 3b00d58af9a028db696e2034c54cf9500fda53a7 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index bae2d7ebe..2da27e939 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit bae2d7ebe3b348679e832102b65d47aceb4ac2f8 +Subproject commit 2da27e939de1aa4eeecc6bc8d3a32844a75bd42b diff --git a/cachelib/external/folly b/cachelib/external/folly index 9aeeaf493..3c5efbdff 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 9aeeaf4933c271559c995df862b52af5bd9645c2 +Subproject commit 3c5efbdff2d01b83fc76827518c14a786f9c28ce diff --git a/cachelib/external/wangle b/cachelib/external/wangle index fd2980040..8733674dc 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit fd298004026d8f72fcfc37e6b4ff1749a88ea4d1 +Subproject commit 8733674dc8977b22324b2dfbd956aa6763a9834c From b42327aea0839c726e8579fc9b36165d2d74bd30 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sat, 18 Feb 2023 18:09:16 -0800 Subject: [PATCH 06/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/df0eb612d7cb64ab73ed2f3b42bfe787a6ed4653 https://github.com/facebook/proxygen/commit/7fc3feabba6dca34b03e012d9a981f05e4ea27a3 Reviewed By: jurajh-fb fbshipit-source-id: fa982baf35fd98edc52be391f03d15a9c2c333bf --- cachelib/external/fbthrift | 2 +- cachelib/external/wangle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 3b00d58af..df0eb612d 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 3b00d58af9a028db696e2034c54cf9500fda53a7 +Subproject commit df0eb612d7cb64ab73ed2f3b42bfe787a6ed4653 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 8733674dc..cb61ed175 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 8733674dc8977b22324b2dfbd956aa6763a9834c +Subproject commit cb61ed1759c692a4c69b85df7cb983ee920e91cf From 0d49b53fc50fbe00b48ef854454b884e11768878 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sun, 19 Feb 2023 20:30:30 -0800 Subject: [PATCH 07/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/1d01d76ff25b7d5c5d36a08f111834082277f8e7 Reviewed By: jurajh-fb fbshipit-source-id: bdefba88e8d002c65d8b7c11e86c8aa772996d9b --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index df0eb612d..1d01d76ff 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit df0eb612d7cb64ab73ed2f3b42bfe787a6ed4653 +Subproject commit 1d01d76ff25b7d5c5d36a08f111834082277f8e7 From bb2d1c657667a15f5ff96fc8a2dd5208bd93aee3 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Tue, 21 Feb 2023 10:54:23 -0800 Subject: [PATCH 08/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/1b848d85947b8d20e00521e95f78690a73543678 https://github.com/facebook/rocksdb/commit/cfe50f7e77326aac5b04050afcda05059a25667c https://github.com/pytorch/fbgemm/commit/c55d8006722eae1ec886502363d8386862a13719 Reviewed By: bigfootjon fbshipit-source-id: e840d1116311ac52336e598442cf66cdc50d7725 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 1d01d76ff..1b848d859 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 1d01d76ff25b7d5c5d36a08f111834082277f8e7 +Subproject commit 1b848d85947b8d20e00521e95f78690a73543678 From c167a8327810110cac2ab739ab2346a05cde5a88 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Tue, 21 Feb 2023 14:59:14 -0800 Subject: [PATCH 09/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/90fddab67b2a40ec0edda28fd014402258726eef Reviewed By: bigfootjon fbshipit-source-id: cf7ac48c00c548805fb74663fe3e9bd9f5906cc2 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 1b848d859..90fddab67 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 1b848d85947b8d20e00521e95f78690a73543678 +Subproject commit 90fddab67b2a40ec0edda28fd014402258726eef From 32ed439b6b319896386cdd4aa818b2ccf285ae23 Mon Sep 17 00:00:00 2001 From: Jiayue Bao Date: Tue, 21 Feb 2023 15:17:04 -0800 Subject: [PATCH 10/92] Return replacedPtr from InsertOrReplace API Summary: Currently `replacedPtr` is passed as an argument and such usage isn't easy to understand (we kept receiving user feedback on that). Now we want to return it. Reviewed By: therealgymmy, antonf, jaesoo-fb Differential Revision: D43143989 fbshipit-source-id: eaae055107050cd67a7ca8b26b716fffc0c002f2 --- .../experimental/objcache2/ObjectCache-inl.h | 28 +++++----- cachelib/experimental/objcache2/ObjectCache.h | 18 +++---- .../objcache2/persistence/Serialization.h | 4 +- .../objcache2/tests/ObjectCacheTest.cpp | 51 +++++++++++-------- 4 files changed, 54 insertions(+), 47 deletions(-) diff --git a/cachelib/experimental/objcache2/ObjectCache-inl.h b/cachelib/experimental/objcache2/ObjectCache-inl.h index 345a27d52..70cfc445b 100644 --- a/cachelib/experimental/objcache2/ObjectCache-inl.h +++ b/cachelib/experimental/objcache2/ObjectCache-inl.h @@ -153,12 +153,13 @@ std::shared_ptr ObjectCache::findToWrite( template template -std::pair::AllocStatus, std::shared_ptr> +std::tuple::AllocStatus, + std::shared_ptr, + std::shared_ptr> ObjectCache::insertOrReplace(folly::StringPiece key, std::unique_ptr object, size_t objectSize, - uint32_t ttlSecs, - std::shared_ptr* replacedPtr) { + uint32_t ttlSecs) { if (config_.objectSizeTrackingEnabled && objectSize == 0) { throw std::invalid_argument( "Object size tracking is enabled but object size is set to be 0."); @@ -176,7 +177,8 @@ ObjectCache::insertOrReplace(folly::StringPiece key, allocateFromL1(key, ttlSecs, 0 /* use current time as creationTime */); if (!handle) { insertErrors_.inc(); - return {AllocStatus::kAllocError, std::shared_ptr(std::move(object))}; + return {AllocStatus::kAllocError, std::shared_ptr(std::move(object)), + nullptr}; } // We don't release the object here because insertOrReplace could throw when // the replaced item is out of refcount; in this case, the object isn't @@ -187,16 +189,15 @@ ObjectCache::insertOrReplace(folly::StringPiece key, auto replaced = this->l1Cache_->insertOrReplace(handle); + std::shared_ptr replacedPtr = nullptr; if (replaced) { replaces_.inc(); - if (replacedPtr) { - auto itemPtr = reinterpret_cast(replaced->getMemory()); - // Just release the handle. Cache destorys object when all handles - // released. - auto deleter = [h = std::move(replaced)](T*) {}; - *replacedPtr = std::shared_ptr( - reinterpret_cast(itemPtr->objectPtr), std::move(deleter)); - } + auto itemPtr = reinterpret_cast(replaced->getMemory()); + // Just release the handle. Cache destorys object when all handles + // released. + auto deleter = [h = std::move(replaced)](T*) {}; + replacedPtr = std::shared_ptr(reinterpret_cast(itemPtr->objectPtr), + std::move(deleter)); } // Just release the handle. Cache destorys object when all handles released. @@ -209,7 +210,8 @@ ObjectCache::insertOrReplace(folly::StringPiece key, // Release the object as it has been successfully inserted to the cache. object.release(); - return {AllocStatus::kSuccess, std::shared_ptr(ptr, std::move(deleter))}; + return {AllocStatus::kSuccess, std::shared_ptr(ptr, std::move(deleter)), + replacedPtr}; } template diff --git a/cachelib/experimental/objcache2/ObjectCache.h b/cachelib/experimental/objcache2/ObjectCache.h index 85abac068..f4cd2a9bb 100644 --- a/cachelib/experimental/objcache2/ObjectCache.h +++ b/cachelib/experimental/objcache2/ObjectCache.h @@ -146,22 +146,20 @@ class ObjectCache : public ObjectCacheBase { // if objectSizeTracking is enabled, a non-zero value must // be passed. // @param ttlSecs object expiring seconds. - // @param replacedPtr a pointer to a shared_ptr, if it is not nullptr it will - // be assigned to the replaced object. // // @throw cachelib::exception::RefcountOverflow if the item we are replacing // is already out of refcounts. // @throw std::invalid_argument if objectSizeTracking is enabled but // objectSize is 0. - // @return a pair of allocation status and shared_ptr of newly inserted - // object. + // @return a tuple of allocation status, shared_ptr of newly inserted + // object and shared_ptr of old object that has been replaced (nullptr + // if no replacement happened) template - std::pair> insertOrReplace( - folly::StringPiece key, - std::unique_ptr object, - size_t objectSize = 0, - uint32_t ttlSecs = 0, - std::shared_ptr* replacedPtr = nullptr); + std::tuple, std::shared_ptr> + insertOrReplace(folly::StringPiece key, + std::unique_ptr object, + size_t objectSize = 0, + uint32_t ttlSecs = 0); // Insert the object into the cache with given key. If the key exists in the // cache, the new object won't be inserted. diff --git a/cachelib/experimental/objcache2/persistence/Serialization.h b/cachelib/experimental/objcache2/persistence/Serialization.h index cccb414b4..4edad88e4 100644 --- a/cachelib/experimental/objcache2/persistence/Serialization.h +++ b/cachelib/experimental/objcache2/persistence/Serialization.h @@ -68,9 +68,9 @@ struct ObjectDeserializer { Deserializer deserializer{reinterpret_cast(payload.begin()), reinterpret_cast(payload.end())}; auto ptr = std::make_unique(deserializer.deserialize()); - auto [allocStatus, _] = + auto res = objCache_.insertOrReplace(key, std::move(ptr), objectSize, ttlSecs); - return allocStatus == ObjectCache::AllocStatus::kSuccess; + return std::get<0>(res) == ObjectCache::AllocStatus::kSuccess; } // cache key of the object to be deserialized diff --git a/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp b/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp index 0bcc120de..6bafa4058 100644 --- a/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp +++ b/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp @@ -206,12 +206,12 @@ class ObjectCacheTest : public ::testing::Test { foo->a = 1; foo->b = 2; foo->c = 3; - auto res = objcache->insertOrReplace("Foo", std::move(foo)); - EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res.first); - ASSERT_NE(nullptr, res.second); - EXPECT_EQ(1, res.second->a); - EXPECT_EQ(2, res.second->b); - EXPECT_EQ(3, res.second->c); + auto [allocRes, ptr, _] = objcache->insertOrReplace("Foo", std::move(foo)); + EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, allocRes); + ASSERT_NE(nullptr, ptr); + EXPECT_EQ(1, ptr->a); + EXPECT_EQ(2, ptr->b); + EXPECT_EQ(3, ptr->c); auto found2 = objcache->template find("Foo"); ASSERT_NE(nullptr, found2); @@ -238,7 +238,7 @@ class ObjectCacheTest : public ::testing::Test { foo->b = 2; foo->c = 3; auto res1 = objcache->insertOrReplace("Foo", std::move(foo)); - EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res1.first); + EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, std::get<0>(res1)); auto found1 = objcache->template find("Foo"); ASSERT_NE(nullptr, found1); @@ -251,7 +251,7 @@ class ObjectCacheTest : public ::testing::Test { foo2->e = 5; foo2->f = 6; auto res2 = objcache->insertOrReplace("Foo2", std::move(foo2)); - EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res2.first); + EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, std::get<0>(res2)); auto found2 = objcache->template find("Foo2"); ASSERT_NE(nullptr, found2); @@ -272,7 +272,7 @@ class ObjectCacheTest : public ::testing::Test { foo4->b = 2; foo4->c = 3; auto res1 = objcache->insertOrReplace("Foo4", std::move(foo4)); - EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res1.first); + EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, std::get<0>(res1)); auto found1 = objcache->template find("Foo4"); ASSERT_NE(nullptr, found1); @@ -285,7 +285,7 @@ class ObjectCacheTest : public ::testing::Test { foo5->e = 5; foo5->f = 6; auto res2 = objcache->insertOrReplace("Foo5", std::move(foo5)); - EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res2.first); + EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, std::get<0>(res2)); auto found2 = objcache->template find("Foo5"); ASSERT_NE(nullptr, found2); @@ -385,11 +385,14 @@ class ObjectCacheTest : public ::testing::Test { foo1->a = 1; foo1->b = 2; foo1->c = 3; - std::shared_ptr replaced; - auto res = - objcache->insertOrReplace("Foo", std::move(foo1), 0, 0, &replaced); - EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res.first); - EXPECT_EQ(nullptr, replaced); + + auto [res1, ptr1, replaced1] = + objcache->insertOrReplace("Foo", std::move(foo1)); + EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res1); + EXPECT_EQ(1, ptr1->a); + EXPECT_EQ(2, ptr1->b); + EXPECT_EQ(3, ptr1->c); + EXPECT_EQ(nullptr, replaced1); auto found1 = objcache->template find("Foo"); ASSERT_NE(nullptr, found1); @@ -401,12 +404,16 @@ class ObjectCacheTest : public ::testing::Test { foo2->a = 10; foo2->b = 20; foo2->c = 30; - res = objcache->insertOrReplace("Foo", std::move(foo2), 0, 0, &replaced); - EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res.first); - ASSERT_NE(nullptr, replaced); - EXPECT_EQ(1, replaced->a); - EXPECT_EQ(2, replaced->b); - EXPECT_EQ(3, replaced->c); + auto [res2, ptr2, replaced2] = + objcache->insertOrReplace("Foo", std::move(foo2)); + EXPECT_EQ(ObjectCache::AllocStatus::kSuccess, res2); + EXPECT_EQ(10, ptr2->a); + EXPECT_EQ(20, ptr2->b); + EXPECT_EQ(30, ptr2->c); + ASSERT_NE(nullptr, replaced2); + EXPECT_EQ(1, replaced2->a); + EXPECT_EQ(2, replaced2->b); + EXPECT_EQ(3, replaced2->c); auto found2 = objcache->template find("Foo"); ASSERT_NE(nullptr, found2); @@ -497,7 +504,7 @@ class ObjectCacheTest : public ::testing::Test { // replace foo1 with foo2 { auto res = objcache->insertOrReplace("Foo", std::move(foo2), foo2Size); - ASSERT_EQ(ObjectCache::AllocStatus::kSuccess, res.first); + ASSERT_EQ(ObjectCache::AllocStatus::kSuccess, std::get<0>(res)); auto found = objcache->template find("Foo"); ASSERT_NE(nullptr, found); From dd0af61a5fcb621ac253f67715b5fad8994627c7 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Tue, 21 Feb 2023 15:51:28 -0800 Subject: [PATCH 11/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/folly/commit/fdb333b2bb6dd9424d19c4e12385726ff87e60d4 https://github.com/facebook/watchman/commit/0b238b069f54a4de27c35a3e2352c37bccc12d60 https://github.com/pytorch/fbgemm/commit/d142cdf42560496e5f473a0f85220ff75681acc8 Reviewed By: bigfootjon fbshipit-source-id: ac185dc9dc24ba7d2765dca010958ce6b38bd029 --- cachelib/external/folly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/folly b/cachelib/external/folly index 3c5efbdff..fdb333b2b 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 3c5efbdff2d01b83fc76827518c14a786f9c28ce +Subproject commit fdb333b2bb6dd9424d19c4e12385726ff87e60d4 From cce19ea5feeba497e8e72e7bda9e899d146a37df Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Wed, 22 Feb 2023 13:29:47 -0800 Subject: [PATCH 12/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/cbc3de581fdf36ba474b0c135b9e785e504f1c1e https://github.com/facebook/rocksdb/commit/229297d1b83c1885e7db2573b9b44736a7be23a5 https://github.com/facebook/watchman/commit/d873e11529fae6d0bbd74cfe95d41732dbfbded8 https://github.com/facebookexperimental/rust-shed/commit/2f45b886ae2eb0bf59664036f0fd36e3b20923d9 Reviewed By: bigfootjon fbshipit-source-id: a65fa2098f6b6f1704154e0509e2f5423f9679eb --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 90fddab67..cbc3de581 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 90fddab67b2a40ec0edda28fd014402258726eef +Subproject commit cbc3de581fdf36ba474b0c135b9e785e504f1c1e diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 2da27e939..287625bd6 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 2da27e939de1aa4eeecc6bc8d3a32844a75bd42b +Subproject commit 287625bd6676b812e75ad0b088a61f72b4c9e681 diff --git a/cachelib/external/folly b/cachelib/external/folly index fdb333b2b..ce2b95715 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit fdb333b2bb6dd9424d19c4e12385726ff87e60d4 +Subproject commit ce2b95715de229fcb51bd97410469a3ad4d2bfb2 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index cb61ed175..44690e789 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit cb61ed1759c692a4c69b85df7cb983ee920e91cf +Subproject commit 44690e7894842a7127245837b69627d4b964aabd From 6357906c331954f34eccc5b870a7984da79f27f4 Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Thu, 23 Feb 2023 20:29:55 -0800 Subject: [PATCH 13/92] Pin fmt version at 8.0.1 (#196) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Change build script to pin fmt version to same as folly's to minimize future breaks. Pull Request resolved: https://github.com/facebook/CacheLib/pull/196 Test Plan: Built successfully on a fresh clone of CacheLib. (Also had to change `external_git_branch=dev` for zstd to deal with the cmake/zstd issue in https://github.com/facebook/CacheLib/issues/194, but that should resolve when gets merged into release) **Context:** OSS build broke between 3-5 Jan 2023, likely due to changes in folly. While switching to v9.1.0 or 9.0.0 fixes the issue at hand, it seems sensible to match folly, which specifies fmt v8.0.1: https://github.com/facebook/folly/blob/main/build/fbcode_builder/manifests/fmt > https://github.com/facebook/CacheLib/issues/62 agordon: For the other packages, you'll notice we do use a specific git tag or branch… I notice `fmt` is an exception - not pinned to a specific git tag or revision - likely an omission that can be fixed. Related CacheLib issues: https://github.com/facebook/CacheLib/issues/186, https://github.com/facebook/CacheLib/issues/189, https://github.com/facebook/CacheLib/issues/107, https://github.com/facebook/CacheLib/issues/97, https://github.com/facebook/CacheLib/issues/62 Possibly related CacheLib commit: 67cc11ad6f5fb7b1e1948513292ef00edee34f5e Last working (Jan 3): https://github.com/facebook/CacheLib/actions/runs/3826992478 First failed (Jan 5): https://github.com/facebook/CacheLib/actions/runs/3844002307/jobs/6546742348 Error: `error: static assertion failed: Cannot format an argument. To make type T formattable provide a formatter specialization: https://fmt.dev/latest/api.html#udt` Reviewed By: therealgymmy Differential Revision: D43517927 Pulled By: jiayuebao fbshipit-source-id: 2d28791f7804d862b646263b96b10b835f843d8c --- contrib/build-package.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/build-package.sh b/contrib/build-package.sh index ff487967c..6e7acac5c 100755 --- a/contrib/build-package.sh +++ b/contrib/build-package.sh @@ -160,6 +160,7 @@ case "$1" in REPODIR=cachelib/external/$NAME SRCDIR=$REPODIR external_git_clone=yes + external_git_tag="8.0.1" cmake_custom_params="-DBUILD_SHARED_LIBS=ON" if test "$build_tests" = "yes" ; then cmake_custom_params="$cmake_custom_params -DFMT_TEST=YES" From a9257379ab72ef2733f35e814c425d12785f0ea9 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Fri, 24 Feb 2023 19:09:53 -0800 Subject: [PATCH 14/92] KVReplayGenerator: parse GET_LEASE and SET_LEASE operations Summary: Memcached's WSA logger will now emits GET_LEASE and SET_LEASE operations as well. This changes makes the cachebench treats those as GET and SET, respectively, for compatibility. Reviewed By: therealgymmy Differential Revision: D43336316 fbshipit-source-id: c9b842d567b9fb2128b822bd429f5dce30b378da --- cachelib/cachebench/workload/KVReplayGenerator.h | 6 +++--- .../workload/tests/KVReplayGeneratorTest.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cachelib/cachebench/workload/KVReplayGenerator.h b/cachelib/cachebench/workload/KVReplayGenerator.h index 4b1297008..a9124e2bd 100644 --- a/cachelib/cachebench/workload/KVReplayGenerator.h +++ b/cachelib/cachebench/workload/KVReplayGenerator.h @@ -230,10 +230,10 @@ inline bool KVReplayGenerator::parseRequest(const std::string& line, // Set op const auto& op = fields[SampleFields::OP]; - // TODO only memcache optypes are supported - if (!op.compare("GET")) { + // TODO implement GET_LEASE and SET_LEASE emulations + if (!op.compare("GET") || !op.compare("GET_LEASE")) { req->req_.setOp(OpType::kGet); - } else if (!op.compare("SET")) { + } else if (!op.compare("SET") || !op.compare("SET_LEASE")) { req->req_.setOp(OpType::kSet); } else if (!op.compare("DELETE")) { req->req_.setOp(OpType::kDel); diff --git a/cachelib/cachebench/workload/tests/KVReplayGeneratorTest.cpp b/cachelib/cachebench/workload/tests/KVReplayGeneratorTest.cpp index 72a55a402..16e4e5206 100644 --- a/cachelib/cachebench/workload/tests/KVReplayGeneratorTest.cpp +++ b/cachelib/cachebench/workload/tests/KVReplayGeneratorTest.cpp @@ -56,6 +56,18 @@ struct TraceEntry { size_t expKeySize = std::max(keySize_, reqKey.size()); expKeySize = std::min(expKeySize, 256); ASSERT_EQ(reqKey.size(), expKeySize); + ASSERT_EQ(req.req_.getOp(), getOpType()); + } + + OpType getOpType() { + if (!op_.compare("GET") || !op_.compare("GET_LEASE")) { + return OpType::kGet; + } else if (!op_.compare("SET") || !op_.compare("SET_LEASE")) { + return OpType::kSet; + } else if (!op_.compare("DELETE")) { + return OpType::kDel; + } + return OpType::kSize; } std::string key_; @@ -86,8 +98,11 @@ TEST(KVReplayGeneratorTest, BasicFormat) { // ,,,,, {7, "GET", 0, 2, std::nullopt, true}, {7, "GET", 0, 2, 50, true}, + {7, "GET_LEASE", 0, 2, 50, true}, {20, "SET", 100, 35, std::nullopt, true}, {20, "SET", 100, 35, 3600, true}, + {20, "SAT", 100, 35, 3600, false}, // invalid op name + {20, "SET_LEASE", 100, 35, 3600, true}, {7, "GET", 0, 0, std::nullopt, false}, // invalid op count {7, "GET", 0, 0, 600, false}, // invalid op count {1024, "SET", 100, 35, 300, true}, // key truncated From f7e13a4bf723a6e128e2707accc12c8c3594bfa2 Mon Sep 17 00:00:00 2001 From: Jiayue Bao Date: Mon, 27 Feb 2023 08:41:42 -0800 Subject: [PATCH 15/92] Update @braintree/sanitize-url version Summary: update to >6.0.1 version Reviewed By: antonk52 Differential Revision: D43575577 fbshipit-source-id: 7143da212ab6f124bffdfdaf3be29ff3ab986ffb --- website/package.json | 3 ++- website/yarn.lock | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/website/package.json b/website/package.json index 8c58fda9a..ac9801eee 100644 --- a/website/package.json +++ b/website/package.json @@ -43,7 +43,8 @@ "ansi-html": "0.0.8", "ua-parser-js": "^1.0.33", "eta": "^2.0.0", - "http-cache-semantics": "^4.1.1" + "http-cache-semantics": "^4.1.1", + "@braintree/sanitize-url": "^6.0.1" }, "browserslist": { "production": [ diff --git a/website/yarn.lock b/website/yarn.lock index 19f12eb0d..51e55da8c 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -1809,10 +1809,10 @@ "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" -"@braintree/sanitize-url@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.0.tgz#fe364f025ba74f6de6c837a84ef44bdb1d61e68f" - integrity sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w== +"@braintree/sanitize-url@^6.0.0", "@braintree/sanitize-url@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.2.tgz#6110f918d273fe2af8ea1c4398a88774bb9fc12f" + integrity sha512-Tbsj02wXCbqGmzdnXNk0SOF19ChhRU70BsroIi4Pm6Ehp56in6vch94mfbdQ17DozxkL3BAVjbZ4Qc1a0HFRAg== "@colors/colors@1.5.0": version "1.5.0" From 70ff91f9558fb17e67003e272d2b75df5317d6bc Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Mon, 27 Feb 2023 08:47:26 -0800 Subject: [PATCH 16/92] Add missing numa deps for fedora, rocky, arch (#197) Summary: Fix OSS builds by adding numa deps to build files. Currently some fail on missing `numa.h`. Context: https://github.com/facebook/CacheLib/issues/161 added the dependencies to the centOS, debian, and ubuntu18 build files. The PR was opened in Sep 2022 but only landed in Dec 2022, and so probably missed out on the fedora, rocky and arch build files which were added in-between those dates. Having had those build actions run on PRs would have caught this (currently, they are only scheduled.) Pull Request resolved: https://github.com/facebook/CacheLib/pull/197 Test Plan: Github Actions builds (ideally, https://github.com/facebook/CacheLib/issues/198 would be landed first.) I've checked that those packages exist for the respective repositories but didn't run them myself. Reviewed By: jaesoo-fb Differential Revision: D43587970 Pulled By: jiayuebao fbshipit-source-id: 8c59e48528042350e576a45ffc3bf2520699f5a9 --- contrib/prerequisites-arch.sh | 1 + contrib/prerequisites-fedora32.sh | 1 + contrib/prerequisites-fedora34.sh | 3 ++- contrib/prerequisites-rocky9.sh | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/contrib/prerequisites-arch.sh b/contrib/prerequisites-arch.sh index 85a8656f7..249f6c808 100755 --- a/contrib/prerequisites-arch.sh +++ b/contrib/prerequisites-arch.sh @@ -19,4 +19,5 @@ sudo pacman -S --needed --noconfirm cmake \ boost \ double-conversion \ libdwarf \ + numactl \ libsodium diff --git a/contrib/prerequisites-fedora32.sh b/contrib/prerequisites-fedora32.sh index 235d6c1a8..942cac047 100755 --- a/contrib/prerequisites-fedora32.sh +++ b/contrib/prerequisites-fedora32.sh @@ -21,6 +21,7 @@ sudo dnf -y install bison flex patch bzip2 cmake \ zlib-devel lz4-devel xz-devel bzip2-devel \ jemalloc-devel snappy-devel libsodium-devel libdwarf-devel libaio-devel \ gmock-devel gflags-devel gtest gtest-devel \ + numactl-devel \ fmt fmt-devel # DO NOT INSTALL glog-devel - need to build from source for the glog-*.cmake files diff --git a/contrib/prerequisites-fedora34.sh b/contrib/prerequisites-fedora34.sh index 7e45c8740..c7182cc51 100755 --- a/contrib/prerequisites-fedora34.sh +++ b/contrib/prerequisites-fedora34.sh @@ -19,4 +19,5 @@ sudo dnf -y install bison flex patch bzip2 cmake \ double-conversion double-conversion-devel make g++ \ boost-devel libevent-devel openssl-devel libunwind-devel \ zlib-devel lz4-devel xz-devel bzip2-devel \ - jemalloc-devel snappy-devel libsodium-devel libdwarf-devel libaio-devel + jemalloc-devel snappy-devel libsodium-devel libdwarf-devel libaio-devel \ + numactl-devel diff --git a/contrib/prerequisites-rocky9.sh b/contrib/prerequisites-rocky9.sh index bec5b8201..06720aba2 100755 --- a/contrib/prerequisites-rocky9.sh +++ b/contrib/prerequisites-rocky9.sh @@ -38,7 +38,8 @@ sudo dnf install -y \ jemalloc-devel \ libsodium-devel \ libaio-devel \ - binutils-devel + binutils-devel \ + numactl-devel sudo dnf install -y \ From 6ad7a318b43de25ba41067c3d6a851d5a60d1633 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005287564 Date: Mon, 27 Feb 2023 10:31:09 -0800 Subject: [PATCH 17/92] fbcode/cachelib/allocator/datastruct/serialize Reviewed By: avalonalex Differential Revision: D43616310 fbshipit-source-id: 3367ad01ba31e5dc561d63a4f3b9746170e64912 --- .../allocator/datastruct/serialize/objects.thrift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cachelib/allocator/datastruct/serialize/objects.thrift b/cachelib/allocator/datastruct/serialize/objects.thrift index bd2c8b79b..223b804e5 100644 --- a/cachelib/allocator/datastruct/serialize/objects.thrift +++ b/cachelib/allocator/datastruct/serialize/objects.thrift @@ -22,17 +22,17 @@ namespace cpp2 facebook.cachelib.serialization // Saved state for an SList struct SListObject { - 2: required i64 size, - 3: required i64 compressedHead, // Pointer to the head element + 2: required i64 size; + 3: required i64 compressedHead; // Pointer to the head element // TODO(bwatling): remove the default value and clean up SList::SList() once // we can rely on 'compressedTail' always being valid. - 4: i64 compressedTail = -1, // Pointer to the tail element + 4: i64 compressedTail = -1; // Pointer to the tail element } struct DListObject { - 1: required i64 compressedHead, - 2: required i64 compressedTail, - 3: required i64 size, + 1: required i64 compressedHead; + 2: required i64 compressedTail; + 3: required i64 size; } struct MultiDListObject { From df5b9f6ef35c55e432b6713c52397a03dd19c34c Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Mon, 27 Feb 2023 16:21:05 -0800 Subject: [PATCH 18/92] Run Github Actions on pull requests (#198) Summary: Run GitHub action builds on every pull request, in addition to currently daily scheduled runs. Benefit: avoid accidentally breaking other OS builds. This would have caught https://github.com/facebook/CacheLib/issues/197. This triggers whenever PRs are opened or when commits are added to a PR. Frequency of PRs (total of 76 PRs over last 18 months since CacheLib was open-sourced) is much less than frequency of daily scheduled builds, so this shouldn't add too many builds overall. Pull Request resolved: https://github.com/facebook/CacheLib/pull/198 Reviewed By: therealgymmy Differential Revision: D43625609 Pulled By: jiayuebao fbshipit-source-id: 1572f6da32584ce6a1983d5e64afedf17ff17457 --- .github/workflows/build-cachelib-centos-8-1.yml | 1 + .github/workflows/build-cachelib-centos-8-5.yml | 1 + .github/workflows/build-cachelib-debian-10.yml | 1 + .github/workflows/build-cachelib-fedora-36.yml | 1 + .github/workflows/build-cachelib-rockylinux-8.yml | 1 + .github/workflows/build-cachelib-rockylinux-9.yml | 1 + .github/workflows/build-cachelib-ubuntu-18.yml | 1 + .github/workflows/build-cachelib-ubuntu-20.yml | 1 + .github/workflows/build-cachelib-ubuntu-22.yml | 1 + 9 files changed, 9 insertions(+) diff --git a/.github/workflows/build-cachelib-centos-8-1.yml b/.github/workflows/build-cachelib-centos-8-1.yml index 5eb1090b0..3983e0c78 100644 --- a/.github/workflows/build-cachelib-centos-8-1.yml +++ b/.github/workflows/build-cachelib-centos-8-1.yml @@ -14,6 +14,7 @@ name: build-cachelib-centos-8-1 on: # push: + pull_request: schedule: - cron: '0 11 * * 1,3,5' jobs: diff --git a/.github/workflows/build-cachelib-centos-8-5.yml b/.github/workflows/build-cachelib-centos-8-5.yml index 3ffee3776..4e6c2d12e 100644 --- a/.github/workflows/build-cachelib-centos-8-5.yml +++ b/.github/workflows/build-cachelib-centos-8-5.yml @@ -14,6 +14,7 @@ name: build-cachelib-centos-8.5 on: # push: + pull_request: schedule: - cron: '0 9 * * *' jobs: diff --git a/.github/workflows/build-cachelib-debian-10.yml b/.github/workflows/build-cachelib-debian-10.yml index c7c67e072..56fb57629 100644 --- a/.github/workflows/build-cachelib-debian-10.yml +++ b/.github/workflows/build-cachelib-debian-10.yml @@ -14,6 +14,7 @@ name: build-cachelib-debian-10 on: # push: + pull_request: schedule: - cron: '0 13 * * *' jobs: diff --git a/.github/workflows/build-cachelib-fedora-36.yml b/.github/workflows/build-cachelib-fedora-36.yml index 216dbf584..f8c042440 100644 --- a/.github/workflows/build-cachelib-fedora-36.yml +++ b/.github/workflows/build-cachelib-fedora-36.yml @@ -14,6 +14,7 @@ name: build-cachelib-fedora-36 on: # push: + pull_request: schedule: - cron: '0 19 * * *' jobs: diff --git a/.github/workflows/build-cachelib-rockylinux-8.yml b/.github/workflows/build-cachelib-rockylinux-8.yml index 879dc2756..c8af12327 100644 --- a/.github/workflows/build-cachelib-rockylinux-8.yml +++ b/.github/workflows/build-cachelib-rockylinux-8.yml @@ -14,6 +14,7 @@ name: build-cachelib-rockylinux-8.6 on: # push: + pull_request: schedule: - cron: '0 15 * * 2,4,6' jobs: diff --git a/.github/workflows/build-cachelib-rockylinux-9.yml b/.github/workflows/build-cachelib-rockylinux-9.yml index f6a86d75a..e26eac6ff 100644 --- a/.github/workflows/build-cachelib-rockylinux-9.yml +++ b/.github/workflows/build-cachelib-rockylinux-9.yml @@ -14,6 +14,7 @@ name: build-cachelib-rockylinux-9.0 on: # push: + pull_request: schedule: - cron: '0 17 * * *' jobs: diff --git a/.github/workflows/build-cachelib-ubuntu-18.yml b/.github/workflows/build-cachelib-ubuntu-18.yml index fad34c089..ad068278a 100644 --- a/.github/workflows/build-cachelib-ubuntu-18.yml +++ b/.github/workflows/build-cachelib-ubuntu-18.yml @@ -19,6 +19,7 @@ name: build-cachelib-ubuntu-18 on: # push: + pull_request: schedule: - cron: '0 5 * * 2,4,6' jobs: diff --git a/.github/workflows/build-cachelib-ubuntu-20.yml b/.github/workflows/build-cachelib-ubuntu-20.yml index 35a3f507e..a8380fdb9 100644 --- a/.github/workflows/build-cachelib-ubuntu-20.yml +++ b/.github/workflows/build-cachelib-ubuntu-20.yml @@ -15,6 +15,7 @@ name: build-cachelib-ubuntu-20 on: # push: + pull_request: schedule: - cron: '0 5 * * 1,3,5' jobs: diff --git a/.github/workflows/build-cachelib-ubuntu-22.yml b/.github/workflows/build-cachelib-ubuntu-22.yml index b4374a5b9..4db194431 100644 --- a/.github/workflows/build-cachelib-ubuntu-22.yml +++ b/.github/workflows/build-cachelib-ubuntu-22.yml @@ -15,6 +15,7 @@ name: build-cachelib-ubuntu-22 on: # push: + pull_request: schedule: - cron: '0 7 * * *' jobs: From e8151adb8bb1fa4f628232c35cab06cad2ffd052 Mon Sep 17 00:00:00 2001 From: Jiayue Bao Date: Tue, 28 Feb 2023 10:25:27 -0800 Subject: [PATCH 19/92] Add a custom deleter class to access the Item Handle Summary: Add a custom deleter class that stores a `handle`. This allows object-cache to access the Item Handle via a shared_ptr. Both size-awareness feature and getting/updating object's TTL require that. Deleter class is marked as private because we don't want to expose `Handle` to object-cache users. Reviewed By: therealgymmy, jaesoo-fb Differential Revision: D42503594 fbshipit-source-id: 16ac14e6a84a1cfa80a3c145d440790002734a34 --- .../experimental/objcache2/ObjectCache-inl.h | 18 ++++----- cachelib/experimental/objcache2/ObjectCache.h | 37 +++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/cachelib/experimental/objcache2/ObjectCache-inl.h b/cachelib/experimental/objcache2/ObjectCache-inl.h index 70cfc445b..9f1b91631 100644 --- a/cachelib/experimental/objcache2/ObjectCache-inl.h +++ b/cachelib/experimental/objcache2/ObjectCache-inl.h @@ -128,8 +128,8 @@ std::shared_ptr ObjectCache::find(folly::StringPiece key) { succL1Lookups_.inc(); auto ptr = found->template getMemoryAs()->objectPtr; - // Just release the handle. Cache destorys object when all handles released. - auto deleter = [h = std::move(found)](const T*) {}; + // Use custom deleter + auto deleter = Deleter(std::move(found)); return std::shared_ptr(reinterpret_cast(ptr), std::move(deleter)); } @@ -146,8 +146,8 @@ std::shared_ptr ObjectCache::findToWrite( succL1Lookups_.inc(); auto ptr = found->template getMemoryAs()->objectPtr; - // Just release the handle. Cache destorys object when all handles released. - auto deleter = [h = std::move(found)](T*) {}; + // Use custom deleter + auto deleter = Deleter(std::move(found)); return std::shared_ptr(reinterpret_cast(ptr), std::move(deleter)); } @@ -200,9 +200,6 @@ ObjectCache::insertOrReplace(folly::StringPiece key, std::move(deleter)); } - // Just release the handle. Cache destorys object when all handles released. - auto deleter = [h = std::move(handle)](T*) {}; - // update total object size if (config_.objectSizeTrackingEnabled) { totalObjectSizeBytes_.fetch_add(objectSize, std::memory_order_relaxed); @@ -210,6 +207,9 @@ ObjectCache::insertOrReplace(folly::StringPiece key, // Release the object as it has been successfully inserted to the cache. object.release(); + + // Use custom deleter + auto deleter = Deleter(std::move(handle)); return {AllocStatus::kSuccess, std::shared_ptr(ptr, std::move(deleter)), replacedPtr}; } @@ -256,8 +256,8 @@ ObjectCache::insert(folly::StringPiece key, object.release(); } - // Just release the handle. Cache destorys object when all handles released. - auto deleter = [h = std::move(handle)](T*) {}; + // Use custom deleter + auto deleter = Deleter(std::move(handle)); return {success ? AllocStatus::kSuccess : AllocStatus::kKeyAlreadyExists, std::shared_ptr(ptr, std::move(deleter))}; } diff --git a/cachelib/experimental/objcache2/ObjectCache.h b/cachelib/experimental/objcache2/ObjectCache.h index f4cd2a9bb..5f8aab85a 100644 --- a/cachelib/experimental/objcache2/ObjectCache.h +++ b/cachelib/experimental/objcache2/ObjectCache.h @@ -94,6 +94,43 @@ class ObjectCache : public ObjectCacheBase { // make constructor private, but constructable by std::make_unique struct InternalConstructor {}; + template + class Deleter { + public: + using ReadHandle = typename AllocatorT::ReadHandle; + using WriteHandle = typename AllocatorT::WriteHandle; + using Handle = std::variant; + + explicit Deleter(typename AllocatorT::ReadHandle&& hdl) + : hdl_(std::move(hdl)) {} + explicit Deleter(typename AllocatorT::WriteHandle&& hdl) + : hdl_(std::move(hdl)) {} + + void operator()(T*) { + // Just release the handle. + // Cache destorys object when all handles released. + std::holds_alternative(hdl_) + ? std::get(hdl_).reset() + : std::get(hdl_).reset(); + } + + WriteHandle& getWriteHandleRef() { + if (std::holds_alternative(hdl_)) { + hdl_ = std::move(std::get(hdl_)).toWriteHandle(); + } + return std::get(hdl_); + } + + ReadHandle& getReadHandleRef() { + return std::holds_alternative(hdl_) + ? std::get(hdl_) + : std::get(hdl_); + } + + private: + Handle hdl_; + }; + public: using ItemDestructor = std::function; using Key = KAllocation::Key; From 982781860c0ccc6c61cde83f33e72341d87e72d7 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Tue, 28 Feb 2023 15:59:14 -0800 Subject: [PATCH 20/92] fix flaky tests in NvmCacheTests Summary: This change fixes following flaky tests in NvmCacheTests. * NvmCacheTest.Delete * NvmCacheTest.NvmEvicted * NvmCacheTest.EvictToNvmGetCheckCtime The root cause of the failures are essentially the same as D42443647 (https://github.com/facebook/CacheLib/commit/5e7ff9ab28cc00c74b19b176885d6af2e3d27d60) which fixed the problem for NvmCacheTest.EvictToNvmGet; we are inserting enough items that could be spilled to NVM cache, where the NvmCache::put() can be dropped and the item is evicted completely when the delete operations (and tombstones) issued as part of the insertion are still outstanding. In order to fix the problem, this change flushes the NVM cache periodically during the insertions. Also, since this could cause more regions are used, the size of NVM cache needs to be increased. This change bumps the default size of NVM cache to 200MB (previous 100MB). Also, the size of persist storage used in the test PersistenceCache has been bumped by 100MB accordingly, i.e., from 400MB to 500MB. This change addresses the github issue https://github.com/facebook/CacheLib/issues/169 Reviewed By: therealgymmy Differential Revision: D43592888 fbshipit-source-id: f0968884eb39fb5728b59129e98345df3240f01e --- .../allocator/nvmcache/tests/NvmCacheTests.cpp | 16 ++++++++++++++++ cachelib/allocator/tests/NvmTestUtils.h | 2 +- cachelib/persistence/tests/PersistenceCache.h | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/cachelib/allocator/nvmcache/tests/NvmCacheTests.cpp b/cachelib/allocator/nvmcache/tests/NvmCacheTests.cpp index 7355627fe..ec74c5198 100644 --- a/cachelib/allocator/nvmcache/tests/NvmCacheTests.cpp +++ b/cachelib/allocator/nvmcache/tests/NvmCacheTests.cpp @@ -245,7 +245,13 @@ TEST_F(NvmCacheTest, EvictToNvmGetCheckCtime) { ASSERT_NE(nullptr, it); cache_->insertOrReplace(it); keyToCtime.insert({key, it->getCreationTime()}); + // Avoid any nvm eviction being dropped due to the race with still + // outstanding remove operation for insertion + if (i % 100 == 0) { + nvm.flushNvmCache(); + } } + nvm.flushNvmCache(); const auto nEvictions = this->evictionCount() - evictBefore; ASSERT_LT(0, nEvictions); @@ -331,6 +337,11 @@ TEST_F(NvmCacheTest, Delete) { auto it = nvm.allocate(pid, key, 15 * 1024); ASSERT_NE(nullptr, it); nvm.insertOrReplace(it); + // Avoid any nvm eviction being dropped due to the race with still + // outstanding remove operation for insertion + if (i % 100 == 0) { + nvm.flushNvmCache(); + } } nvm.flushNvmCache(); @@ -533,6 +544,11 @@ TEST_F(NvmCacheTest, NvmEvicted) { auto it = nvm.allocate(pid, key, allocSize); ASSERT_NE(nullptr, it); nvm.insertOrReplace(it); + // Avoid any nvm eviction being dropped due to the race with still + // outstanding remove operation for insertion + if (i % 100 == 0) { + nvm.flushNvmCache(); + } } nvm.flushNvmCache(); diff --git a/cachelib/allocator/tests/NvmTestUtils.h b/cachelib/allocator/tests/NvmTestUtils.h index 6d6242aad..cad96c41d 100644 --- a/cachelib/allocator/tests/NvmTestUtils.h +++ b/cachelib/allocator/tests/NvmTestUtils.h @@ -27,7 +27,7 @@ namespace utils { using NavyConfig = navy::NavyConfig; inline NavyConfig getNvmTestConfig(const std::string& cacheDir) { NavyConfig config{}; - config.setSimpleFile(cacheDir + "/navy", 100 * 1024ULL * 1024ULL); + config.setSimpleFile(cacheDir + "/navy", 200 * 1024ULL * 1024ULL); config.setDeviceMetadataSize(4 * 1024 * 1024); config.setBlockSize(1024); config.setNavyReqOrderingShards(10); diff --git a/cachelib/persistence/tests/PersistenceCache.h b/cachelib/persistence/tests/PersistenceCache.h index 5400b4d4e..1db5b5fc8 100644 --- a/cachelib/persistence/tests/PersistenceCache.h +++ b/cachelib/persistence/tests/PersistenceCache.h @@ -213,7 +213,7 @@ class PersistenceCache { public: const uint32_t kNumKeys = 1024 * 1024; // 1 million const size_t kCacheSize = 100 * kNumKeys; // 100MB - const size_t kCapacity = 4 * kCacheSize; // 400MB + const size_t kCapacity = 5 * kCacheSize; // 500MB std::unique_ptr buffer_; std::string cacheDir_; From 9447a8acfb84c70c93333063bbee22d5e748a3e1 Mon Sep 17 00:00:00 2001 From: Darryl Gardner Date: Tue, 28 Feb 2023 17:07:02 -0800 Subject: [PATCH 21/92] Added PM9A3 support for Cachebench Write Bytes Calculations Summary: The Samsung PM9A3 does not report samsung in the model number so I added the specific model number to the vendorMap. Reviewed By: jaesoo-fb Differential Revision: D43676582 fbshipit-source-id: 6df19c40dd9da9563b75aa5847a1d1f9eb6a9aef --- cachelib/cachebench/util/NandWrites.cpp | 1 + .../cachebench/util/tests/NandWritesTest.cpp | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+) diff --git a/cachelib/cachebench/util/NandWrites.cpp b/cachelib/cachebench/util/NandWrites.cpp index ae82aca65..370ddfa2b 100644 --- a/cachelib/cachebench/util/NandWrites.cpp +++ b/cachelib/cachebench/util/NandWrites.cpp @@ -400,6 +400,7 @@ uint64_t nandWriteBytes(const folly::StringPiece& deviceName, const folly::StringPiece&)>> vendorMap{{"samsung", samsungWriteBytes}, {"mz1lb960hbjr-", samsungWriteBytes}, + {"mzol23t8hcls-", samsungWriteBytes}, // The Samsung PM983a doesn't include Samsung in the model // number at this time, but it's a Samsung device. {"liteon", liteonWriteBytes}, diff --git a/cachelib/cachebench/util/tests/NandWritesTest.cpp b/cachelib/cachebench/util/tests/NandWritesTest.cpp index 0002e8a83..af09593f4 100644 --- a/cachelib/cachebench/util/tests/NandWritesTest.cpp +++ b/cachelib/cachebench/util/tests/NandWritesTest.cpp @@ -240,6 +240,96 @@ TEST_F(NandWritesTest, nandWriteBytes_handlesSamsungPM983aDevice) { EXPECT_EQ(nandWriteBytes("nvme1n1", kNvmePath, mockFactory_), 35061362294784); } +TEST_F(NandWritesTest, nandWriteBytes_handlesSamsungPM9A3Device) { + constexpr auto& kListOutput = R"EOF({ + "Devices" : [ + { + "DevicePath" : "/dev/nvme0n1", + "Firmware" : "P1FB007", + "Index" : 0, + "NameSpace" : 1, + "ModelNumber" : "MTFDHBA512TCK", + "ProductName" : "Non-Volatile memory controller: Micron Technology Inc Device 0x5410", + "SerialNumber" : " 21062E6B8061", + "UsedBytes" : 512110190592, + "MaximumLBA" : 1000215216, + "PhysicalSize" : 512110190592, + "SectorSize" : 512 + }, + { + "DevicePath" : "/dev/nvme1n1", + "Firmware" : "GDA82F2Q", + "Index" : 1, + "NameSpace" : 1, + "ModelNumber" : "MZOL23T8HCLS-00AFB", + "ProductName" : "Unknown device", + "SerialNumber" : "S5X9NG0T116005", + "UsedBytes" : 104910848, + "MaximumLBA" : 918149526, + "PhysicalSize" : 3760740458496, + "SectorSize" : 4096 + }, + { + "DevicePath" : "/dev/nvme2n1", + "Firmware" : "GDA82F2Q", + "Index" : 2, + "NameSpace" : 1, + "ModelNumber" : "MZOL23T8HCLS-00AFB", + "ProductName" : "Unknown device", + "SerialNumber" : "S5X9NG0T116027", + "UsedBytes" : 0, + "MaximumLBA" : 918149526, + "PhysicalSize" : 3760740458496, + "SectorSize" : 4096 + } + ] +})EOF"; + + constexpr auto& kSmartLogOutput = R"EOF( +[015:000] PhysicallyWrittenBytes : 241393664 +[031:016] Physically Read Bytes : 106217472 +[037:032] Bad NAND Block Count (Raw Value) : 0 +[039:038] Bad NAND Block Count (Normalized Value) : 100 +[047:040] Uncorrectable Read Error Count : 0 +[055:048] Soft ECC Error Count : 0 +[059:056] SSD End to end Correction Count (Detected Errors) : 0 +[063:060] SSD End to end Correction Count (Corrected Errors): 0 +[064:064] System Data Percentage Used : 0 +[068:065] User Data Erase Count (Min) : 0 +[072:069] User Data Erase Count (Max) : 1 +[080:073] Refresh Count : 0 +[086:081] Program Fail Count (Raw Value) : 0 +[088:087] Program Fail Count (Normalized Value) : 100 +[094:089] User Data Erase Fail Count (Raw Value) : 0 +[096:095] User Data Erase Fail Count (Normalized Value) : 100 +[102:097] System Area Erase Fail Count (Raw Value) : 0 +[104:103] System Area Erase Fail Count (Normalized value) : 100 +[105:105] Thermal Throttling Status : 0 +[106:106] Thermal Throttling Count : 0 +[108:107] PHY Error Count : 0 +[110:109] Bad DLLP Count : 0 +[112:111] Bad TLP Count : 0 +[114:113] Reserved : 0 +[118:115] Incomplete Shutdowns : 0 +[119:119] % Free Blocks : 96 +[121:120] PCIe Correctable Error Count (RTS) : 0 +[123:122] PCIe Correctable Error Count (RRS) : 0 +[131:124] XOR Recovery Count : 0 +[137:132] Bad System NAND block count (Raw Value) : 0 +[139:138] Bad System NAND block count (Normalized Value) : 100 +[141:140] Capacitor Health : 163 +[157:142] Endurance Estimate : 28862181 +[165:158] Security Version Number : 4294967296 +[167:166] Log Page Version : 1 +)EOF"; + + mockFactory_->expectedCommands( + {{{kNvmePath, "list", "-o", "json"}, kListOutput}, + {{kNvmePath, "samsung", "vs-smart-add-log", "/dev/nvme1n1"}, + kSmartLogOutput}}); + EXPECT_EQ(nandWriteBytes("nvme1n1", kNvmePath, mockFactory_), 241393664); +} + TEST_F(NandWritesTest, nandWriteBytes_handlesSeagateDevice) { constexpr auto& kListOutput = R"EOF({ "Devices" : [ From 293118bfed1d63726ab24e3bee39962da268ac44 Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Wed, 1 Mar 2023 09:47:43 -0800 Subject: [PATCH 22/92] Fix XDCHECK regression in lambda for gcc-8.x (#201) Summary: XDCHECK (or XCHECK) fails here for gcc-8.x in a lambda, so we move it outside. This occurs in CacheBench's AsyncCacheStressor.h. ``` /__w/CacheLib/CacheLib/cachelib/../cachelib/cachebench/runner/AsyncCacheStressor.h:306:7: internal compiler error: in cp_build_addr_expr_1, at cp/typeck.c:5965 ``` This line compiled fine with 8.5 before Jan 2023 so I suspect a regression in folly or other external library. It still compiles fine with gcc-7.5, 9.4, and 11.3.1. Possibly related commits: https://github.com/facebook/folly/commit/1aafad45f316896a7504396f421dacd6c10d7d5f and https://github.com/facebook/folly/commit/e6d09f66b9fc473bc108361d4c8dce8f29f7bcaf Line of gcc-8.5 that it fails on: https://github.com/gcc-mirror/gcc/blob/releases/gcc-8.5.0/gcc/cp/typeck.c#L5965 The version that isn't in a lambda compiles just fine: https://github.com/facebook/CacheLib/blob/df5b9f6ef35c55e432b6713c52397a03dd19c34c/cachelib/cachebench/runner/CacheStressor.h#L399 Pull Request resolved: https://github.com/facebook/CacheLib/pull/201 Test Plan: GitHub actions. Built fine on my fork with CentOS 8.5/gcc-8.5. This issue currently causes 3 builds that use gcc-8.5 to fail (2 CentOS and RockyLinux-8.6) and 1 build using gcc-8.3 (Debian). Reviewed By: therealgymmy Differential Revision: D43681854 Pulled By: jaesoo-fb fbshipit-source-id: f3a65aefedcd98a26a80bb6ad009ad0d64e2395b --- cachelib/cachebench/runner/AsyncCacheStressor.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cachelib/cachebench/runner/AsyncCacheStressor.h b/cachelib/cachebench/runner/AsyncCacheStressor.h index 5b50db43b..830b50379 100644 --- a/cachelib/cachebench/runner/AsyncCacheStressor.h +++ b/cachelib/cachebench/runner/AsyncCacheStressor.h @@ -287,6 +287,10 @@ class AsyncCacheStressor : public Stressor { ++stats.get; auto lock = chainedItemAcquireUniqueLock(*key); + // This was moved outside the lambda, as otherwise gcc-8.x crashes with an + // internal compiler error here (suspected regression in folly). + XDCHECK(req->sizeBegin + 1 != req->sizeEnd); + auto onReadyFn = [&, req, key, l = std::move(lock), pid](auto hdl) { WriteHandle wHdl; if (hdl == nullptr) { @@ -303,7 +307,6 @@ class AsyncCacheStressor : public Stressor { } else { wHdl = std::move(hdl).toWriteHandle(); } - XDCHECK(req->sizeBegin + 1 != req->sizeEnd); bool chainSuccessful = false; for (auto j = req->sizeBegin + 1; j != req->sizeEnd; j++) { ++stats.addChained; From f853a42a804c7259d55272d70b010078c50ffe52 Mon Sep 17 00:00:00 2001 From: Jiayue Bao Date: Wed, 1 Mar 2023 15:39:43 -0800 Subject: [PATCH 23/92] Get or update object TTL via object shared_ptr Summary: Add the following TTL-related APIs: - getConfiguredTtlSec - getExpiryTimeSec - extendTtlSec - updateExpiryTimeSec Usage: ``` auto ptr = objcache->find("key"); auto configuredTtl = objcache->getConfiguredTtl(ptr); auto expiryTime = objcache->getExpiryTimeSec(ptr); objcache->extendTtl(ptr, std::chrono::seconds(3)); objcache->updateExpiryTimeSec(ptr, newExpiryTimeSecs); ``` Reviewed By: therealgymmy, jaesoo-fb Differential Revision: D43167879 fbshipit-source-id: 3b11fb0a2b9a3b5c38fcfd856ade100e6ae27470 --- cachelib/experimental/objcache2/ObjectCache.h | 79 +++++++++++++++ .../objcache2/tests/ObjectCacheTest.cpp | 95 +++++++++++++++++++ 2 files changed, 174 insertions(+) diff --git a/cachelib/experimental/objcache2/ObjectCache.h b/cachelib/experimental/objcache2/ObjectCache.h index 5f8aab85a..125321328 100644 --- a/cachelib/experimental/objcache2/ObjectCache.h +++ b/cachelib/experimental/objcache2/ObjectCache.h @@ -267,6 +267,63 @@ class ObjectCache : public ObjectCacheBase { : sizeController_->getCurrentEntriesLimit(); } + // Get the expiry timestamp of the object + // @param object object shared pointer returned from ObjectCache APIs + // + // @return the expiry timestamp in seconds of the object + // 0 if object is nullptr + template + uint32_t getExpiryTimeSec(const std::shared_ptr& object) const { + if (object == nullptr) { + return 0; + } + return getReadHandleRefInternal(object)->getExpiryTime(); + } + + // Get the configured TTL of the object + // @param object object shared pointer returned from ObjectCache APIs + // + // @return the configured TTL in seconds of the object + // 0 if object is nullptr + template + std::chrono::seconds getConfiguredTtl( + const std::shared_ptr& object) const { + if (object == nullptr) { + return std::chrono::seconds{0}; + } + return getReadHandleRefInternal(object)->getConfiguredTTL(); + } + + // Update the expiry timestamp of an object + // + // @param object object shared pointer returned from ObjectCache APIs + // @param expiryTimeSecs the expiryTime in seconds to update + // + // @return boolean indicating whether expiry time was successfully updated + template + bool updateExpiryTimeSec(std::shared_ptr& object, + uint32_t expiryTimeSecs) { + if (object == nullptr) { + return false; + } + return getWriteHandleRefInternal(object)->updateExpiryTime( + expiryTimeSecs); + } + + // Update expiry time to @ttl seconds from now. + // + // @param object object shared pointer returned from ObjectCache APIs + // @param ttl TTL in seconds (from now) + // + // @return boolean indicating whether TTL was successfully extended + template + bool extendTtl(std::shared_ptr& object, std::chrono::seconds ttl) { + if (object == nullptr) { + return false; + } + return getWriteHandleRefInternal(object)->extendTTL(ttl); + } + protected: // Serialize cache allocator config for exporting to Scuba std::map serializeConfigParams() const override; @@ -307,6 +364,28 @@ class ObjectCache : public ObjectCacheBase { bool stopSizeController(std::chrono::seconds timeout = std::chrono::seconds{ 0}); + // Get a ReadHandle reference from the object shared_ptr + template + typename AllocatorT::ReadHandle& getReadHandleRefInternal( + const std::shared_ptr& object) const { + auto* deleter = std::get_deleter>(object); + XDCHECK(deleter != nullptr); + auto& hdl = deleter->getReadHandleRef(); + XDCHECK(hdl != nullptr); + return hdl; + } + + // Get a WriteHandle reference from the object shared_ptr + template + typename AllocatorT::WriteHandle& getWriteHandleRefInternal( + std::shared_ptr& object) { + auto* deleter = std::get_deleter>(object); + XDCHECK(deleter != nullptr); + auto& hdl = deleter->getWriteHandleRef(); + XDCHECK(hdl != nullptr); + return hdl; + } + // Config passed to the cache. Config config_{}; diff --git a/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp b/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp index 6bafa4058..701654cd1 100644 --- a/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp +++ b/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp @@ -886,6 +886,69 @@ class ObjectCacheTest : public ::testing::Test { } } + void testGetTtl() { + const uint32_t ttlSecs = 600; + + ObjectCacheConfig config; + config.setCacheName("test").setCacheCapacity(10'000).setItemDestructor( + [&](ObjectCacheDestructorData data) { data.deleteObject(); }); + auto objcache = ObjectCache::create(config); + + auto before = util::getCurrentTimeSec(); + std::this_thread::sleep_for(std::chrono::seconds{3}); + objcache->insertOrReplace("Foo", std::make_unique(), 0 /*object size*/, + ttlSecs); + + // lookup via find API + auto found1 = objcache->template find("Foo"); + ASSERT_NE(nullptr, found1); + + // get TTL info + EXPECT_EQ(ttlSecs, objcache->getConfiguredTtl(found1).count()); + EXPECT_LE(before + ttlSecs, objcache->getExpiryTimeSec(found1)); + + // lookup via findToWrite API + auto found2 = objcache->template findToWrite("Foo"); + ASSERT_NE(nullptr, found2); + + // get TTL info + EXPECT_EQ(ttlSecs, objcache->getConfiguredTtl(found2).count()); + EXPECT_LE(before + ttlSecs, objcache->getExpiryTimeSec(found2)); + } + + void testUpdateTtl() { + const uint32_t ttlSecs = 600; + + ObjectCacheConfig config; + config.setCacheName("test").setCacheCapacity(10'000).setItemDestructor( + [&](ObjectCacheDestructorData data) { data.deleteObject(); }); + auto objcache = ObjectCache::create(config); + + auto insertionTime = util::getCurrentTimeSec(); + objcache->insertOrReplace("Foo", std::make_unique(), 0 /*object size*/, + ttlSecs); + + auto found = objcache->template find("Foo"); + ASSERT_NE(nullptr, found); + + // get TTL info + EXPECT_EQ(ttlSecs, objcache->getConfiguredTtl(found).count()); + EXPECT_LE(insertionTime + ttlSecs, objcache->getExpiryTimeSec(found)); + + // update expiry time + auto currExpTime = objcache->getExpiryTimeSec(found); + EXPECT_TRUE(objcache->updateExpiryTimeSec(found, currExpTime + ttlSecs)); + EXPECT_EQ(2 * ttlSecs, objcache->getConfiguredTtl(found).count()); + EXPECT_EQ(currExpTime + ttlSecs, objcache->getExpiryTimeSec(found)); + + // extend TTL + auto now = util::getCurrentTimeSec(); + std::this_thread::sleep_for(std::chrono::seconds{3}); + EXPECT_TRUE(objcache->extendTtl(found, std::chrono::seconds(3 * ttlSecs))); + EXPECT_LE(now + ttlSecs, objcache->getExpiryTimeSec(found)); + EXPECT_LE(3 * ttlSecs, objcache->getConfiguredTtl(found).count()); + } + void testMultithreadReplace() { // Sanity test to see if insertOrReplace across multiple // threads are safe. @@ -1079,6 +1142,32 @@ class ObjectCacheTest : public ::testing::Test { fs[i].join(); } } + + void testMultithreadUpdateTtl() { + // Sanity test to see if update TTL across multiple + // threads is safe. + ObjectCacheConfig config; + config.setCacheName("test").setCacheCapacity(10'000).setItemDestructor( + [&](ObjectCacheDestructorData data) { data.deleteObject(); }); + auto objcache = ObjectCache::create(config); + objcache->insertOrReplace("key", std::make_unique(), 0, 60); + + auto runUpdateTtlOps = [&] { + for (int i = 0; i < 2000; i++) { + auto found = objcache->template find("key"); + auto configuredTtlSecs = objcache->getConfiguredTtl(found).count(); + objcache->extendTtl(found, std::chrono::seconds{configuredTtlSecs}); + } + }; + + std::vector ts; + for (int i = 0; i < 10; i++) { + ts.push_back(std::thread{runUpdateTtlOps}); + } + for (int i = 0; i < 10; i++) { + ts[i].join(); + } + } }; using AllocatorTypes = ::testing::TypestestPersistenceHighLoad(); } +TYPED_TEST(ObjectCacheTest, GetTtl) { this->testGetTtl(); } +TYPED_TEST(ObjectCacheTest, UpdateTtl) { this->testUpdateTtl(); } + TYPED_TEST(ObjectCacheTest, MultithreadReplace) { this->testMultithreadReplace(); } @@ -1135,6 +1227,9 @@ TYPED_TEST(ObjectCacheTest, MultithreadFindAndEviction) { TYPED_TEST(ObjectCacheTest, MultithreadFindAndReplaceWith10Shards) { this->testMultithreadFindAndReplaceWith10Shards(); } +TYPED_TEST(ObjectCacheTest, MultithreadUpdateTtl) { + this->testMultithreadUpdateTtl(); +} using ObjectCache = ObjectCache; TEST(ObjectCacheTest, LruEviction) { From c120a5307c3062b21253c27f4a3ea598ae780b8b Mon Sep 17 00:00:00 2001 From: Jiayue Bao Date: Wed, 1 Mar 2023 16:13:29 -0800 Subject: [PATCH 24/92] Remove isWriteHandle() API Summary: Based on our discussion, this API would be confusing if a reference of ReadHandle is obtained from a WriteHandle. We also don't want to make it virtual because this will increase `sizeof(ReadHandle)` / `sizeof(WriteHandle)` by 8 bytes. Reviewed By: therealgymmy Differential Revision: D43667308 fbshipit-source-id: a77a17113f1a23f84332ebfa7ea6772d7647339c --- cachelib/allocator/Handle.h | 4 ---- cachelib/allocator/tests/BaseAllocatorTest.h | 8 +------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/cachelib/allocator/Handle.h b/cachelib/allocator/Handle.h index a125ace1b..11d2bed2b 100644 --- a/cachelib/allocator/Handle.h +++ b/cachelib/allocator/Handle.h @@ -242,8 +242,6 @@ struct ReadHandleImpl { return hdl; } - bool isWriteHandle() const { return false; } - protected: // accessor. Calling getInternal() on handle with isReady() == false blocks // the thread until the handle is ready. @@ -571,8 +569,6 @@ struct WriteHandleImpl : public ReadHandleImpl { // creating this item handle. WriteHandleImpl clone() const { return WriteHandleImpl{ReadHandle::clone()}; } - bool isWriteHandle() const { return true; } - // Friends friend ReadHandle; // Only CacheAllocator and NvmCache can create non-default constructed handles diff --git a/cachelib/allocator/tests/BaseAllocatorTest.h b/cachelib/allocator/tests/BaseAllocatorTest.h index d684545cb..aa9d38a85 100644 --- a/cachelib/allocator/tests/BaseAllocatorTest.h +++ b/cachelib/allocator/tests/BaseAllocatorTest.h @@ -713,35 +713,29 @@ class BaseAllocatorTest : public AllocatorTest { auto handle = alloc.find("key"); ASSERT_NE(handle, nullptr); ASSERT_TRUE(isConst(handle->getMemory())); - ASSERT_EQ(handle.isWriteHandle(), false); // read handle clone auto handle2 = handle.clone(); ASSERT_TRUE(isConst(handle2->getMemory())); - ASSERT_EQ(handle2.isWriteHandle(), false); // upgrade a read handle to a write handle auto handle3 = std::move(handle).toWriteHandle(); ASSERT_FALSE(isConst(handle3->getMemory())); - ASSERT_EQ(handle3.isWriteHandle(), true); } { auto handle = alloc.findToWrite("key"); ASSERT_NE(handle, nullptr); ASSERT_FALSE(isConst(handle->getMemory())); - ASSERT_EQ(handle.isWriteHandle(), true); // write handle clone auto handle2 = handle.clone(); ASSERT_FALSE(isConst(handle2->getMemory())); - ASSERT_EQ(handle2.isWriteHandle(), true); // downgrade a write handle to a read handle ReadHandle handle3 = handle.clone(); ASSERT_NE(handle3, nullptr); ASSERT_TRUE(isConst(handle3->getMemory())); - ASSERT_EQ(handle3.isWriteHandle(), false); } { @@ -752,7 +746,7 @@ class BaseAllocatorTest : public AllocatorTest { // This is like doing a "clone" and setting it into wait context waitContext->set(alloc.find("key")); auto handle2 = std::move(handle).toWriteHandle(); - ASSERT_EQ(handle2.isWriteHandle(), true); + ASSERT_FALSE(isConst(handle2->getMemory())); } } From 7785d24b3030a64a2e7d885e8ad552d5fa758f9b Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Wed, 1 Mar 2023 16:16:43 -0800 Subject: [PATCH 25/92] Edit Cachebench_FB_HW_eval.md using inpage editor Summary: This diff has been automatically generated by the inpage editor. NOTE: If you want to update this diff, go via the preview link inside the static docs section below. Ensure you are editing the same page that was used to create this diff. Reviewed By: therealgymmy Differential Revision: D43667238 fbshipit-source-id: 0be4c1ef376a5a1a2de92afc311af24f66d10afd --- .../Cache_Library_User_Guides/Cachebench_FB_HW_eval.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/website/docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md b/website/docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md index ce9964913..09abe4b05 100644 --- a/website/docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md +++ b/website/docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md @@ -17,10 +17,11 @@ sufficient free memory (50+GB) and SSD capacity (1TB). * SSD Capacity: 100GB or more available capacity * Internet connection capable of accessing github.com and installing packages -## Set up the SSD devices using mdraid +## Set up the SSD devices -To gather SSD performance metrics, the SSD must be setup first. An example -below sets up a raid device to handle two ssds being used by CacheBench. +To gather SSD performance metrics, the SSD must be setup first. Cachebench (and CacheLib) supports using various types of devices for NVM cache including a raw block device or a regular file. When one wants to use multiple SSDs as NVM cache, the CacheLib also provides a native support for RAID0 (i.e., striping). + +Optionally, as an example, an user can setup and use md devices as follows. In this example, the md device is created from two ssd devices to be used as a raw block device in CacheBench. ```sh mdadm --create /dev/md0 --force --raid-devices=2 --level=0 --chunk=256 /dev/nvme1n1 /dev/nvme2n1 From 185bbe6664167a680f4070713987548573cbbd2c Mon Sep 17 00:00:00 2001 From: Daniel Wong Date: Thu, 2 Mar 2023 11:23:44 -0800 Subject: [PATCH 26/92] Fix Debian GitHub build & zstd CMake error (#200) Summary: 1. Workaround for Debian Docker image bug that is breaking Debian build on GitHub (Explicitly mark Git repo as safe). 2. Pin zstd to a commit that resolves problems with older CMakes (note: affects all OSes, not just Debian) Context for 1: In latest Debian Docker image , there is a regression that affects the checkout action. From https://github.com/actions/checkout/issues/1169: > - Checkout runs, and runs /usr/bin/git config --global --add safe.directory > - The global .gitconfig does not exist > - Any calls to git remain unsafe/dubious The suggested workaround was to use --system instead of --global. Pull Request resolved: https://github.com/facebook/CacheLib/pull/200 Test Plan: See if GitHub Action Debian build is fixed. Reviewed By: therealgymmy Differential Revision: D43720363 Pulled By: jaesoo-fb fbshipit-source-id: 54f3586cc7f8e72045e60d8dd454c7a77725e6b2 --- .github/workflows/build-cachelib-debian-10.yml | 3 +++ contrib/build-package.sh | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-cachelib-debian-10.yml b/.github/workflows/build-cachelib-debian-10.yml index 56fb57629..7f0ab29a6 100644 --- a/.github/workflows/build-cachelib-debian-10.yml +++ b/.github/workflows/build-cachelib-debian-10.yml @@ -52,6 +52,9 @@ jobs: g++ - || true - name: "checkout sources" uses: actions/checkout@v2 + - name: "Add Git safe directory" + # Workaround for Docker image bug (GitHub issue #199). + run: git config --system --add safe.directory $GITHUB_WORKSPACE - name: "Install Prerequisites" run: ./contrib/build.sh -S -B - name: "Test: update-submodules" diff --git a/contrib/build-package.sh b/contrib/build-package.sh index 6e7acac5c..755933bd4 100755 --- a/contrib/build-package.sh +++ b/contrib/build-package.sh @@ -102,11 +102,12 @@ test "$#" -eq 0 \ && die "missing dependancy name to build. See -h for help" ###################################### -## Check which dependecy was requested +## Check which dependency was requested ###################################### external_git_clone= external_git_branch= +# external_git_tag can also be used for commit hashes external_git_tag= update_submodules= cmake_custom_params= @@ -175,7 +176,10 @@ case "$1" in REPODIR=cachelib/external/$NAME SRCDIR=$REPODIR/build/cmake external_git_clone=yes - external_git_branch=release + # Previously, we pinned to release branch. v1.5.4 needed + # CMake >= 3.18, later reverted. While waiting for v1.5.5, + # pin to the fix: https://github.com/facebook/zstd/pull/3510 + external_git_tag=8420502e if test "$build_tests" = "yes" ; then cmake_custom_params="-DZSTD_BUILD_TESTS=ON" else From 968533f58cfdc9fa70bdedc46918005150899a2d Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Fri, 3 Mar 2023 09:43:41 -0800 Subject: [PATCH 27/92] fix broken installation page link Summary: An user in github reported an issue that the installation link is broken. Somehow, docs/installation/installation.md cannot be referenced by `/docs/installation/installation`, but only by `/docs/installation`. The root cause could not figured out yet, but this change fixes it as such for now. Reviewed By: jiayuebao Differential Revision: D43757739 fbshipit-source-id: 4abd3208800c0b68e9162d381f6395897f047b24 --- README.md | 2 +- .../docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md | 5 ++--- .../docs/Cache_Library_User_Guides/Cachebench_Overview.md | 2 +- website/docs/installation/testing.md | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e05c932d1..523b8b20a 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ cd CacheLib Re-running `./contrib/build.sh` will update CacheLib and its dependencies to their latest versions and rebuild them. -See [build](https://cachelib.org/docs/installation/installation) for more details about +See [build](https://cachelib.org/docs/installation/) for more details about the building and installation process. diff --git a/website/docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md b/website/docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md index 09abe4b05..d17b7ac52 100644 --- a/website/docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md +++ b/website/docs/Cache_Library_User_Guides/Cachebench_FB_HW_eval.md @@ -19,7 +19,7 @@ sufficient free memory (50+GB) and SSD capacity (1TB). ## Set up the SSD devices -To gather SSD performance metrics, the SSD must be setup first. Cachebench (and CacheLib) supports using various types of devices for NVM cache including a raw block device or a regular file. When one wants to use multiple SSDs as NVM cache, the CacheLib also provides a native support for RAID0 (i.e., striping). +To gather SSD performance metrics, the SSD must be setup first. Cachebench (and CacheLib) supports using various types of devices for NVM cache including a raw block device or a regular file. When one wants to use multiple SSDs as NVM cache, the CacheLib also provides a native support for RAID0 (i.e., striping). Optionally, as an example, an user can setup and use md devices as follows. In this example, the md device is created from two ssd devices to be used as a raw block device in CacheBench. @@ -143,7 +143,7 @@ mdadm --create /dev/md0 --force --raid-devices=2 --level=0 --chunk=256 /dev/nvme make install ``` -See [build and installation](/docs/installation/installation) for further details. +See [build and installation](/docs/installation) for further details. ## Running the benchmark for SSD perf testing @@ -197,7 +197,6 @@ For a full list of options that can be configured, see [configuring cachebench]( using the `--progress` and specifying a duration in seconds. If `--progress-stats-file` is also specified, on every progress interval, `cachebench` would log the internal stats to the specified file. - ## Running cachebench with the trace workload Meta is sharing anonymized traces captured from large scale production cache services. These traces are licensed under the same license as CacheLib. They are meant to help academic and industry researchers to optimize for our caching workloads. One can freely download it from our AWS S3 bucket and run the CacheBench to replay the trace with varying configuration as follows. diff --git a/website/docs/Cache_Library_User_Guides/Cachebench_Overview.md b/website/docs/Cache_Library_User_Guides/Cachebench_Overview.md index eb7264654..8c878e1be 100644 --- a/website/docs/Cache_Library_User_Guides/Cachebench_Overview.md +++ b/website/docs/Cache_Library_User_Guides/Cachebench_Overview.md @@ -53,6 +53,6 @@ developer's need. The following are few examples. ## Building cachebench -Follow instructions in [Installation](/docs/installation/installation) to build +Follow instructions in [Installation](/docs/installation) to build cachebench. This should install cachebench in your local machine under ```opt/cachelib/bin/cachebench``` diff --git a/website/docs/installation/testing.md b/website/docs/installation/testing.md index 02b2cb747..d8730127b 100644 --- a/website/docs/installation/testing.md +++ b/website/docs/installation/testing.md @@ -11,7 +11,7 @@ of the cache infrastructure. ## Building CacheLib Unit Tests To build the cachelib unit tests, use one of the following commands -(see [installation](docs/installation/installation) instructions for more details): +(see [installation](/docs/installation) instructions for more details): 1. Use `./contrib/build.sh` script with the `-T` option. 2. Use `./contrib/build-package.sh -t cachelib` (with the `-t` option) @@ -42,7 +42,7 @@ Running a single unit test binary: ```sh $ cd opt/cachelib/tests -$ ./allocator-test-ItemTest +$ ./allocator-test-ItemTest [==========] Running 6 tests from 1 test suite. [----------] Global test environment set-up. [----------] 6 tests from ItemTest From 496ed376b7000bca496e03a2b1cb4e47d24e7f24 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Fri, 3 Mar 2023 12:13:05 -0800 Subject: [PATCH 28/92] fix another broken installation page link in index.js Summary: There is another missing link in index.js for installation page. This change fixes it. Reviewed By: jiayuebao Differential Revision: D43774697 fbshipit-source-id: 1c2ff1c801ae41ea6b50e6e687714f422bcb0c92 --- website/src/pages/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/pages/index.js b/website/src/pages/index.js index 151ec3f3f..5886c079f 100644 --- a/website/src/pages/index.js +++ b/website/src/pages/index.js @@ -117,7 +117,7 @@ function Home() { 'button button--secondary button--lg', styles.getStarted, )} - to={ useBaseUrl('docs/installation/installation') }> + to={ useBaseUrl('docs/installation') }> Get Started From 67d2d8be64206b6c75e123483c3ebe202b548a1c Mon Sep 17 00:00:00 2001 From: Michel Salim Date: Sat, 4 Mar 2023 18:50:50 -0800 Subject: [PATCH 29/92] temporarily disable PackIt (#205) Summary: We need to fix builds for the entire Folly stack first before this will work again Pull Request resolved: https://github.com/facebook/CacheLib/pull/205 Reviewed By: michel-slm, jiayuebao Differential Revision: D43786012 Pulled By: jaesoo-fb fbshipit-source-id: dfd1947d7d2c294fc622496d6054c2395ef0d5a3 --- .packit.yaml | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 .packit.yaml diff --git a/.packit.yaml b/.packit.yaml deleted file mode 100644 index bea307d9d..000000000 --- a/.packit.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# See the documentation for more information: -# https://packit.dev/docs/configuration - -specfile_path: cachelib.spec - -upstream_package_name: CacheLib -downstream_package_name: cachelib - -actions: - fix-spec-file: - - bash -c "sed -i cachelib.spec -e \"s/%global commit.*/%global commit $(git rev-parse HEAD)/\"" - - bash -c "sed -i cachelib.spec -e \"s/%global date.*/%global date $(git show -s --date=format:'%Y%m%d' --format=%cd)/\"" - create-archive: - - bash -c "COMMIT=$(git rev-parse HEAD); curl -ORL https://github.com/facebook/CacheLib/archive/${COMMIT}/cachelib-${COMMIT}.tar.gz; echo cachelib-${COMMIT}.tar.gz" - post-upstream-clone: "bash -c \"rm -rf cachelib-dist-git; git clone -b packit https://pagure.io/meta/cachelib.git cachelib-dist-git && mv cachelib-dist-git/cachelib*.{spec,patch} .\"" - -jobs: -- job: copr_build - trigger: pull_request - metadata: - targets: - - fedora-rawhide-aarch64 - - fedora-rawhide-x86_64 - - fedora-35-aarch64 - - fedora-35-x86_64 From 115732a51ed3c5b9ce88842f4ccb5c876eab6401 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Mon, 6 Mar 2023 09:55:32 -0800 Subject: [PATCH 30/92] Edit Overview_A_random_walk_down_the_Cache_Library.md using inpage editor Summary: This diff has been automatically generated by the inpage editor. NOTE: If you want to update this diff, go via the preview link inside the static docs section below. Ensure you are editing the same page that was used to create this diff. Reviewed By: therealgymmy Differential Revision: D43781316 fbshipit-source-id: 18091011f9e4592240fb41c5fb9cc8cb40e62205 --- .../Overview_A_random_walk_down_the_Cache_Library.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/Cache_Library_Architecture_Guide/Overview_A_random_walk_down_the_Cache_Library.md b/website/docs/Cache_Library_Architecture_Guide/Overview_A_random_walk_down_the_Cache_Library.md index f13fc1322..cf4e750c4 100644 --- a/website/docs/Cache_Library_Architecture_Guide/Overview_A_random_walk_down_the_Cache_Library.md +++ b/website/docs/Cache_Library_Architecture_Guide/Overview_A_random_walk_down_the_Cache_Library.md @@ -107,7 +107,7 @@ There will be a section discussing each of the bullets below. * For regular cache: Find the item in the chained hash map. From the item, get the slab it lives on and form the slab, identify the allocation class and promote the item on that particular LRU queue. Increment the refcount and return the item handle. ## Flash overview -Flash is organized in a similar way: there is a cache for smaller items (BigHash) and for larger item (Block Cache). Unlike DRAM, the client does not get to choose where the item goes. It's done automatically thresholding the size. Together, this constitutes [Navy](/docs/Cache_Library_Architecture_Guide/Navy_Architecture_Overview ) -- the flash cache engine of CacheLib. +Flash is organized in a similar way: there is a cache for smaller items (BigHash) and for larger item (Block Cache). Unlike DRAM, the client does not get to choose where the item goes. It's done automatically thresholding the size. Together, this constitutes [Navy](/docs/Cache_Library_Architecture_Guide/Navy_Overview ) -- the flash cache engine of CacheLib. * "block device" refers to devices that's read/write happen with a fixed size block (if it helps, substitute the word "page" here). It means you can't write with precision of bytes but have to incur overhead if you don't write an entire block. From 17bdc1818911fc13bee1bfd10480a496d6336496 Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Tue, 7 Mar 2023 10:30:13 -0800 Subject: [PATCH 31/92] fbcode/cachelib/experimental/objcache2/persistence Reviewed By: jiayuebao Differential Revision: D43869027 fbshipit-source-id: 6f805a86b072e2fc96d4357672175e8283e06d0d --- .../objcache2/persistence/persistent_data.thrift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cachelib/experimental/objcache2/persistence/persistent_data.thrift b/cachelib/experimental/objcache2/persistence/persistent_data.thrift index 486e130a1..1d310693f 100644 --- a/cachelib/experimental/objcache2/persistence/persistent_data.thrift +++ b/cachelib/experimental/objcache2/persistence/persistent_data.thrift @@ -17,12 +17,12 @@ namespace cpp2 facebook.cachelib.objcache2.persistence struct Item { - 1: string key, - 2: string payload, - 3: i32 objectSize, - 4: i32 expiryTime, + 1: string key; + 2: string payload; + 3: i32 objectSize; + 4: i32 expiryTime; } struct Metadata { - 1: i32 threadCount, + 1: i32 threadCount; } From e679b72d5b78c51f1cd3a250ad4918250af8ddc9 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Tue, 7 Mar 2023 15:54:02 -0800 Subject: [PATCH 32/92] README.md: added build status badges to main README.md Summary: As suggested by wonglkd in https://github.com/facebook/CacheLib/issues/199, this change adds the build status for all targets in the main README.md (https://github.com/facebook/CacheLib) Reviewed By: therealgymmy Differential Revision: D43854616 fbshipit-source-id: add32de29c160ed06e1778fef41bb37ffc359fd7 --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 523b8b20a..7fc943b20 100644 --- a/README.md +++ b/README.md @@ -77,3 +77,18 @@ https://www.facebook.com/whitehat Facebook's security team will triage your report and determine whether or not is it eligible for a bounty under our program. + + +## Build status + +Clicking on a badge will show you the recent builds for that OS. If your target OS's build is failing, you may wish to check recent issues and PRs for known workarounds. + +- [![CentOS 8.1](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-centos-8-1.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-centos-8-1.yml?query=event%3Aschedule) +- [![CentOS 8.5](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-centos-8-5.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-centos-8-5.yml?query=event%3Aschedule) +- [![Debian 10](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-debian-10.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-debian-10.yml?query=event%3Aschedule) +- [![Fedora 36](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-fedora-36.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-fedora-36.yml?query=event%3Aschedule) +- [![Rocky Linux 8](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-rockylinux-8.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-rockylinux-8.yml?query=event%3Aschedule) +- [![Rocky Linux 9](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-rockylinux-9.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-rockylinux-9.yml?query=event%3Aschedule) +- [![Ubuntu 18](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-ubuntu-18.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-ubuntu-18.yml?query=event%3Aschedule) +- [![Ubuntu 20](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-ubuntu-20.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-ubuntu-20.yml?query=event%3Aschedule) +- [![Ubuntu 22](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-ubuntu-22.yml/badge.svg?event=schedule)](https://github.com/facebook/cachelib/actions/workflows/build-cachelib-ubuntu-22.yml?query=event%3Aschedule) From 43a7ce3ab7b58c26e15b2972203948e8f016e2d5 Mon Sep 17 00:00:00 2001 From: Aliaa Atwi Date: Wed, 8 Mar 2023 11:54:15 -0800 Subject: [PATCH 33/92] Fix Bug in ItemValue handling in CacheBench Summary: **Context:** To enable user/intern simulations, D41134915 added 'itemValue' support in cachebench simulations. Any string that appears in the 'itemValue' column in the trace, is used to populate the cachelib item value (previously empty). For user/intern, we set this string to "0" for user and "1" for intern. Then in FBDep.cpp, we tell the admission policy to distinguish user/intern with a lambda function that parses item value. Prod uses a different lambda that reads item *header*, which has a user/intern flag set by Proxygen as part of the request to BigCache. We cannot use the same function and item header flag in simulations because the simulator does not run Proxygen. Instead, it emulates its behavior with trace + PieceWiseReplayGenerator. **This diff:** Currently, the logic that populates item value in cachebench (setStringItem below) takes a std::string and sets the item value with that. When we want to read the item in FBDep, we don't know where the end of the string is because the item can be bigger than the data. Right now, we're avoiding this by adding a null character at the end of the itemValue data string. FBDep then uses strnlen to find the length of the data until the null string. **This is not working as intended**, and the string read in FBDep includes gibberish after the "0" or "1" because it is not properly terminated. This diff fixes the issue. Reviewed By: jaesoo-fb Differential Revision: D43861361 fbshipit-source-id: d4974281e28165ecf8c23c44dc4a6b50d5b1b806 --- cachelib/cachebench/cache/Cache-inl.h | 13 +++++++++++-- cachelib/cachebench/runner/CacheStressor.h | 4 +--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cachelib/cachebench/cache/Cache-inl.h b/cachelib/cachebench/cache/Cache-inl.h index ed8bfd1b0..dc5e878fc 100644 --- a/cachelib/cachebench/cache/Cache-inl.h +++ b/cachelib/cachebench/cache/Cache-inl.h @@ -794,8 +794,17 @@ void Cache::setUint64ToItem(WriteHandle& handle, template void Cache::setStringItem(WriteHandle& handle, const std::string& str) { - auto ptr = reinterpret_cast(getMemory(handle)); - std::memcpy(ptr, str.data(), std::min(str.size(), getSize(handle))); + auto dataSize = getSize(handle); + if (dataSize < 1) + return; + + auto ptr = reinterpret_cast(getMemory(handle)); + std::strncpy(ptr, str.c_str(), dataSize); + + // Make sure the copied string ends with null char + if (str.size() + 1 > dataSize) { + ptr[dataSize - 1] = '\0'; + } } template diff --git a/cachelib/cachebench/runner/CacheStressor.h b/cachelib/cachebench/runner/CacheStressor.h index 4ea54b1f1..d2433a734 100644 --- a/cachelib/cachebench/runner/CacheStressor.h +++ b/cachelib/cachebench/runner/CacheStressor.h @@ -254,9 +254,7 @@ class CacheStressor : public Stressor { } if (!itemValue.empty()) { - // Add the null character to ensure this is a proper c string. - // TODO(T141356292): Clean this up to avoid allocating a new string - cache_->setStringItem(handle, itemValue + "\0"); + cache_->setStringItem(handle, itemValue); } else { cache_->setStringItem(handle, hardcodedString_); } From 872d61a6f09ce100c510069f526ce9fb9cb701c6 Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Wed, 8 Mar 2023 16:08:53 -0800 Subject: [PATCH 34/92] fbcode/cachelib/benchmarks Differential Revision: D43869116 fbshipit-source-id: c62c2518691313ec82c15c9f65ac304378222257 --- cachelib/benchmarks/DataTypeBench.thrift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cachelib/benchmarks/DataTypeBench.thrift b/cachelib/benchmarks/DataTypeBench.thrift index a1f16f4b7..94d53ade8 100644 --- a/cachelib/benchmarks/DataTypeBench.thrift +++ b/cachelib/benchmarks/DataTypeBench.thrift @@ -17,11 +17,9 @@ namespace cpp2 facebook.cachelib.datatypebench struct StdMap { - 1: required map m, + 1: required map m; } struct StdUnorderedMap { - 1: required map - (cpp.template = "std::unordered_map") - m, + 1: required map (cpp.template = "std::unordered_map") m; } From ffa54709fb021fa2d15494fed39d60df53b0fb0f Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Wed, 8 Mar 2023 16:09:11 -0800 Subject: [PATCH 35/92] fbcode/cachelib/allocator/datastruct/tests Differential Revision: D43869054 fbshipit-source-id: e90b16576404b8eb5819c65d61fe972f0f518c66 --- cachelib/allocator/datastruct/tests/test_objects.thrift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cachelib/allocator/datastruct/tests/test_objects.thrift b/cachelib/allocator/datastruct/tests/test_objects.thrift index 51af09851..4cb58b188 100644 --- a/cachelib/allocator/datastruct/tests/test_objects.thrift +++ b/cachelib/allocator/datastruct/tests/test_objects.thrift @@ -20,6 +20,6 @@ namespace cpp2 facebook.cachelib.test_serialization // testing warm rolls from the old format to the new format. // TODO(bwatling): remove this when 'compressedTail' is always present. struct SListObjectNoCompressedTail { - 2: required i64 size, - 3: required i64 compressedHead, // Pointer to the head element + 2: required i64 size; + 3: required i64 compressedHead; // Pointer to the head element } From 1031b13fc914104ca9b606edc7c183896e0bb46a Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Wed, 8 Mar 2023 16:13:55 -0800 Subject: [PATCH 36/92] fbcode/cachelib/experimental/objcache2/tests Differential Revision: D43869046 fbshipit-source-id: 288bc98b8146424f71ece5d0685d08c59e3ed523 --- .../experimental/objcache2/tests/test_object.thrift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cachelib/experimental/objcache2/tests/test_object.thrift b/cachelib/experimental/objcache2/tests/test_object.thrift index bf6ad0743..a448014cd 100644 --- a/cachelib/experimental/objcache2/tests/test_object.thrift +++ b/cachelib/experimental/objcache2/tests/test_object.thrift @@ -17,13 +17,13 @@ namespace cpp2 facebook.cachelib.objcache2.test struct ThriftFoo { - 1: i32 a; - 2: i32 b; - 3: i32 c; + 1: i32 a; + 2: i32 b; + 3: i32 c; } struct ThriftFoo2 { - 1: i32 d; - 2: i32 e; - 3: i32 f; + 1: i32 d; + 2: i32 e; + 3: i32 f; } From d92910bc096906f94c0b9ef888e1b2d7fcdac68d Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Wed, 8 Mar 2023 16:14:25 -0800 Subject: [PATCH 37/92] fbcode/cachelib/experimental/objcache/tests Differential Revision: D43869073 fbshipit-source-id: 52fea96db9cefe735ba56b564bf6af5566cd6d76 --- .../tests/ThriftCustomAllocator.thrift | 77 +++++++++++-------- 1 file changed, 44 insertions(+), 33 deletions(-) diff --git a/cachelib/experimental/objcache/tests/ThriftCustomAllocator.thrift b/cachelib/experimental/objcache/tests/ThriftCustomAllocator.thrift index 97f82d466..b1610b3aa 100644 --- a/cachelib/experimental/objcache/tests/ThriftCustomAllocator.thrift +++ b/cachelib/experimental/objcache/tests/ThriftCustomAllocator.thrift @@ -24,22 +24,26 @@ struct UseSimpleCustomAllocator { // A template type like map needs to use "cpp.template" to specify a replacement template 1: map< + // A concrete type like string needs to use "cpp.type" to specify a replacement type + string ( + cpp.use_allocator, + cpp.type = "facebook::cachelib::objcache::test::TestString", + ), + string ( + cpp.use_allocator, + cpp.type = "facebook::cachelib::objcache::test::TestString", + ) + > ( + cpp.use_allocator, + cpp.template = "facebook::cachelib::objcache::test::TestMap", + ) m; - // A concrete type like string needs to use "cpp.type" to specify a replacement type - string - (cpp.use_allocator, - cpp.type = "facebook::cachelib::objcache::test::TestString"), - - string - (cpp.use_allocator, - cpp.type = "facebook::cachelib::objcache::test::TestString") - - > (cpp.use_allocator, - cpp.template = "facebook::cachelib::objcache::test::TestMap") m; - - // Native types or types that do not allocate memory do NOT need custom allocator - 2: i32 m2; -} (cpp.allocator="facebook::cachelib::objcache::test::ScopedTestAllocator", cpp.allocator_via="m") + // Native types or types that do not allocate memory do NOT need custom allocator + 2: i32 m2; +} ( + cpp.allocator = "facebook::cachelib::objcache::test::ScopedTestAllocator", + cpp.allocator_via = "m", +) // TODO: thrift allocator propagation behavior is broken. Right now, for the following // myObj1 = myObj2; // even if the allocator copy-assignment propagation is false, myObj2's @@ -50,17 +54,21 @@ struct UseSimpleCustomAllocator { union UnionWithCustomAllocator { 1: map< - i32, - string - (cpp.use_allocator, - cpp.type = "facebook::cachelib::objcache::test::TestString") - > (cpp.use_allocator, - cpp.template = "facebook::cachelib::objcache::test::TestMap")m1; - 2: string - (cpp.use_allocator, - cpp.type = "facebook::cachelib::objcache::test::TestString") m2; + i32, + string ( + cpp.use_allocator, + cpp.type = "facebook::cachelib::objcache::test::TestString", + ) + > ( + cpp.use_allocator, + cpp.template = "facebook::cachelib::objcache::test::TestMap", + ) m1; + 2: string ( + cpp.use_allocator, + cpp.type = "facebook::cachelib::objcache::test::TestString", + ) m2; 3: i32 m3; -} (cpp.allocator="facebook::cachelib::objcache::test::ScopedTestAllocator") +} (cpp.allocator = "facebook::cachelib::objcache::test::ScopedTestAllocator") // TODO: even though thrift union does not support allocator. We still need to // annotate it with allocator so it has a `get_allocator()` method so // that when deserializing it will be able to pass an allocator an inner @@ -89,11 +97,14 @@ union UnionWithCustomAllocator { // } struct UseTwoF14Maps { - 1: map - (cpp.use_allocator, - cpp.template = "facebook::cachelib::objcache::test::TestFollyF14FastMap") m1; - 2: map - (cpp.use_allocator, - cpp.template = "facebook::cachelib::objcache::test::TestFollyF14FastMap") m2; -} (cpp.allocator= - "facebook::cachelib::objcache::test::TestF14TemplateAllocator>") + 1: map ( + cpp.use_allocator, + cpp.template = "facebook::cachelib::objcache::test::TestFollyF14FastMap", + ) m1; + 2: map ( + cpp.use_allocator, + cpp.template = "facebook::cachelib::objcache::test::TestFollyF14FastMap", + ) m2; +} ( + cpp.allocator = "facebook::cachelib::objcache::test::TestF14TemplateAllocator>", +) From 1e05a161e84c2bb341903ff4e5cdc1496c87b9e0 Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Wed, 8 Mar 2023 16:43:58 -0800 Subject: [PATCH 38/92] fbcode/cachelib/navy/serialization Differential Revision: D43869045 fbshipit-source-id: 120149fa4cac2590b93f0c9a9fa5f7827efca3fc --- cachelib/navy/serialization/objects.thrift | 90 +++++++++++----------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/cachelib/navy/serialization/objects.thrift b/cachelib/navy/serialization/objects.thrift index 32be4bd17..887c90c6b 100644 --- a/cachelib/navy/serialization/objects.thrift +++ b/cachelib/navy/serialization/objects.thrift @@ -17,78 +17,78 @@ namespace cpp2 facebook.cachelib.navy.serialization struct IndexEntry { - 1: required i32 key = 0, - 2: required i32 address = 0, - 3: i16 sizeHint = 0, - 4: byte totalHits = 0, - 5: byte currentHits = 0, + 1: required i32 key = 0; + 2: required i32 address = 0; + 3: i16 sizeHint = 0; + 4: byte totalHits = 0; + 5: byte currentHits = 0; } struct IndexBucket { - 1: required i32 bucketId = 0, - 2: required list entries, + 1: required i32 bucketId = 0; + 2: required list entries; } struct Region { - 1: required i32 regionId = 0, - 2: required i32 lastEntryEndOffset = 0, - 3: required i32 classId = 0, - 4: required i32 numItems = 0, - 5: required bool pinned = false, - 6: i32 priority = 0, + 1: required i32 regionId = 0; + 2: required i32 lastEntryEndOffset = 0; + 3: required i32 classId = 0; + 4: required i32 numItems = 0; + 5: required bool pinned = false; + 6: i32 priority = 0; } struct RegionData { - 1: required list regions, - 2: required i32 regionSize = 0, + 1: required list regions; + 2: required i32 regionSize = 0; } struct FifoPolicyNodeData { - 1: required i32 idx, - 2: required i64 trackTime, + 1: required i32 idx; + 2: required i64 trackTime; } -struct FifoPolicyData{ - 1: required list queue, +struct FifoPolicyData { + 1: required list queue; } struct AccessStats { - 1: byte totalHits = 0, - 2: byte currHits = 0, - 3: byte numReinsertions = 0, + 1: byte totalHits = 0; + 2: byte currHits = 0; + 3: byte numReinsertions = 0; } struct AccessStatsPair { - 1: i64 key, - 2: AccessStats stats, + 1: i64 key; + 2: AccessStats stats; } struct AccessTracker { - 1: map deprecated_data, - 2: list data, + 1: map deprecated_data; + 2: list data; } struct BlockCacheConfig { - 1: required i64 version = 0, - 2: required i64 cacheBaseOffset = 0, - 3: required i64 cacheSize = 0, - 4: required i32 allocAlignSize = 0, - 5: required set deprecated_sizeClasses, - 6: required bool checksum = false, - 7: map deprecated_sizeDist, - 8: i64 holeCount = 0, - 9: i64 holeSizeTotal = 0, - 10: bool reinsertionPolicyEnabled = false, - 11: i64 usedSizeBytes = 0, + 1: required i64 version = 0; + 2: required i64 cacheBaseOffset = 0; + 3: required i64 cacheSize = 0; + 4: required i32 allocAlignSize = 0; + 5: required set deprecated_sizeClasses; + 6: required bool checksum = false; + 7: map deprecated_sizeDist; + 8: i64 holeCount = 0; + 9: i64 holeSizeTotal = 0; + 10: bool reinsertionPolicyEnabled = false; + 11: i64 usedSizeBytes = 0; } struct BigHashPersistentData { - 1: required i32 version = 0, - 2: required i64 generationTime = 0, - 3: required i64 itemCount = 0, - 4: required i64 bucketSize = 0, - 5: required i64 cacheBaseOffset = 0, - 6: required i64 numBuckets = 0, - 7: map deprecated_sizeDist, - 8: i64 usedSizeBytes = 0, + 1: required i32 version = 0; + 2: required i64 generationTime = 0; + 3: required i64 itemCount = 0; + 4: required i64 bucketSize = 0; + 5: required i64 cacheBaseOffset = 0; + 6: required i64 numBuckets = 0; + 7: map deprecated_sizeDist; + 8: i64 usedSizeBytes = 0; } From 0bc9f66f72b017616970f8dac7b2d87aeadc8692 Mon Sep 17 00:00:00 2001 From: Igor Chorazewicz Date: Wed, 8 Mar 2023 23:00:16 -0800 Subject: [PATCH 39/92] Introduce 'markedForEviction' state for the Item. (#183) Summary: It is similar to 'moving' but requires ref count to be 0. An item which is marked for eviction causes all incRef() calls to that item to fail. This will be used to ensure that once item is selected for eviction, no one can interfere and prevent the eviction from suceeding. 'markedForEviction' relies on the same 'exlusive' bit as the 'moving' state. To distinguish between those two states, 'moving' add 1 to the refCount. This is hidden from the user, so getRefCount() will not return that extra ref. Pull Request resolved: https://github.com/facebook/CacheLib/pull/183 Test Plan: flatmemcache shadow result: It seems there is a slight latency regression in allocation (~1 micro second) https://fburl.com/ods/u3isn8b4 It's probably small enough to ignore. But we can come back if this starts showing up in large scale in production. Imported from GitHub, without a `Test Plan:` line. Reviewed By: therealgymmy Differential Revision: D42089974 Pulled By: haowu14 fbshipit-source-id: 90477faa9443080a7ddefa37a524965a04b6f084 --- cachelib/allocator/CacheAllocator-inl.h | 88 ++++--- cachelib/allocator/CacheAllocator.h | 10 +- cachelib/allocator/CacheItem-inl.h | 56 ++-- cachelib/allocator/CacheItem.h | 57 ++-- cachelib/allocator/Refcount.h | 305 +++++++++++++++------- cachelib/allocator/tests/ItemTest.cpp | 14 +- cachelib/allocator/tests/RefCountTest.cpp | 102 ++++++-- 7 files changed, 450 insertions(+), 182 deletions(-) diff --git a/cachelib/allocator/CacheAllocator-inl.h b/cachelib/allocator/CacheAllocator-inl.h index 1d8959326..b8d0256d5 100644 --- a/cachelib/allocator/CacheAllocator-inl.h +++ b/cachelib/allocator/CacheAllocator-inl.h @@ -832,20 +832,21 @@ CacheAllocator::releaseBackToAllocator(Item& it, removeFromMMContainer(*head); - // If this chained item is marked as exclusive, we will not free it. - // We must capture the exclusive state before we do the decRef when + // If this chained item is marked as moving, we will not free it. + // We must capture the moving state before we do the decRef when // we know the item must still be valid - const bool wasExclusive = head->isExclusive(); + const bool wasMoving = head->isMoving(); + XDCHECK(!head->isMarkedForEviction()); // Decref and check if we were the last reference. Now if the item - // was marked exclusive, after decRef, it will be free to be released + // was marked moving, after decRef, it will be free to be released // by slab release thread const auto childRef = head->decRef(); - // If the item is already exclusive and we already decremented the + // If the item is already moving and we already decremented the // refcount, we don't need to free this item. We'll let the slab // release thread take care of that - if (!wasExclusive) { + if (!wasMoving) { if (childRef != 0) { throw std::runtime_error(folly::sformat( "chained item refcount is not zero. We cannot proceed! " @@ -853,7 +854,7 @@ CacheAllocator::releaseBackToAllocator(Item& it, childRef, head->toString())); } - // Item is not exclusive and refcount is 0, we can proceed to + // Item is not moving and refcount is 0, we can proceed to // free it or recylce the memory if (head == toRecycle) { XDCHECK(ReleaseRes::kReleased != res); @@ -881,9 +882,12 @@ CacheAllocator::releaseBackToAllocator(Item& it, } template -void CacheAllocator::incRef(Item& it) { - it.incRef(); - ++handleCount_.tlStats(); +bool CacheAllocator::incRef(Item& it) { + if (it.incRef()) { + ++handleCount_.tlStats(); + return true; + } + return false; } template @@ -903,8 +907,12 @@ CacheAllocator::acquire(Item* it) { SCOPE_FAIL { stats_.numRefcountOverflow.inc(); }; - incRef(*it); - return WriteHandle{it, *this}; + if (LIKELY(incRef(*it))) { + return WriteHandle{it, *this}; + } else { + // item is being evicted + return WriteHandle{}; + } } template @@ -1179,7 +1187,7 @@ bool CacheAllocator::moveChainedItem(ChainedItem& oldItem, // This item has been unlinked from its parent and we're the only // owner of it, so we're done here - if (!oldItem.isInMMContainer() || oldItem.isOnlyExclusive()) { + if (!oldItem.isInMMContainer() || oldItem.isOnlyMoving()) { return false; } @@ -1210,7 +1218,7 @@ bool CacheAllocator::moveChainedItem(ChainedItem& oldItem, // In case someone else had removed this chained item from its parent by now // So we check again to see if the it has been unlinked from its parent - if (!oldItem.isInMMContainer() || oldItem.isOnlyExclusive()) { + if (!oldItem.isInMMContainer() || oldItem.isOnlyMoving()) { return false; } @@ -1226,7 +1234,7 @@ bool CacheAllocator::moveChainedItem(ChainedItem& oldItem, // parent's chain and the MMContainer. auto oldItemHandle = replaceChainedItemLocked(oldItem, std::move(newItemHdl), *parentHandle); - XDCHECK(oldItemHandle->isExclusive()); + XDCHECK(oldItemHandle->isMoving()); XDCHECK(!oldItemHandle->isInMMContainer()); return true; @@ -1255,7 +1263,7 @@ CacheAllocator::findEviction(PoolId pid, ClassId cid) { : toRecycle; // make sure no other thead is evicting the item - if (candidate->getRefCount() != 0 || !candidate->markExclusive()) { + if (candidate->getRefCount() != 0 || !candidate->markMoving()) { ++itr; continue; } @@ -1270,11 +1278,11 @@ CacheAllocator::findEviction(PoolId pid, ClassId cid) { ? advanceIteratorAndTryEvictChainedItem(itr) : advanceIteratorAndTryEvictRegularItem(mmContainer, itr); evictionSuccessful = toReleaseHandle != nullptr; - // destroy toReleseHandle. The item won't be released to allocator - // since we marked it as exclusive. + // destroy toReleaseHandle. The item won't be released to allocator + // since we marked for eviction. } - const auto ref = candidate->unmarkExclusive(); + const auto ref = candidate->unmarkMoving(); if (ref == 0u) { // Invalidate iterator since later on we may use this mmContainer // again, which cannot be done unless we drop this iterator @@ -2361,7 +2369,7 @@ void CacheAllocator::releaseSlabImpl( // Need to mark an item for release before proceeding // If we can't mark as moving, it means the item is already freed const bool isAlreadyFreed = - !markExclusiveForSlabRelease(releaseContext, alloc, throttler); + !markMovingForSlabRelease(releaseContext, alloc, throttler); if (isAlreadyFreed) { continue; } @@ -2406,8 +2414,8 @@ bool CacheAllocator::moveForSlabRelease( stats_.numMoveAttempts.inc(); // Nothing to move and the key is likely also bogus for chained items. - if (oldItem.isOnlyExclusive()) { - oldItem.unmarkExclusive(); + if (oldItem.isOnlyMoving()) { + oldItem.unmarkMoving(); const auto res = releaseBackToAllocator(oldItem, RemoveContext::kNormal, false); XDCHECK(res == ReleaseRes::kReleased); @@ -2446,7 +2454,7 @@ bool CacheAllocator::moveForSlabRelease( // that's identical to this one to replace it. Here we just need to wait // until all users have dropped the item handles before we can proceed. startTime = util::getCurrentTimeSec(); - while (!oldItem.isOnlyExclusive()) { + while (!oldItem.isOnlyMoving()) { throttleWith(throttler, [&] { XLOGF(WARN, "Spent {} seconds, slab release still waiting for refcount to " @@ -2500,8 +2508,8 @@ CacheAllocator::allocateNewItemForOldItem(const Item& oldItem) { return {}; } - // Set up the destination for the move. Since oldChainedItem would have - // the exclusive bit set, it won't be picked for eviction. + // Set up the destination for the move. Since oldChainedItem would be + // marked as moving, it won't be picked for eviction. auto newItemHdl = allocateChainedItemInternal(parentHandle, oldChainedItem.getSize()); if (!newItemHdl) { @@ -2553,7 +2561,7 @@ bool CacheAllocator::tryMovingForSlabRelease( // item is still valid. const std::string parentKey = oldItem.asChainedItem().getParentItem(compressor_).getKey().str(); - if (oldItem.isOnlyExclusive()) { + if (oldItem.isOnlyMoving()) { // If chained item no longer has a refcount, its parent is already // being released, so we abort this try to moving. return false; @@ -2583,10 +2591,10 @@ void CacheAllocator::evictForSlabRelease( stats_.numEvictionAttempts.inc(); // if the item is already in a state where only the exclusive bit is set, - // nothing needs to be done. We simply need to unmark exclusive bit and free + // nothing needs to be done. We simply need to call unmarkMoving and free // the item. - if (item.isOnlyExclusive()) { - item.unmarkExclusive(); + if (item.isOnlyMoving()) { + item.unmarkMoving(); const auto res = releaseBackToAllocator(item, RemoveContext::kNormal, false); XDCHECK(ReleaseRes::kReleased == res); @@ -2617,7 +2625,7 @@ void CacheAllocator::evictForSlabRelease( stats_.numEvictionSuccesses.inc(); // we have the last handle. no longer need to hold on to the exclusive bit - item.unmarkExclusive(); + item.unmarkMoving(); // manually decrement the refcount to call releaseBackToAllocator const auto ref = decRef(*owningHandle); @@ -2629,7 +2637,7 @@ void CacheAllocator::evictForSlabRelease( } if (shutDownInProgress_) { - item.unmarkExclusive(); + item.unmarkMoving(); allocator_->abortSlabRelease(ctx); throw exception::SlabReleaseAborted( folly::sformat("Slab Release aborted while trying to evict" @@ -2775,9 +2783,9 @@ CacheAllocator::advanceIteratorAndTryEvictChainedItem( template typename CacheAllocator::WriteHandle CacheAllocator::evictNormalItemForSlabRelease(Item& item) { - XDCHECK(item.isExclusive()); + XDCHECK(item.isMoving()); - if (item.isOnlyExclusive()) { + if (item.isOnlyMoving()) { return WriteHandle{}; } @@ -2789,7 +2797,7 @@ CacheAllocator::evictNormalItemForSlabRelease(Item& item) { // We remove the item from both access and mm containers. It doesn't matter // if someone else calls remove on the item at this moment, the item cannot - // be freed as long as we have the exclusive bit set. + // be freed as long as it's marked for eviction. auto handle = accessContainer_->removeIf(item, std::move(predicate)); if (!handle) { @@ -2813,7 +2821,7 @@ CacheAllocator::evictNormalItemForSlabRelease(Item& item) { template typename CacheAllocator::WriteHandle CacheAllocator::evictChainedItemForSlabRelease(ChainedItem& child) { - XDCHECK(child.isExclusive()); + XDCHECK(child.isMoving()); // We have the child marked as moving, but dont know anything about the // state of the parent. Unlike the case of regular eviction where we are @@ -2835,7 +2843,7 @@ CacheAllocator::evictChainedItemForSlabRelease(ChainedItem& child) { // check if the child is still in mmContainer and the expected parent is // valid under the chained item lock. if (expectedParent.getKey() != parentKey || !child.isInMMContainer() || - child.isOnlyExclusive() || + child.isOnlyMoving() || &expectedParent != &child.getParentItem(compressor_) || !expectedParent.isAccessible() || !expectedParent.hasChainedItem()) { return {}; @@ -2890,14 +2898,14 @@ CacheAllocator::evictChainedItemForSlabRelease(ChainedItem& child) { // In case someone else had removed this chained item from its parent by now // So we check again to see if it has been unlinked from its parent - if (!child.isInMMContainer() || child.isOnlyExclusive()) { + if (!child.isInMMContainer() || child.isOnlyMoving()) { return {}; } // check after removing from the MMContainer that the parent is still not // being marked as moving. If parent is moving, it will release the child // item and we will wait for that. - if (parentHandle->isExclusive()) { + if (parentHandle->isMoving()) { return {}; } @@ -2930,7 +2938,7 @@ bool CacheAllocator::removeIfExpired(const ReadHandle& handle) { } template -bool CacheAllocator::markExclusiveForSlabRelease( +bool CacheAllocator::markMovingForSlabRelease( const SlabReleaseContext& ctx, void* alloc, util::Throttler& throttler) { // MemoryAllocator::processAllocForRelease will execute the callback // if the item is not already free. So there are three outcomes here: @@ -2949,7 +2957,7 @@ bool CacheAllocator::markExclusiveForSlabRelease( // Since this callback is executed, the item is not yet freed itemFreed = false; Item* item = static_cast(memory); - if (item->markExclusive()) { + if (item->markMoving()) { markedMoving = true; } }; diff --git a/cachelib/allocator/CacheAllocator.h b/cachelib/allocator/CacheAllocator.h index ed0096390..32d44c138 100644 --- a/cachelib/allocator/CacheAllocator.h +++ b/cachelib/allocator/CacheAllocator.h @@ -1308,7 +1308,7 @@ class CacheAllocator : public CacheBase { private: // wrapper around Item's refcount and active handle tracking - FOLLY_ALWAYS_INLINE void incRef(Item& it); + FOLLY_ALWAYS_INLINE bool incRef(Item& it); FOLLY_ALWAYS_INLINE RefcountWithFlags::Value decRef(Item& it); // drops the refcount and if needed, frees the allocation back to the memory @@ -1756,9 +1756,9 @@ class CacheAllocator : public CacheBase { // @return true when successfully marked as moving, // fasle when this item has already been freed - bool markExclusiveForSlabRelease(const SlabReleaseContext& ctx, - void* alloc, - util::Throttler& throttler); + bool markMovingForSlabRelease(const SlabReleaseContext& ctx, + void* alloc, + util::Throttler& throttler); // "Move" (by copying) the content in this item to another memory // location by invoking the move callback. @@ -1937,7 +1937,7 @@ class CacheAllocator : public CacheBase { } static bool parentEvictForSlabReleasePredicate(const Item& item) { - return item.getRefCount() == 1 && !item.isExclusive(); + return item.getRefCount() == 1 && !item.isMoving(); } std::unique_ptr createDeserializer(); diff --git a/cachelib/allocator/CacheItem-inl.h b/cachelib/allocator/CacheItem-inl.h index f59fa9d59..bf77b43aa 100644 --- a/cachelib/allocator/CacheItem-inl.h +++ b/cachelib/allocator/CacheItem-inl.h @@ -148,15 +148,16 @@ std::string CacheItem::toString() const { return folly::sformat( "item: " "memory={}:raw-ref={}:size={}:key={}:hex-key={}:" - "isInMMContainer={}:isAccessible={}:isExclusive={}:references={}:ctime=" + "isInMMContainer={}:isAccessible={}:isMarkedForEviction={}:" + "isMoving={}:references={}:ctime=" "{}:" "expTime={}:updateTime={}:isNvmClean={}:isNvmEvicted={}:hasChainedItem=" "{}", this, getRefCountAndFlagsRaw(), getSize(), folly::humanify(getKey().str()), folly::hexlify(getKey()), - isInMMContainer(), isAccessible(), isExclusive(), getRefCount(), - getCreationTime(), getExpiryTime(), getLastAccessTime(), isNvmClean(), - isNvmEvicted(), hasChainedItem()); + isInMMContainer(), isAccessible(), isMarkedForEviction(), isMoving(), + getRefCount(), getCreationTime(), getExpiryTime(), getLastAccessTime(), + isNvmClean(), isNvmEvicted(), hasChainedItem()); } } @@ -217,23 +218,43 @@ bool CacheItem::isInMMContainer() const noexcept { } template -bool CacheItem::markExclusive() noexcept { - return ref_.markExclusive(); +bool CacheItem::markForEviction() noexcept { + return ref_.markForEviction(); } template -RefcountWithFlags::Value CacheItem::unmarkExclusive() noexcept { - return ref_.unmarkExclusive(); +RefcountWithFlags::Value CacheItem::unmarkForEviction() noexcept { + return ref_.unmarkForEviction(); } template -bool CacheItem::isExclusive() const noexcept { - return ref_.isExclusive(); +bool CacheItem::isMarkedForEviction() const noexcept { + return ref_.isMarkedForEviction(); } template -bool CacheItem::isOnlyExclusive() const noexcept { - return ref_.isOnlyExclusive(); +bool CacheItem::markForEvictionWhenMoving() { + return ref_.markForEvictionWhenMoving(); +} + +template +bool CacheItem::markMoving() { + return ref_.markMoving(); +} + +template +RefcountWithFlags::Value CacheItem::unmarkMoving() noexcept { + return ref_.unmarkMoving(); +} + +template +bool CacheItem::isMoving() const noexcept { + return ref_.isMoving(); +} + +template +bool CacheItem::isOnlyMoving() const noexcept { + return ref_.isOnlyMoving(); } template @@ -335,7 +356,8 @@ bool CacheItem::updateExpiryTime(uint32_t expiryTimeSecs) noexcept { // check for moving to make sure we are not updating the expiry time while at // the same time re-allocating the item with the old state of the expiry time // in moveRegularItem(). See D6852328 - if (isExclusive() || !isInMMContainer() || isChainedItem()) { + if (isMoving() || isMarkedForEviction() || !isInMMContainer() || + isChainedItem()) { return false; } // attempt to atomically update the value of expiryTime @@ -451,12 +473,14 @@ std::string CacheChainedItem::toString() const { return folly::sformat( "chained item: " "memory={}:raw-ref={}:size={}:parent-compressed-ptr={}:" - "isInMMContainer={}:isAccessible={}:isExclusive={}:references={}:ctime={}" + "isInMMContainer={}:isAccessible={}:isMarkedForEviction={}:" + "isMoving={}:references={}:ctime={}" ":" "expTime={}:updateTime={}", this, Item::getRefCountAndFlagsRaw(), Item::getSize(), cPtr.getRaw(), - Item::isInMMContainer(), Item::isAccessible(), Item::isExclusive(), - Item::getRefCount(), Item::getCreationTime(), Item::getExpiryTime(), + Item::isInMMContainer(), Item::isAccessible(), + Item::isMarkedForEviction(), Item::isMoving(), Item::getRefCount(), + Item::getCreationTime(), Item::getExpiryTime(), Item::getLastAccessTime()); } diff --git a/cachelib/allocator/CacheItem.h b/cachelib/allocator/CacheItem.h index 06136db03..afee315cb 100644 --- a/cachelib/allocator/CacheItem.h +++ b/cachelib/allocator/CacheItem.h @@ -305,12 +305,17 @@ class CACHELIB_PACKED_ATTR CacheItem { */ RefcountWithFlags::Value getRefCountAndFlagsRaw() const noexcept; - FOLLY_ALWAYS_INLINE void incRef() { - if (LIKELY(ref_.incRef())) { - return; + // Increments item's ref count + // + // @return true on success, failure if item is marked as exclusive + // @throw exception::RefcountOverflow on ref count overflow + FOLLY_ALWAYS_INLINE bool incRef() { + try { + return ref_.incRef(); + } catch (exception::RefcountOverflow& e) { + throw exception::RefcountOverflow( + folly::sformat("{} item: {}", e.what(), toString())); } - throw exception::RefcountOverflow( - folly::sformat("Refcount maxed out. item: {}", toString())); } FOLLY_ALWAYS_INLINE RefcountWithFlags::Value decRef() { @@ -344,23 +349,43 @@ class CACHELIB_PACKED_ATTR CacheItem { /** * The following two functions corresond to whether or not an item is - * currently in the process of being moved. This happens during a slab - * rebalance, eviction or resize operation. + * currently in the process of being evicted. * - * An item can only be marked exclusive when `isInMMContainer` returns true. + * An item can only be marked exclusive when `isInMMContainer` returns true + * and item is not already exclusive nor moving and the ref count is 0. * This operation is atomic. * - * User can also query if an item "isOnlyExclusive". This returns true only - * if the refcount is 0 and only the exclusive bit is set. - * - * Unmarking exclusive does not depend on `isInMMContainer`. + * Unmarking exclusive does not depend on `isInMMContainer` * Unmarking exclusive will also return the refcount at the moment of * unmarking. */ - bool markExclusive() noexcept; - RefcountWithFlags::Value unmarkExclusive() noexcept; - bool isExclusive() const noexcept; - bool isOnlyExclusive() const noexcept; + bool markForEviction() noexcept; + RefcountWithFlags::Value unmarkForEviction() noexcept; + bool isMarkedForEviction() const noexcept; + + /** + * The following functions correspond to whether or not an item is + * currently in the processed of being moved. When moving, ref count + * is always >= 1. + * + * An item can only be marked moving when `isInMMContainer` returns true + * and item is not already exclusive nor moving. + * + * User can also query if an item "isOnlyMoving". This returns true only + * if the refcount is one and only the exclusive bit is set. + * + * Unmarking moving does not depend on `isInMMContainer` + * Unmarking moving will also return the refcount at the moment of + * unmarking. + */ + bool markMoving(); + RefcountWithFlags::Value unmarkMoving() noexcept; + bool isMoving() const noexcept; + bool isOnlyMoving() const noexcept; + + /** This function attempts to mark item as exclusive. + * Can only be called on the item that is moving.*/ + bool markForEvictionWhenMoving(); /** * Item cannot be marked both chained allocation and diff --git a/cachelib/allocator/Refcount.h b/cachelib/allocator/Refcount.h index c60dea34f..107e10735 100644 --- a/cachelib/allocator/Refcount.h +++ b/cachelib/allocator/Refcount.h @@ -132,32 +132,28 @@ class FOLLY_PACK_ATTR RefcountWithFlags { RefcountWithFlags& operator=(RefcountWithFlags&&) = delete; // Bumps up the reference count only if the new count will be strictly less - // than or equal to the maxCount. - // @return true if refcount is bumped. false otherwise. - FOLLY_ALWAYS_INLINE bool incRef() noexcept { - Value* const refPtr = &refCount_; - unsigned int nCASFailures = 0; - constexpr bool isWeak = false; - Value oldVal = __atomic_load_n(refPtr, __ATOMIC_RELAXED); - - while (true) { - const Value newCount = oldVal + static_cast(1); - if (UNLIKELY((oldVal & kAccessRefMask) == (kAccessRefMask))) { - return false; + // than or equal to the maxCount and the item is not exclusive + // @return true if refcount is bumped. false otherwise (if item is exclusive) + // @throw exception::RefcountOverflow if new count would be greater than + // maxCount + FOLLY_ALWAYS_INLINE bool incRef() { + auto predicate = [](const Value curValue) { + Value bitMask = getAdminRef(); + + const bool exlusiveBitIsSet = curValue & bitMask; + if (UNLIKELY((curValue & kAccessRefMask) == (kAccessRefMask))) { + throw exception::RefcountOverflow("Refcount maxed out."); } - if (__atomic_compare_exchange_n(refPtr, &oldVal, newCount, isWeak, - __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) { - return true; - } + // Check if the item is not marked for eviction + return !exlusiveBitIsSet || ((curValue & kAccessRefMask) != 0); + }; - if ((++nCASFailures % 4) == 0) { - // this pause takes up to 40 clock cycles on intel and the lock cmpxchgl - // above should take about 100 clock cycles. we pause once every 400 - // cycles or so if we are extremely unlucky. - folly::asm_volatile_pause(); - } - } + auto newValue = [](const Value curValue) { + return (curValue + static_cast(1)); + }; + + return atomicUpdateValue(predicate, newValue); } // Bumps down the reference count @@ -167,33 +163,38 @@ class FOLLY_PACK_ATTR RefcountWithFlags { // @throw RefcountUnderflow when we are trying to decremenet from 0 // refcount and have a refcount leak. FOLLY_ALWAYS_INLINE Value decRef() { - Value* const refPtr = &refCount_; - unsigned int nCASFailures = 0; - constexpr bool isWeak = false; - - Value oldVal = __atomic_load_n(refPtr, __ATOMIC_RELAXED); - while (true) { - const Value newCount = oldVal - static_cast(1); - if ((oldVal & kAccessRefMask) == 0) { + auto predicate = [](const Value curValue) { + if ((curValue & kAccessRefMask) == 0) { throw exception::RefcountUnderflow( "Trying to decRef with no refcount. RefCount Leak!"); } + return true; + }; - if (__atomic_compare_exchange_n(refPtr, &oldVal, newCount, isWeak, - __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) { - return newCount & kRefMask; - } - if ((++nCASFailures % 4) == 0) { - // this pause takes up to 40 clock cycles on intel and the lock cmpxchgl - // above should take about 100 clock cycles. we pause once every 400 - // cycles or so if we are extremely unlucky - folly::asm_volatile_pause(); - } - } + Value retValue; + auto newValue = [&retValue](const Value curValue) { + retValue = (curValue - static_cast(1)); + return retValue; + }; + + auto updated = atomicUpdateValue(predicate, newValue); + XDCHECK(updated); + + return retValue & kRefMask; } - // Return refcount excluding control bits and flags - Value getAccessRef() const noexcept { return getRaw() & kAccessRefMask; } + // Return refcount excluding moving refcount, control bits and flags. + Value getAccessRef() const noexcept { + auto raw = getRaw(); + auto accessRef = raw & kAccessRefMask; + + if ((raw & getAdminRef()) && accessRef >= 1) { + // if item is moving, ignore the extra ref + return accessRef - static_cast(1); + } else { + return accessRef; + } + } // Return access ref and the admin ref bits Value getRefWithAccessAndAdmin() const noexcept { @@ -246,65 +247,160 @@ class FOLLY_PACK_ATTR RefcountWithFlags { } /** - * The following four functions are used to track whether or not - * an item is currently in the process of being moved. This happens during a - * slab rebalance or resize operation or during eviction. + * The following two functions correspond to whether or not an item is + * currently in the process of being evicted. * - * An item can only be marked exclusive when `isInMMContainer` returns true - * and the item is not yet marked as exclusive. This operation is atomic. + * An item that is marked for eviction prevents from obtaining a handle to + * the item (incRef() will return false). This guarantees that eviction of + * marked item will always suceed. * - * User can also query if an item "isOnlyExclusive". This returns true only - * if the refcount is 0 and only the exclusive bit is set. + * An item can only be marked for eviction when `isInMMContainer` returns true + * and item does not have `kExclusive` bit set and access ref count is 0. + * This operation is atomic. * - * Unmarking exclusive does not depend on `isInMMContainer`. - * Unmarking exclusive will also return the refcount at the moment of - * unmarking. + * When item is marked for eviction, `kExclusive` bit is set and ref count is + * zero. + * + * Unmarking for eviction clears the `kExclusive` bit. `unamrkForEviction` + * does not depend on `isInMMContainer` nor `isAccessible` */ - bool markExclusive() noexcept { - Value bitMask = getAdminRef(); - Value conditionBitMask = getAdminRef(); + bool markForEviction() noexcept { + Value linkedBitMask = getAdminRef(); + Value exclusiveBitMask = getAdminRef(); - Value* const refPtr = &refCount_; - unsigned int nCASFailures = 0; - constexpr bool isWeak = false; - Value curValue = __atomic_load_n(refPtr, __ATOMIC_RELAXED); - while (true) { - const bool flagSet = curValue & conditionBitMask; - const bool alreadyExclusive = curValue & bitMask; - if (!flagSet || alreadyExclusive) { + auto predicate = [linkedBitMask, exclusiveBitMask](const Value curValue) { + const bool unlinked = !(curValue & linkedBitMask); + const bool alreadyExclusive = curValue & exclusiveBitMask; + + if (unlinked || alreadyExclusive) { return false; } - - const Value newValue = curValue | bitMask; - if (__atomic_compare_exchange_n(refPtr, &curValue, newValue, isWeak, - __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) { - XDCHECK(newValue & conditionBitMask); - return true; + if ((curValue & kAccessRefMask) != 0) { + return false; } - if ((++nCASFailures % 4) == 0) { - // this pause takes up to 40 clock cycles on intel and the lock cmpxchgl - // above should take about 100 clock cycles. we pause once every 400 - // cycles or so if we are extremely unlucky. - folly::asm_volatile_pause(); - } - } + return true; + }; + + auto newValue = [exclusiveBitMask](const Value curValue) { + return curValue | exclusiveBitMask; + }; + + return atomicUpdateValue(predicate, newValue); } - Value unmarkExclusive() noexcept { + + Value unmarkForEviction() noexcept { + XDCHECK(isMarkedForEviction()); Value bitMask = ~getAdminRef(); return __atomic_and_fetch(&refCount_, bitMask, __ATOMIC_ACQ_REL) & kRefMask; } - bool isExclusive() const noexcept { - return getRaw() & getAdminRef(); + + bool isMarkedForEviction() const noexcept { + auto raw = getRaw(); + return (raw & getAdminRef()) && ((raw & kAccessRefMask) == 0); + } + + /** + * The following functions correspond to whether or not an item is + * currently in the processed of being moved. + * + * A `moving` item cannot be recycled nor freed to the allocator. It has + * to be unmarked first. + * + * When moving, internal ref count is always >= 1 and `kExclusive` bit is set + * getRefCount does not return the extra ref (it may return 0). + * + * An item can only be marked moving when `isInMMContainer` returns true + * and does not have `kExclusive` bit set. + * + * User can also query if an item "isOnlyMoving". This returns true only + * if the refcount is one and only the exlusive bit is set. + * + * Unmarking clears `kExclusive` bit and decreses the interanl refCount by 1. + * `unmarkMoving` does does not depend on `isInMMContainer` + */ + bool markMoving() { + Value linkedBitMask = getAdminRef(); + Value exclusiveBitMask = getAdminRef(); + + auto predicate = [linkedBitMask, exclusiveBitMask](const Value curValue) { + const bool unlinked = !(curValue & linkedBitMask); + const bool alreadyExclusive = curValue & exclusiveBitMask; + + if (unlinked || alreadyExclusive) { + return false; + } + if (UNLIKELY((curValue & kAccessRefMask) == (kAccessRefMask))) { + throw exception::RefcountOverflow("Refcount maxed out."); + } + + return true; + }; + + auto newValue = [exclusiveBitMask](const Value curValue) { + // Set exclusive flag and make the ref count non-zero (to distinguish + // from exclusive case). This extra ref will not be reported to the + // user + return (curValue + static_cast(1)) | exclusiveBitMask; + }; + + return atomicUpdateValue(predicate, newValue); + } + + Value unmarkMoving() noexcept { + XDCHECK(isMoving()); + auto predicate = [](const Value curValue) { + XDCHECK((curValue & kAccessRefMask) != 0); + return true; + }; + + Value retValue; + auto newValue = [&retValue](const Value curValue) { + retValue = + (curValue - static_cast(1)) & ~getAdminRef(); + return retValue; + }; + + auto updated = atomicUpdateValue(predicate, newValue); + XDCHECK(updated); + + return retValue & kRefMask; + } + + bool isMoving() const noexcept { + auto raw = getRaw(); + return (raw & getAdminRef()) && ((raw & kAccessRefMask) != 0); + } + + /** + * This function attempts to mark item for eviction. + * Can only be called on the item that is moving. + * + * Returns true and marks the item for eviction only if item isOnlyMoving. + * Leaves the item marked as moving and returns false otherwise. + */ + bool markForEvictionWhenMoving() { + XDCHECK(isMoving()); + + auto predicate = [](const Value curValue) { + return (curValue & kAccessRefMask) == 1; + }; + + auto newValue = [](const Value curValue) { + XDCHECK((curValue & kAccessRefMask) == 1); + return (curValue - static_cast(1)); + }; + + return atomicUpdateValue(predicate, newValue); } - bool isOnlyExclusive() const noexcept { - // An item is only exclusive when its refcount is zero and only the - // exclusive bit among all the control bits is set. This indicates an item - // is exclusive to the current thread. No other thread is allowed to - // do anything with it. + + bool isOnlyMoving() const noexcept { + // An item is only moving when its refcount is one and only the exclusive + // bit among all the control bits is set. This indicates an item is already + // on its way out of cache. auto ref = getRefWithAccessAndAdmin(); - bool anyOtherBitSet = ref & ~getAdminRef(); - if (anyOtherBitSet) { + Value valueWithoutExclusiveBit = ref & ~getAdminRef(); + if (valueWithoutExclusiveBit != 1) { return false; } return ref & getAdminRef(); @@ -370,6 +466,39 @@ class FOLLY_PACK_ATTR RefcountWithFlags { } private: + /** + * Helper function to modify refCount_ atomically. + * + * If predicate(currentValue) is true, then it atomically assigns result + * of newValueF(currentValue) to refCount_ and returns true. Otherwise + * returns false and leaves refCount_ unmodified. + */ + template + bool atomicUpdateValue(P&& predicate, F&& newValueF) { + Value* const refPtr = &refCount_; + unsigned int nCASFailures = 0; + constexpr bool isWeak = false; + Value curValue = __atomic_load_n(refPtr, __ATOMIC_RELAXED); + while (true) { + if (!predicate(curValue)) { + return false; + } + + const Value newValue = newValueF(curValue); + if (__atomic_compare_exchange_n(refPtr, &curValue, newValue, isWeak, + __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) { + return true; + } + + if ((++nCASFailures % 4) == 0) { + // this pause takes up to 40 clock cycles on intel and the lock cmpxchgl + // above should take about 100 clock cycles. we pause once every 400 + // cycles or so if we are extremely unlucky. + folly::asm_volatile_pause(); + } + } + } + template static Value getFlag() noexcept { static_assert(flagBit >= kNumAccessRefBits + kNumAdminRefBits, diff --git a/cachelib/allocator/tests/ItemTest.cpp b/cachelib/allocator/tests/ItemTest.cpp index b0f3a2fde..70dd1277f 100644 --- a/cachelib/allocator/tests/ItemTest.cpp +++ b/cachelib/allocator/tests/ItemTest.cpp @@ -83,10 +83,20 @@ TEST(ItemTest, ExpiryTime) { EXPECT_EQ(tenMins, item->getConfiguredTTL()); // Test that writes fail while the item is moving - item->markExclusive(); + result = item->markMoving(); + EXPECT_TRUE(result); + result = item->updateExpiryTime(0); + EXPECT_FALSE(result); + item->unmarkMoving(); + + // Test that writes fail while the item is marked for eviction + item->markAccessible(); + result = item->markForEviction(); + EXPECT_TRUE(result); result = item->updateExpiryTime(0); EXPECT_FALSE(result); - item->unmarkExclusive(); + item->unmarkForEviction(); + item->unmarkAccessible(); // Test that writes fail while the item is not in an MMContainer item->unmarkInMMContainer(); diff --git a/cachelib/allocator/tests/RefCountTest.cpp b/cachelib/allocator/tests/RefCountTest.cpp index b355a48a8..1f31894dd 100644 --- a/cachelib/allocator/tests/RefCountTest.cpp +++ b/cachelib/allocator/tests/RefCountTest.cpp @@ -30,6 +30,7 @@ class RefCountTest : public AllocTestBase { public: static void testMultiThreaded(); static void testBasic(); + static void testMarkForEvictionAndMoving(); }; void RefCountTest::testMultiThreaded() { @@ -81,7 +82,7 @@ void RefCountTest::testBasic() { ASSERT_EQ(0, ref.getRaw()); ASSERT_FALSE(ref.isInMMContainer()); ASSERT_FALSE(ref.isAccessible()); - ASSERT_FALSE(ref.isExclusive()); + ASSERT_FALSE(ref.isMoving()); ASSERT_FALSE(ref.template isFlagSet()); ASSERT_FALSE(ref.template isFlagSet()); @@ -89,7 +90,7 @@ void RefCountTest::testBasic() { ref.markInMMContainer(); ASSERT_TRUE(ref.isInMMContainer()); ASSERT_FALSE(ref.isAccessible()); - ASSERT_FALSE(ref.isExclusive()); + ASSERT_FALSE(ref.isMoving()); ASSERT_EQ(0, ref.getAccessRef()); ASSERT_FALSE(ref.template isFlagSet()); ASSERT_FALSE(ref.template isFlagSet()); @@ -105,13 +106,13 @@ void RefCountTest::testBasic() { // Incrementing past the max will fail auto rawRef = ref.getRaw(); - ASSERT_FALSE(ref.incRef()); + ASSERT_THROW(ref.incRef(), std::overflow_error); ASSERT_EQ(rawRef, ref.getRaw()); // Bumping up access ref shouldn't affect admin ref and flags ASSERT_TRUE(ref.isInMMContainer()); ASSERT_FALSE(ref.isAccessible()); - ASSERT_FALSE(ref.isExclusive()); + ASSERT_FALSE(ref.isMoving()); ASSERT_EQ(RefcountWithFlags::kAccessRefMask, ref.getAccessRef()); ASSERT_TRUE(ref.template isFlagSet()); ASSERT_FALSE(ref.template isFlagSet()); @@ -128,7 +129,7 @@ void RefCountTest::testBasic() { // Bumping down access ref shouldn't affect admin ref and flags ASSERT_TRUE(ref.isInMMContainer()); ASSERT_FALSE(ref.isAccessible()); - ASSERT_FALSE(ref.isExclusive()); + ASSERT_FALSE(ref.isMoving()); ASSERT_EQ(0, ref.getAccessRef()); ASSERT_TRUE(ref.template isFlagSet()); ASSERT_FALSE(ref.template isFlagSet()); @@ -136,7 +137,7 @@ void RefCountTest::testBasic() { ref.template unSetFlag(); ASSERT_TRUE(ref.isInMMContainer()); ASSERT_FALSE(ref.isAccessible()); - ASSERT_FALSE(ref.isExclusive()); + ASSERT_FALSE(ref.isMoving()); ASSERT_EQ(0, ref.getAccessRef()); ASSERT_FALSE(ref.template isFlagSet()); ASSERT_FALSE(ref.template isFlagSet()); @@ -145,33 +146,104 @@ void RefCountTest::testBasic() { ASSERT_EQ(0, ref.getRaw()); ASSERT_FALSE(ref.isInMMContainer()); ASSERT_FALSE(ref.isAccessible()); - ASSERT_FALSE(ref.isExclusive()); + ASSERT_FALSE(ref.isMoving()); ASSERT_EQ(0, ref.getAccessRef()); ASSERT_FALSE(ref.template isFlagSet()); ASSERT_FALSE(ref.template isFlagSet()); // conditionally set flags - ASSERT_FALSE((ref.markExclusive())); + ASSERT_FALSE((ref.markMoving())); ref.markInMMContainer(); - ASSERT_TRUE((ref.markExclusive())); - ASSERT_FALSE((ref.isOnlyExclusive())); + // only first one succeeds + ASSERT_TRUE((ref.markMoving())); + ASSERT_FALSE((ref.markMoving())); ref.unmarkInMMContainer(); + ref.template setFlag(); - // Have no other admin refcount but with a flag still means "isOnlyExclusive" - ASSERT_TRUE((ref.isOnlyExclusive())); + // Have no other admin refcount but with a flag still means "isOnlyMoving" + ASSERT_TRUE((ref.isOnlyMoving())); - // Set some flags and verify that "isOnlyExclusive" does not care about flags + // Set some flags and verify that "isOnlyMoving" does not care about flags ref.markIsChainedItem(); ASSERT_TRUE(ref.isChainedItem()); - ASSERT_TRUE((ref.isOnlyExclusive())); + ASSERT_TRUE((ref.isOnlyMoving())); ref.unmarkIsChainedItem(); ASSERT_FALSE(ref.isChainedItem()); - ASSERT_TRUE((ref.isOnlyExclusive())); + ASSERT_TRUE((ref.isOnlyMoving())); +} + +void RefCountTest::testMarkForEvictionAndMoving() { + { + // cannot mark for eviction when not in MMContainer + RefcountWithFlags ref; + ASSERT_FALSE(ref.markForEviction()); + } + + { + // can mark for eviction when in MMContainer + // and unmarkForEviction return value contains admin bits + RefcountWithFlags ref; + ref.markInMMContainer(); + ASSERT_TRUE(ref.markForEviction()); + ASSERT_TRUE(ref.unmarkForEviction() > 0); + } + + { + // cannot mark for eviction when moving + RefcountWithFlags ref; + ref.markInMMContainer(); + + ASSERT_TRUE(ref.markMoving()); + ASSERT_FALSE(ref.markForEviction()); + + ref.unmarkInMMContainer(); + auto ret = ref.unmarkMoving(); + ASSERT_EQ(ret, 0); + } + + { + // cannot mark moving when marked for eviction + RefcountWithFlags ref; + ref.markInMMContainer(); + + ASSERT_TRUE(ref.markForEviction()); + ASSERT_FALSE(ref.markMoving()); + + ref.unmarkInMMContainer(); + auto ret = ref.unmarkForEviction(); + ASSERT_EQ(ret, 0); + } + + { + // can mark moving when ref count > 0 + RefcountWithFlags ref; + ref.markInMMContainer(); + + ref.incRef(); + + ASSERT_TRUE(ref.markMoving()); + + ref.unmarkInMMContainer(); + auto ret = ref.unmarkMoving(); + ASSERT_EQ(ret, 1); + } + + { + // cannot mark for eviction when ref count > 0 + RefcountWithFlags ref; + ref.markInMMContainer(); + + ref.incRef(); + ASSERT_FALSE(ref.markForEviction()); + } } } // namespace TEST_F(RefCountTest, MutliThreaded) { testMultiThreaded(); } TEST_F(RefCountTest, Basic) { testBasic(); } +TEST_F(RefCountTest, MarkForEvictionAndMoving) { + testMarkForEvictionAndMoving(); +} } // namespace tests } // namespace cachelib } // namespace facebook From 0bdb93505ef6cb86ea0950a3889ee2dacf066cb0 Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Thu, 9 Mar 2023 08:10:36 -0800 Subject: [PATCH 40/92] fbcode/cachelib/allocator/serialize Differential Revision: D43869057 fbshipit-source-id: 84aa3aec8d75f04b640d6aa8393002190c97842f --- cachelib/allocator/serialize/objects.thrift | 138 ++++++++++---------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/cachelib/allocator/serialize/objects.thrift b/cachelib/allocator/serialize/objects.thrift index 8d30ee8d8..61297cdf1 100644 --- a/cachelib/allocator/serialize/objects.thrift +++ b/cachelib/allocator/serialize/objects.thrift @@ -23,136 +23,136 @@ include "cachelib/allocator/datastruct/serialize/objects.thrift" // make sure to communicate that with our users. struct CacheAllocatorMetadata { - 1: required i64 allocatorVersion, // version of cache alloctor - 2: i64 cacheCreationTime = 0, // time when the cache was created. - 3: required i64 accessType = 0, // default chained alloc - 4: required i64 mmType = 0, // default LRU - 5: map> fragmentationSize, - 6: list compactCachePools, - 7: i64 numPermanentItems, - 8: i64 numChainedParentItems, - 9: i64 numChainedChildItems, - 10: i64 ramFormatVersion = 0, // format version of ram cache - 11: i64 numAbortedSlabReleases = 0, // number of times slab release is aborted + 1: required i64 allocatorVersion; // version of cache alloctor + 2: i64 cacheCreationTime = 0; // time when the cache was created. + 3: required i64 accessType = 0; // default chained alloc + 4: required i64 mmType = 0; // default LRU + 5: map> fragmentationSize; + 6: list compactCachePools; + 7: i64 numPermanentItems; + 8: i64 numChainedParentItems; + 9: i64 numChainedChildItems; + 10: i64 ramFormatVersion = 0; // format version of ram cache + 11: i64 numAbortedSlabReleases = 0; // number of times slab release is aborted } struct NvmCacheMetadata { - 1: i64 nvmFormatVersion = 0, - 2: i64 creationTime = 0, - 3: bool safeShutDown = false, - 4: bool encryptionEnabled = false, - 5: bool truncateAllocSize = false, + 1: i64 nvmFormatVersion = 0; + 2: i64 creationTime = 0; + 3: bool safeShutDown = false; + 4: bool encryptionEnabled = false; + 5: bool truncateAllocSize = false; } struct CompactCacheMetadataObject { - 1: required i64 keySize, - 2: required i64 valueSize, + 1: required i64 keySize; + 2: required i64 valueSize; } struct CompactCacheAllocatorObject { - 1: required list chunks, - 2: required CompactCacheMetadataObject ccMetadata, + 1: required list chunks; + 2: required CompactCacheMetadataObject ccMetadata; } struct CompactCacheAllocatorManagerObject { - 1: required map allocators, + 1: required map allocators; } struct MMLruConfig { - 1: required i32 lruRefreshTime, - 2: required bool updateOnWrite, - 3: required i32 lruInsertionPointSpec, - 4: bool updateOnRead = true, - 5: bool tryLockUpdate = false, - 6: double lruRefreshRatio = 0.0, + 1: required i32 lruRefreshTime; + 2: required bool updateOnWrite; + 3: required i32 lruInsertionPointSpec; + 4: bool updateOnRead = true; + 5: bool tryLockUpdate = false; + 6: double lruRefreshRatio = 0.0; } struct MMLruObject { - 1: required MMLruConfig config, + 1: required MMLruConfig config; // number of evictions for this MM object. - 5: i64 evictions = 0, + 5: i64 evictions = 0; - 6: required i64 insertionPoint, - 7: required i64 tailSize, - 8: required DListObject lru, - 9: required i64 compressedInsertionPoint, + 6: required i64 insertionPoint; + 7: required i64 tailSize; + 8: required DListObject lru; + 9: required i64 compressedInsertionPoint; } struct MMLruCollection { - 1: required map> pools, + 1: required map> pools; } struct MM2QConfig { - 1: required i32 lruRefreshTime, - 2: required bool updateOnWrite, - 3: required i32 hotSizePercent, - 4: required i32 coldSizePercent, - 5: bool updateOnRead = true, - 6: bool tryLockUpdate = false, - 7: bool rebalanceOnRecordAccess = true, - 8: double lruRefreshRatio = 0.0, + 1: required i32 lruRefreshTime; + 2: required bool updateOnWrite; + 3: required i32 hotSizePercent; + 4: required i32 coldSizePercent; + 5: bool updateOnRead = true; + 6: bool tryLockUpdate = false; + 7: bool rebalanceOnRecordAccess = true; + 8: double lruRefreshRatio = 0.0; } struct MM2QObject { - 1: required MM2QConfig config, - 13: bool tailTrackingEnabled = false, + 1: required MM2QConfig config; + 13: bool tailTrackingEnabled = false; // number of evictions for this MM object. - 11: i64 evictions = 0, + 11: i64 evictions = 0; // Warm, hot and cold lrus - 12: required MultiDListObject lrus, + 12: required MultiDListObject lrus; } struct MM2QCollection { - 1: required map> pools, + 1: required map> pools; } struct MMTinyLFUConfig { - 1: required i32 lruRefreshTime, - 2: required bool updateOnWrite, - 3: required i32 windowToCacheSizeRatio, - 4: required i32 tinySizePercent, - 5: bool updateOnRead = true, - 6: bool tryLockUpdate = false, - 7: double lruRefreshRatio = 0.0, + 1: required i32 lruRefreshTime; + 2: required bool updateOnWrite; + 3: required i32 windowToCacheSizeRatio; + 4: required i32 tinySizePercent; + 5: bool updateOnRead = true; + 6: bool tryLockUpdate = false; + 7: double lruRefreshRatio = 0.0; } struct MMTinyLFUObject { - 1: required MMTinyLFUConfig config, + 1: required MMTinyLFUConfig config; // number of evictions for this MM object. - 2: i64 evictions = 0, + 2: i64 evictions = 0; // Warm, hot and cold lrus - 3: required MultiDListObject lrus, + 3: required MultiDListObject lrus; } struct MMTinyLFUCollection { - 1: required map> pools, + 1: required map> pools; } struct ChainedHashTableObject { // fields in ChainedHashTable::Config - 1: required i32 bucketsPower, - 2: required i32 locksPower, - 3: i64 numKeys, + 1: required i32 bucketsPower; + 2: required i32 locksPower; + 3: i64 numKeys; // this magic id ensures on a warm roll, user cannot // start the cache with a different hash function - 4: i32 hasherMagicId = 0, + 4: i32 hasherMagicId = 0; } struct MMTTLBucketObject { - 4: i64 expirationTime, - 5: i64 creationTime, - 6: required DListObject dList, + 4: i64 expirationTime; + 5: i64 creationTime; + 6: required DListObject dList; } struct TTLBucketCollection { - 1: required map buckets, - 2: i64 minEpoch = 0, - 3: i64 maxTTL = 0, - 4: i64 interval = 0, + 1: required map buckets; + 2: i64 minEpoch = 0; + 3: i64 maxTTL = 0; + 4: i64 interval = 0; } From 99a05d35a3ed9a782262160e9e2119b90a41f86e Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Thu, 9 Mar 2023 08:16:02 -0800 Subject: [PATCH 41/92] fbcode/cachelib/experimental/objcache Differential Revision: D43869089 fbshipit-source-id: 57d359fa8cfeaca395f636f6d3997a934afca94a --- .../objcache/ObjectCachePersistence.thrift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cachelib/experimental/objcache/ObjectCachePersistence.thrift b/cachelib/experimental/objcache/ObjectCachePersistence.thrift index fcddb82ef..e5acba4d5 100644 --- a/cachelib/experimental/objcache/ObjectCachePersistence.thrift +++ b/cachelib/experimental/objcache/ObjectCachePersistence.thrift @@ -17,9 +17,9 @@ namespace cpp2 facebook.cachelib.objcache.serialization struct Item { - 1: byte poolId - 2: i32 creationTime, - 3: i32 expiryTime, - 4: string key, - 5: string payload, + 1: byte poolId; + 2: i32 creationTime; + 3: i32 expiryTime; + 4: string key; + 5: string payload; } From d1ff29c61115f5eebc20984b22a9e67a10adc488 Mon Sep 17 00:00:00 2001 From: generatedunixname226714639793621 Date: Fri, 10 Mar 2023 08:09:44 -0800 Subject: [PATCH 42/92] fbcode/cachelib/ Differential Revision: D43904241 fbshipit-source-id: 3d7484bee3a62495b2f2ee299fd3b0b855a3be58 --- cachelib/shm/shm.thrift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cachelib/shm/shm.thrift b/cachelib/shm/shm.thrift index 0372d7c8f..702294722 100644 --- a/cachelib/shm/shm.thrift +++ b/cachelib/shm/shm.thrift @@ -17,6 +17,6 @@ namespace cpp2 facebook.cachelib.serialization struct ShmManagerObject { - 1: required byte shmVal, - 3: required map nameToKeyMap, + 1: required byte shmVal; + 3: required map nameToKeyMap; } From 3a8d8b4ad3cb5f6221b19f971b15092bcb0617e8 Mon Sep 17 00:00:00 2001 From: Jiayue Bao Date: Mon, 13 Mar 2023 09:25:25 -0700 Subject: [PATCH 43/92] Add extra notes for object-cache find APIs Summary: Putting extra note of separating read/write traffic when using find APIs. Reviewed By: jaesoo-fb Differential Revision: D43960690 fbshipit-source-id: 56d3a8b65c7b66b3319bee6e7ffdd959826c8dcf --- website/docs/Cache_Library_User_Guides/eviction_policy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/Cache_Library_User_Guides/eviction_policy.md b/website/docs/Cache_Library_User_Guides/eviction_policy.md index 356a3cb19..cce947619 100644 --- a/website/docs/Cache_Library_User_Guides/eviction_policy.md +++ b/website/docs/Cache_Library_User_Guides/eviction_policy.md @@ -23,7 +23,7 @@ The second modification is promotion delay. Normally every access item is moved How often does cachelib refresh a previously accessed item. By default this is 60 seconds. * `updateOnWrite`/`updateOnRead` -Specifies if a LRU promotion happens on read or write or both. As a rule of thumb, for most services that care primarily about read performance, turn on `updateOnRead`. However, if your service cares a lot about retention time of items that are recently written, then turn on `updateOnWrite` as well. +Specifies if a LRU promotion happens on read or write or both. As a rule of thumb, for most services that care primarily about read performance, turn on `updateOnRead`. However, if your service cares a lot about retention time of items that are recently written, then turn on `updateOnWrite` as well. By default, `updateOnRead = true` and `updateOnWrite = false`. * `ipSpec` This essentially turns the LRU into a two-segmented LRU. Setting this to `1` means every new insertion will be inserted 1/2 from the end of the LRU, `2` means 1/4 from the end of the LRU, and so on. From e0350ffaa9219608deee6a644e360e0ac5dbb6ab Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Thu, 16 Mar 2023 08:58:16 -0700 Subject: [PATCH 44/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/cachelib/commit/3a8d8b4ad3cb5f6221b19f971b15092bcb0617e8 https://github.com/facebook/fb303/commit/14f3fe46ad17507566ff548af434cd8dd48e77e0 https://github.com/facebook/fbthrift/commit/0dd3ae758c42c05dc36f80c80c70256296fbaf38 https://github.com/facebook/folly/commit/c566c5821e8a5a2020fa752bc81791d2e5318a99 https://github.com/facebook/litho/commit/3e36498bd9c4d03adbd254ee2e8deff40a72b820 https://github.com/facebook/mcrouter/commit/009a445b8d8968885129a6644e6f4227da0fd119 https://github.com/facebook/ocamlrep/commit/67f2dd5513a9e5e429bc06008fdecf48d6edbf85 https://github.com/facebook/proxygen/commit/8e65cb443405cac707f923b92ede1662398609e0 https://github.com/facebook/rocksdb/commit/ccaa3225b0211d8ab6c48cda9e37f0e0f876f6ff https://github.com/facebook/squangle/commit/95df6767f18a5855fa4db00c22edb7ce5d445afe https://github.com/facebook/wangle/commit/3ef97c73473cc90c6a87757cc7a987e7a4bb2d4c https://github.com/facebook/watchman/commit/25d3c50287cc3bb0998de4b49d65497af396c38b https://github.com/facebookexperimental/edencommon/commit/748239e8ddc01031a36c67942c81f8629bae31b0 https://github.com/facebookexperimental/rust-shed/commit/2b7d2725f8153fe01c87121633035873067cb36c https://github.com/facebookincubator/conversionsapi-tag-for-googletagmanager/commit/0e047c2874d94adc75362537075914bfcdead490 https://github.com/facebookincubator/fizz/commit/cd4dfb08e1fd566bf14b5ad8b341d1efaec9b87a https://github.com/facebookincubator/katran/commit/c46afd52ed6a471ec2b1785cecb4acde5c20339a https://github.com/facebookincubator/mvfst/commit/974e095abb20ec172d90046f78026d3869932999 https://github.com/facebookincubator/superconsole/commit/b8046de038ba40327ec218f704caad06ab51cdaa https://github.com/facebookincubator/velox/commit/c42568b2b5108eab81494d16f0398fef16d0ebba https://github.com/facebookresearch/multimodal/commit/ea503752b79fe6feb67aa96fcbebce20a6d1448e https://github.com/facebookresearch/recipes/commit/a686044d8db6b0908a7fd64f5294b0294f8ac34b https://github.com/facebookresearch/vrs/commit/7caabf09bec364c05b3116c5f0632648eb9af15c https://github.com/fairinternal/egohowto/commit/145ebd9f48095d91cf34180d90e18e329d9d8ac6 https://github.com/pytorch/fbgemm/commit/ae6235bc4b521102155fad4b54f92df34b5a6afe https://github.com/pytorch/kineto/commit/df9329b105818c9ba5149e32b459cc4ebd9521cc Reviewed By: jurajh-fb fbshipit-source-id: 55993c5132fe0451f2e0eb68946891d8ad9648d8 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index cbc3de581..0dd3ae758 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit cbc3de581fdf36ba474b0c135b9e785e504f1c1e +Subproject commit 0dd3ae758c42c05dc36f80c80c70256296fbaf38 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 287625bd6..cd4dfb08e 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 287625bd6676b812e75ad0b088a61f72b4c9e681 +Subproject commit cd4dfb08e1fd566bf14b5ad8b341d1efaec9b87a diff --git a/cachelib/external/folly b/cachelib/external/folly index ce2b95715..c566c5821 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit ce2b95715de229fcb51bd97410469a3ad4d2bfb2 +Subproject commit c566c5821e8a5a2020fa752bc81791d2e5318a99 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 44690e789..3ef97c734 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 44690e7894842a7127245837b69627d4b964aabd +Subproject commit 3ef97c73473cc90c6a87757cc7a987e7a4bb2d4c From 8b98b6e1fee2e40b88c9bd62a61ded478831227b Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Thu, 16 Mar 2023 14:22:01 -0700 Subject: [PATCH 45/92] added PoolRebalancer stats for the loop Summary: This change adds following ODS stats for PoolRebalancer worker. * rebalancer.runs * rebalancer.rebalanced_slabs * rebalancer.latency.loop_last_ms * rebalancer.latency.loop_avg_ms * rebalancer.latency.release_last_ms * rebalancer.latency.release_avg_ms * rebalancer.latency.pick_last_ms * rebalancer.latency.pick_avg_ms Reviewed By: therealgymmy Differential Revision: D43951006 fbshipit-source-id: e4e7f720795990acd6529a9cdcdd884cb9d5057b --- cachelib/allocator/Cache.cpp | 19 +++++++++++++++++ cachelib/allocator/CacheAllocator-inl.h | 1 + cachelib/allocator/CacheAllocator.h | 7 +++++++ cachelib/allocator/CacheStats.h | 19 +++++++++++++++++ cachelib/allocator/PoolRebalancer.cpp | 27 ++++++++++++++++++++++++ cachelib/allocator/PoolRebalancer.h | 28 +++++++++++++++++++++++++ 6 files changed, 101 insertions(+) diff --git a/cachelib/allocator/Cache.cpp b/cachelib/allocator/Cache.cpp index 5c228ed7b..749457798 100644 --- a/cachelib/allocator/Cache.cpp +++ b/cachelib/allocator/Cache.cpp @@ -284,6 +284,25 @@ void CacheBase::updateGlobalCacheStats(const std::string& statPrefix) const { counters_.updateDelta(statPrefix + "reaper.skipped_slabs", stats.numReaperSkippedSlabs); + counters_.updateDelta(statPrefix + "rebalancer.runs", + stats.rebalancerStats.numRuns); + counters_.updateDelta(statPrefix + "rebalancer.rebalanced_slabs", + stats.rebalancerStats.numRebalancedSlabs); + counters_.updateCount(statPrefix + "rebalancer.latency.loop_last_ms", + stats.rebalancerStats.lastRebalanceTimeMs); + counters_.updateCount(statPrefix + "rebalancer.latency.loop_avg_ms", + stats.rebalancerStats.avgRebalanceTimeMs); + + counters_.updateCount(statPrefix + "rebalancer.latency.release_last_ms", + stats.rebalancerStats.lastReleaseTimeMs); + counters_.updateCount(statPrefix + "rebalancer.latency.release_avg_ms", + stats.rebalancerStats.avgReleaseTimeMs); + + counters_.updateCount(statPrefix + "rebalancer.latency.pick_last_ms", + stats.rebalancerStats.lastPickTimeMs); + counters_.updateCount(statPrefix + "rebalancer.latency.pick_avg_ms", + stats.rebalancerStats.avgPickTimeMs); + const auto slabReleaseStats = getSlabReleaseStats(); counters_.updateDelta(statPrefix + "slabs.rebalancer_runs", slabReleaseStats.numSlabReleaseForRebalanceAttempts); diff --git a/cachelib/allocator/CacheAllocator-inl.h b/cachelib/allocator/CacheAllocator-inl.h index b8d0256d5..5c0ddbbea 100644 --- a/cachelib/allocator/CacheAllocator-inl.h +++ b/cachelib/allocator/CacheAllocator-inl.h @@ -3411,6 +3411,7 @@ GlobalCacheStats CacheAllocator::getGlobalCacheStats() const { ret.nvmUpTime = currTime - nvmCacheState_.getCreationTime(); ret.nvmCacheEnabled = nvmCache_ ? nvmCache_->isEnabled() : false; ret.reaperStats = getReaperStats(); + ret.rebalancerStats = getRebalancerStats(); ret.numActiveHandles = getNumActiveHandles(); ret.isNewRamCache = cacheCreationTime_ == cacheInstanceCreationTime_; diff --git a/cachelib/allocator/CacheAllocator.h b/cachelib/allocator/CacheAllocator.h index 32d44c138..692f42bec 100644 --- a/cachelib/allocator/CacheAllocator.h +++ b/cachelib/allocator/CacheAllocator.h @@ -1146,6 +1146,13 @@ class CacheAllocator : public CacheBase { return stats; } + // returns the pool rebalancer stats + RebalancerStats getRebalancerStats() const { + auto stats = + poolRebalancer_ ? poolRebalancer_->getStats() : RebalancerStats{}; + return stats; + } + // return the LruType of an item typename MMType::LruType getItemLruType(const Item& item) const; diff --git a/cachelib/allocator/CacheStats.h b/cachelib/allocator/CacheStats.h index fb9955b80..b51be687a 100644 --- a/cachelib/allocator/CacheStats.h +++ b/cachelib/allocator/CacheStats.h @@ -289,6 +289,22 @@ struct ReaperStats { uint64_t avgTraversalTimeMs{0}; }; +// Stats for reaper +struct RebalancerStats { + uint64_t numRuns{0}; + + uint64_t numRebalancedSlabs{0}; + + uint64_t lastRebalanceTimeMs{0}; + uint64_t avgRebalanceTimeMs{0}; + + uint64_t lastReleaseTimeMs{0}; + uint64_t avgReleaseTimeMs{0}; + + uint64_t lastPickTimeMs{0}; + uint64_t avgPickTimeMs{0}; +}; + // CacheMetadata type to export struct CacheMetadata { // allocator_version @@ -494,6 +510,9 @@ struct GlobalCacheStats { // stats related to the reaper ReaperStats reaperStats; + // stats related to the pool rebalancer + RebalancerStats rebalancerStats; + uint64_t numNvmRejectsByExpiry{}; uint64_t numNvmRejectsByClean{}; uint64_t numNvmRejectsByAP{}; diff --git a/cachelib/allocator/PoolRebalancer.cpp b/cachelib/allocator/PoolRebalancer.cpp index 6c963c80b..ff1c2a46d 100644 --- a/cachelib/allocator/PoolRebalancer.cpp +++ b/cachelib/allocator/PoolRebalancer.cpp @@ -103,6 +103,8 @@ RebalanceContext PoolRebalancer::pickVictimByFreeAlloc(PoolId pid) const { } bool PoolRebalancer::tryRebalancing(PoolId pid, RebalanceStrategy& strategy) { + const auto begin = util::getCurrentTimeMs(); + if (freeAllocThreshold_ > 0) { auto ctx = pickVictimByFreeAlloc(pid); if (ctx.victimClassId != Slab::kInvalidClassId) { @@ -114,16 +116,41 @@ bool PoolRebalancer::tryRebalancing(PoolId pid, RebalanceStrategy& strategy) { return false; } + auto currentTimeSec = util::getCurrentTimeMs(); const auto context = strategy.pickVictimAndReceiver(cache_, pid); + auto end = util::getCurrentTimeMs(); + pickVictimStats_.recordLoopTime(end > currentTimeSec ? end - currentTimeSec + : 0); + if (context.victimClassId == Slab::kInvalidClassId) { XLOGF(DBG, "Pool Id: {} rebalancing strategy didn't find an victim", static_cast(pid)); return false; } + currentTimeSec = util::getCurrentTimeMs(); releaseSlab(pid, context.victimClassId, context.receiverClassId); + end = util::getCurrentTimeMs(); + releaseStats_.recordLoopTime(end > currentTimeSec ? end - currentTimeSec : 0); + rebalanceStats_.recordLoopTime(end > begin ? end - begin : 0); + return true; } +RebalancerStats PoolRebalancer::getStats() const noexcept { + RebalancerStats stats; + stats.numRuns = getRunCount(); + stats.numRebalancedSlabs = rebalanceStats_.getNumLoops(); + stats.lastRebalanceTimeMs = rebalanceStats_.getLastLoopTimeMs(); + stats.avgRebalanceTimeMs = rebalanceStats_.getAvgLoopTimeMs(); + + stats.lastReleaseTimeMs = releaseStats_.getLastLoopTimeMs(); + stats.avgReleaseTimeMs = releaseStats_.getAvgLoopTimeMs(); + + stats.lastPickTimeMs = pickVictimStats_.getLastLoopTimeMs(); + stats.avgPickTimeMs = pickVictimStats_.getAvgLoopTimeMs(); + return stats; +} + } // namespace cachelib } // namespace facebook diff --git a/cachelib/allocator/PoolRebalancer.h b/cachelib/allocator/PoolRebalancer.h index 4a3ee1463..4238aacea 100644 --- a/cachelib/allocator/PoolRebalancer.h +++ b/cachelib/allocator/PoolRebalancer.h @@ -53,7 +53,30 @@ class PoolRebalancer : public PeriodicWorker { return stats_.getSlabReleaseEvents(pid); } + RebalancerStats getStats() const noexcept; + private: + struct LoopStats { + // record the count and the time taken + void recordLoopTime(uint64_t msTaken) { + numLoops_.fetch_add(1, std::memory_order_relaxed); + lastLoopTimeMs_.store(msTaken, std::memory_order_relaxed); + totalLoopTimeMs_.fetch_add(msTaken, std::memory_order_relaxed); + } + + uint64_t getAvgLoopTimeMs() const { + return numLoops_ ? totalLoopTimeMs_ / numLoops_ : 0; + } + uint64_t getLastLoopTimeMs() const { return lastLoopTimeMs_; } + uint64_t getNumLoops() const { return numLoops_; } + + private: + // time it took us the last time and the average + std::atomic lastLoopTimeMs_{0}; + std::atomic totalLoopTimeMs_{0}; + std::atomic numLoops_{0}; + }; + // This will attempt to rebalance by // 1. reading the stats from the cache allocator // 2. analyzing the stats by using the rebalance strategy @@ -86,6 +109,11 @@ class PoolRebalancer : public PeriodicWorker { // slab release stats for this rebalancer. ReleaseStats stats_; + // loop timing stats + LoopStats rebalanceStats_; + LoopStats releaseStats_; + LoopStats pickVictimStats_; + // implements the actual logic of running tryRebalancing and // updating the stats void work() final; From c90dd1d35b6ba984d747542d79598e4397038fb9 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Thu, 16 Mar 2023 16:37:28 -0700 Subject: [PATCH 46/92] WorkloadGenerator: fixed a bug in scaling key popularity distribution Summary: There was a bug in scaling the number of keys in WorkloadGenerator. Particularly, even when user wants to scale the number of keys larger than the sum of the number of keys in the popDistFile, the generated key population is a lot less than specified, but only close to the sum in popDistFile. This is due to the bug in FastDiscreteDistribution. Specifically, when it initializes the popularity buckets and the weights, there was a bug not initializing the key offset of bucket correctly; it was not considering the scaling factor into account. This change fixes the bug. Reviewed By: therealgymmy Differential Revision: D44144006 fbshipit-source-id: 1391b63b319598ac9d3e1307a86ad22b550bc2eb --- cachelib/cachebench/workload/FastDiscrete.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cachelib/cachebench/workload/FastDiscrete.h b/cachelib/cachebench/workload/FastDiscrete.h index 7c4341b37..ca0448547 100644 --- a/cachelib/cachebench/workload/FastDiscrete.h +++ b/cachelib/cachebench/workload/FastDiscrete.h @@ -107,9 +107,12 @@ class FastDiscreteDistribution final : public Distribution { sizes[i] -= facebook::cachelib::util::narrow_cast(bucketPct * sizes[i]); probs[i] -= bucketPct * probs[i]; - buckets.push_back(static_cast(objectsSeen * scalingFactor_)); + + auto scaledObjects = + static_cast(objectsSeen * scalingFactor_); + buckets.push_back(scaledObjects); if (bucketOffsets_.size() > 0) { - bucketOffsets_.push_back(bucketOffsets_.back() + objectsSeen); + bucketOffsets_.push_back(bucketOffsets_.back() + scaledObjects); } weightSeen = 0.0; objectsSeen = 0; From ecc68cbc7270438b7e74d958e31dec6ba46b510b Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Thu, 16 Mar 2023 16:51:34 -0700 Subject: [PATCH 47/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/cachelib/commit/8b98b6e1fee2e40b88c9bd62a61ded478831227b https://github.com/facebook/fb303/commit/dea5d002e3911cb251111d1dfc8834242214d523 https://github.com/facebook/fbthrift/commit/ab5dd63a065b47a44223f8f90c71317109ea75cd https://github.com/facebook/folly/commit/e288b430e59df666ae4a54608ea912999010d118 https://github.com/facebook/litho/commit/412ca44112d6def586b2f26d0c8b94eac1196388 https://github.com/facebook/mcrouter/commit/3b31830856d1230096b2a23c6b48e9c7de928965 https://github.com/facebook/proxygen/commit/b663997565fcd8027fb65adc740c67d228ba7e7b https://github.com/facebook/wangle/commit/30304c925a406ef9f63df718808ba3b253813f97 https://github.com/facebook/watchman/commit/1a5e610e5fa7dac2647fedc8fdc738675fd1b70b https://github.com/facebookexperimental/edencommon/commit/4c30e6e99067c17c363a337a92a3fdc780dc0a8f https://github.com/facebookexperimental/rust-shed/commit/349a3c61780fad70924e0d490d5087da21de5b6e https://github.com/facebookincubator/fizz/commit/b35b6da5bd4060f84e01c316010467de1ad1e7fc https://github.com/facebookincubator/katran/commit/cbefcadb1016bcb3f3649f4c131fdfda39582664 https://github.com/facebookincubator/mvfst/commit/68a198e5e3a64da86402e867e2d724ea2f96f8d1 https://github.com/facebookincubator/velox/commit/c98c0a77120b4f63dbd3c397c1879a65411aa5eb https://github.com/fairinternal/egohowto/commit/6bf781137a4835b39e4bc0701d4ccb1c0afdb8f5 https://github.com/pytorch/fbgemm/commit/c7cddecb8ddeaad71bb42f53f2e2cebc20a0cf91 Reviewed By: jurajh-fb fbshipit-source-id: 55e049c90043f451d8fea19c376e10b76717a477 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 0dd3ae758..ab5dd63a0 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 0dd3ae758c42c05dc36f80c80c70256296fbaf38 +Subproject commit ab5dd63a065b47a44223f8f90c71317109ea75cd diff --git a/cachelib/external/fizz b/cachelib/external/fizz index cd4dfb08e..b35b6da5b 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit cd4dfb08e1fd566bf14b5ad8b341d1efaec9b87a +Subproject commit b35b6da5bd4060f84e01c316010467de1ad1e7fc diff --git a/cachelib/external/folly b/cachelib/external/folly index c566c5821..e288b430e 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit c566c5821e8a5a2020fa752bc81791d2e5318a99 +Subproject commit e288b430e59df666ae4a54608ea912999010d118 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 3ef97c734..30304c925 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 3ef97c73473cc90c6a87757cc7a987e7a4bb2d4c +Subproject commit 30304c925a406ef9f63df718808ba3b253813f97 From 81e8547d8da75f47971a89df5fc980be8d98fbd2 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Thu, 16 Mar 2023 18:06:57 -0700 Subject: [PATCH 48/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/cachelib/commit/ecc68cbc7270438b7e74d958e31dec6ba46b510b https://github.com/facebook/fbthrift/commit/f34160a4b258a312c2fac9a2148a032ed0171a00 https://github.com/facebook/proxygen/commit/50a75b247476f78c232ef50e3de30d1d3d02e92b https://github.com/facebook/rocksdb/commit/291300ece8d5d94b6589d28d4d882bbace39443f https://github.com/facebook/watchman/commit/c744865639ae6793e1209c5769a15519cc0c87bc https://github.com/facebookexperimental/rust-shed/commit/fa39022b6cfe39f710d9535bbbf0227fa0f3e621 https://github.com/facebookincubator/mvfst/commit/5e2c438184c90fd0af8971d29295b175dcf804a4 https://github.com/facebookincubator/velox/commit/e473acfa2f524e9130ba3ca0302636a438956a4c Reviewed By: jurajh-fb fbshipit-source-id: 26bc70a453698f5b37f4e0c06822d9c691d99ae8 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index ab5dd63a0..f34160a4b 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit ab5dd63a065b47a44223f8f90c71317109ea75cd +Subproject commit f34160a4b258a312c2fac9a2148a032ed0171a00 From 29258e1400f96caca79d68eefe18356d85fa3146 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Thu, 16 Mar 2023 22:27:45 -0700 Subject: [PATCH 49/92] RebalanceStrategy: do not expose constructor with Type as public Summary: The type_ of RebalanceStrategy is only being used for the logging. However, it seems that this could be confusing for users to consider that the specific strategy instance is created simply by passing the Type. This change fixes this by making the constructor "protected". Reviewed By: therealgymmy Differential Revision: D43143713 fbshipit-source-id: 098c292b701e9eeef2d3adb08bcec6dca64ab0ee --- cachelib/allocator/RebalanceStrategy.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cachelib/allocator/RebalanceStrategy.h b/cachelib/allocator/RebalanceStrategy.h index c9aecf866..d723b8839 100644 --- a/cachelib/allocator/RebalanceStrategy.h +++ b/cachelib/allocator/RebalanceStrategy.h @@ -58,8 +58,7 @@ class RebalanceStrategy { struct BaseConfig {}; - explicit RebalanceStrategy(Type strategyType = PickNothingOrTest) - : type_(strategyType) {} + RebalanceStrategy() = default; virtual ~RebalanceStrategy() = default; @@ -83,6 +82,8 @@ class RebalanceStrategy { using PoolState = std::array; static const RebalanceContext kNoOpContext; + explicit RebalanceStrategy(Type strategyType) : type_(strategyType) {} + virtual RebalanceContext pickVictimAndReceiverImpl(const CacheBase&, PoolId) { return {}; } @@ -174,7 +175,7 @@ class RebalanceStrategy { const std::function& impl, T noOp); - Type type_{NumTypes}; + Type type_ = PickNothingOrTest; // maintain the state of the previous snapshot of pool for every pool. We // ll use this for processing and getting the deltas for some of these. From 5e7fb72711ba46ec2d97bacc0cdea1e5a65d5d82 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Fri, 17 Mar 2023 02:19:38 -0700 Subject: [PATCH 50/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fb303/commit/dc711c4170529922fed5623057de49af91f80d68 https://github.com/facebook/folly/commit/304ee74d43d0ad0fdbee06c88c63ce5a87d4adcb https://github.com/facebookexperimental/rust-shed/commit/3289c397f080362e9945ea62a3fe9098653e2f8e Reviewed By: jurajh-fb fbshipit-source-id: adcd397b6de52f2b46250dc06e599a32b2430345 --- cachelib/external/folly | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/folly b/cachelib/external/folly index e288b430e..304ee74d4 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit e288b430e59df666ae4a54608ea912999010d118 +Subproject commit 304ee74d43d0ad0fdbee06c88c63ce5a87d4adcb From e3c33c3c0c5cd80ebbcf51545a01e8b33f11e4ef Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Fri, 17 Mar 2023 17:01:20 -0700 Subject: [PATCH 51/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/12aae3090bf9bafbdb95f7a052efe4bb1a4bd06b https://github.com/facebook/proxygen/commit/129abd006476e3c3f65be951cb145faf9837b9fa https://github.com/facebook/rocksdb/commit/eac6b6d0cd5b73c9ca4f24fce25492282c528908 https://github.com/fairinternal/egohowto/commit/735cc9eb85fe22f76973a6f456c4938419b89cd6 Reviewed By: jurajh-fb fbshipit-source-id: 134da62bbb68aff4e904975dbb2e8297d582492b --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/wangle | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index f34160a4b..12aae3090 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit f34160a4b258a312c2fac9a2148a032ed0171a00 +Subproject commit 12aae3090bf9bafbdb95f7a052efe4bb1a4bd06b diff --git a/cachelib/external/fizz b/cachelib/external/fizz index b35b6da5b..556c4d162 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit b35b6da5bd4060f84e01c316010467de1ad1e7fc +Subproject commit 556c4d1624b06a7f4a8de9f1c0ff932708621bae diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 30304c925..cfd8a7a37 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 30304c925a406ef9f63df718808ba3b253813f97 +Subproject commit cfd8a7a37ad102c0bf64f2b09b63036fe3aa7c71 From b4a4f7621c2d97eab511c0e8f01676697f4f2df2 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Fri, 17 Mar 2023 19:15:07 -0700 Subject: [PATCH 52/92] RebalanceStrategy: removed duplicated calls to getPoolStats() Summary: In T146934410, we have seen that the getPoolStats could be expensive. However, previously, PoolRebalance and PoolResizer ended up calling getPoolStats for more than once unnecessarily; even three times in T146934410 per each invocation. This change removes the duplicated calls by changing all of relavant interface functions to take the PoolStats as parameter. Reviewed By: therealgymmy Differential Revision: D43892289 fbshipit-source-id: fb6191336d0535203f5ba11c6c8083552c9a5c0a --- cachelib/allocator/FreeMemStrategy.cpp | 4 +-- cachelib/allocator/FreeMemStrategy.h | 3 +- cachelib/allocator/HitsPerSlabStrategy.cpp | 8 ++--- cachelib/allocator/HitsPerSlabStrategy.h | 12 +++++--- cachelib/allocator/LruTailAgeStrategy.cpp | 9 +++--- cachelib/allocator/LruTailAgeStrategy.h | 12 +++++--- cachelib/allocator/MarginalHitsStrategy.cpp | 8 ++--- cachelib/allocator/MarginalHitsStrategy.h | 10 +++++-- cachelib/allocator/PoolResizeStrategy.h | 5 ++-- cachelib/allocator/RandomStrategy.h | 6 ++-- cachelib/allocator/RebalanceStrategy.cpp | 30 +++++++++---------- cachelib/allocator/RebalanceStrategy.h | 16 ++++++---- cachelib/allocator/tests/AllocatorTestUtils.h | 7 +++-- .../allocator/tests/SimpleRebalancingTest.h | 17 ++++++----- 14 files changed, 85 insertions(+), 62 deletions(-) diff --git a/cachelib/allocator/FreeMemStrategy.cpp b/cachelib/allocator/FreeMemStrategy.cpp index 5ddce0c9b..2a386ace7 100644 --- a/cachelib/allocator/FreeMemStrategy.cpp +++ b/cachelib/allocator/FreeMemStrategy.cpp @@ -37,15 +37,13 @@ FreeMemStrategy::FreeMemStrategy(Config config) // // 2. Pick the first class we find with free memory past the threshold RebalanceContext FreeMemStrategy::pickVictimAndReceiverImpl( - const CacheBase& cache, PoolId pid) { + const CacheBase& cache, PoolId pid, const PoolStats& poolStats) { const auto& pool = cache.getPool(pid); if (pool.getUnAllocatedSlabMemory() > config_.maxUnAllocatedSlabs * Slab::kSize) { return kNoOpContext; } - const auto poolStats = cache.getPoolStats(pid); - // ignore allocation classes that have fewer than the threshold of slabs. const auto victims = filterByNumEvictableSlabs( poolStats, std::move(poolStats.getClassIds()), config_.minSlabs); diff --git a/cachelib/allocator/FreeMemStrategy.h b/cachelib/allocator/FreeMemStrategy.h index ad07137c8..f0e0586a5 100644 --- a/cachelib/allocator/FreeMemStrategy.h +++ b/cachelib/allocator/FreeMemStrategy.h @@ -53,7 +53,8 @@ class FreeMemStrategy : public RebalanceStrategy { explicit FreeMemStrategy(Config config = {}); RebalanceContext pickVictimAndReceiverImpl(const CacheBase& cache, - PoolId pid) final; + PoolId pid, + const PoolStats& poolStats) final; private: const Config config_; diff --git a/cachelib/allocator/HitsPerSlabStrategy.cpp b/cachelib/allocator/HitsPerSlabStrategy.cpp index b312292b4..9b3b59af9 100644 --- a/cachelib/allocator/HitsPerSlabStrategy.cpp +++ b/cachelib/allocator/HitsPerSlabStrategy.cpp @@ -121,7 +121,7 @@ ClassId HitsPerSlabStrategy::pickReceiver(const Config& config, } RebalanceContext HitsPerSlabStrategy::pickVictimAndReceiverImpl( - const CacheBase& cache, PoolId pid) { + const CacheBase& cache, PoolId pid, const PoolStats& poolStats) { if (!cache.getPool(pid).allSlabsAllocated()) { XLOGF(DBG, "Pool Id: {}" @@ -131,8 +131,6 @@ RebalanceContext HitsPerSlabStrategy::pickVictimAndReceiverImpl( return kNoOpContext; } - const auto poolStats = cache.getPoolStats(pid); - const auto config = getConfigCopy(); RebalanceContext ctx; @@ -189,8 +187,8 @@ RebalanceContext HitsPerSlabStrategy::pickVictimAndReceiverImpl( } ClassId HitsPerSlabStrategy::pickVictimImpl(const CacheBase& cache, - PoolId pid) { - const auto poolStats = cache.getPoolStats(pid); + PoolId pid, + const PoolStats& poolStats) { const auto config = getConfigCopy(); auto victimClassId = pickVictim(config, cache, pid, poolStats); diff --git a/cachelib/allocator/HitsPerSlabStrategy.h b/cachelib/allocator/HitsPerSlabStrategy.h index 366809754..41f29f897 100644 --- a/cachelib/allocator/HitsPerSlabStrategy.h +++ b/cachelib/allocator/HitsPerSlabStrategy.h @@ -88,10 +88,14 @@ class HitsPerSlabStrategy : public RebalanceStrategy { return config_; } - RebalanceContext pickVictimAndReceiverImpl(const CacheBase& cache, - PoolId pid) override final; - - ClassId pickVictimImpl(const CacheBase& cache, PoolId pid) override final; + RebalanceContext pickVictimAndReceiverImpl( + const CacheBase& cache, + PoolId pid, + const PoolStats& poolStats) override final; + + ClassId pickVictimImpl(const CacheBase& cache, + PoolId pid, + const PoolStats& poolStats) override final; private: static AllocInfo makeAllocInfo(PoolId pid, diff --git a/cachelib/allocator/LruTailAgeStrategy.cpp b/cachelib/allocator/LruTailAgeStrategy.cpp index 72a34b93b..0bd714893 100644 --- a/cachelib/allocator/LruTailAgeStrategy.cpp +++ b/cachelib/allocator/LruTailAgeStrategy.cpp @@ -138,7 +138,7 @@ ClassId LruTailAgeStrategy::pickReceiver( } RebalanceContext LruTailAgeStrategy::pickVictimAndReceiverImpl( - const CacheBase& cache, PoolId pid) { + const CacheBase& cache, PoolId pid, const PoolStats& poolStats) { if (!cache.getPool(pid).allSlabsAllocated()) { XLOGF(DBG, "Pool Id: {}" @@ -151,7 +151,6 @@ RebalanceContext LruTailAgeStrategy::pickVictimAndReceiverImpl( const auto config = getConfigCopy(); - const auto poolStats = cache.getPoolStats(pid); const auto poolEvictionAgeStats = cache.getPoolEvictionAgeStats(pid, config.slabProjectionLength); @@ -190,11 +189,13 @@ RebalanceContext LruTailAgeStrategy::pickVictimAndReceiverImpl( return ctx; } -ClassId LruTailAgeStrategy::pickVictimImpl(const CacheBase& cache, PoolId pid) { +ClassId LruTailAgeStrategy::pickVictimImpl(const CacheBase& cache, + PoolId pid, + const PoolStats& poolStats) { const auto config = getConfigCopy(); const auto poolEvictionAgeStats = cache.getPoolEvictionAgeStats(pid, config.slabProjectionLength); - return pickVictim(config, pid, cache.getPoolStats(pid), poolEvictionAgeStats); + return pickVictim(config, pid, poolStats, poolEvictionAgeStats); } } // namespace cachelib } // namespace facebook diff --git a/cachelib/allocator/LruTailAgeStrategy.h b/cachelib/allocator/LruTailAgeStrategy.h index f7e4ceb58..d43757f60 100644 --- a/cachelib/allocator/LruTailAgeStrategy.h +++ b/cachelib/allocator/LruTailAgeStrategy.h @@ -95,10 +95,14 @@ class LruTailAgeStrategy : public RebalanceStrategy { return config_; } - RebalanceContext pickVictimAndReceiverImpl(const CacheBase& cache, - PoolId pid) override final; - - ClassId pickVictimImpl(const CacheBase& cache, PoolId pid) override final; + RebalanceContext pickVictimAndReceiverImpl( + const CacheBase& cache, + PoolId pid, + const PoolStats& poolStats) override final; + + ClassId pickVictimImpl(const CacheBase& cache, + PoolId pid, + const PoolStats& poolStats) override final; private: static AllocInfo makeAllocInfo(PoolId pid, diff --git a/cachelib/allocator/MarginalHitsStrategy.cpp b/cachelib/allocator/MarginalHitsStrategy.cpp index 83a17252d..1f3258422 100644 --- a/cachelib/allocator/MarginalHitsStrategy.cpp +++ b/cachelib/allocator/MarginalHitsStrategy.cpp @@ -30,7 +30,7 @@ MarginalHitsStrategy::MarginalHitsStrategy(Config config) : RebalanceStrategy(MarginalHits), config_(std::move(config)) {} RebalanceContext MarginalHitsStrategy::pickVictimAndReceiverImpl( - const CacheBase& cache, PoolId pid) { + const CacheBase& cache, PoolId pid, const PoolStats& poolStats) { const auto config = getConfigCopy(); if (!cache.getPool(pid).allSlabsAllocated()) { XLOGF(DBG, @@ -39,7 +39,6 @@ RebalanceContext MarginalHitsStrategy::pickVictimAndReceiverImpl( static_cast(pid)); return kNoOpContext; } - auto poolStats = cache.getPoolStats(pid); auto scores = computeClassMarginalHits(pid, poolStats); auto classesSet = poolStats.getClassIds(); std::vector classes(classesSet.begin(), classesSet.end()); @@ -66,8 +65,9 @@ RebalanceContext MarginalHitsStrategy::pickVictimAndReceiverImpl( } ClassId MarginalHitsStrategy::pickVictimImpl(const CacheBase& cache, - PoolId pid) { - return pickVictimAndReceiverImpl(cache, pid).victimClassId; + PoolId pid, + const PoolStats& stats) { + return pickVictimAndReceiverImpl(cache, pid, stats).victimClassId; } std::unordered_map diff --git a/cachelib/allocator/MarginalHitsStrategy.h b/cachelib/allocator/MarginalHitsStrategy.h index 851e5982f..d6e350984 100644 --- a/cachelib/allocator/MarginalHitsStrategy.h +++ b/cachelib/allocator/MarginalHitsStrategy.h @@ -66,11 +66,15 @@ class MarginalHitsStrategy : public RebalanceStrategy { } // pick victim and receiver classes from a pool - RebalanceContext pickVictimAndReceiverImpl(const CacheBase& cache, - PoolId pid) override final; + RebalanceContext pickVictimAndReceiverImpl( + const CacheBase& cache, + PoolId pid, + const PoolStats& poolStats) override final; // pick victim class from a pool to shrink - ClassId pickVictimImpl(const CacheBase& cache, PoolId pid) override final; + ClassId pickVictimImpl(const CacheBase& cache, + PoolId pid, + const PoolStats& poolStats) override final; private: // compute delta of tail hits for every class in this pool diff --git a/cachelib/allocator/PoolResizeStrategy.h b/cachelib/allocator/PoolResizeStrategy.h index ce284e5ea..84b95b9ea 100644 --- a/cachelib/allocator/PoolResizeStrategy.h +++ b/cachelib/allocator/PoolResizeStrategy.h @@ -37,10 +37,11 @@ class PoolResizeStrategy : public RebalanceStrategy { : RebalanceStrategy(PoolResize), minSlabsPerAllocClass_(minSlabs) {} // implementation that picks a victim - ClassId pickVictimImpl(const CacheBase& cache, PoolId poolId) final { + ClassId pickVictimImpl(const CacheBase&, + PoolId, + const PoolStats& stats) final { // pick the class with maximum eviction age. also, ensure that the class // does not drop below threshold of slabs. - const auto stats = cache.getPoolStats(poolId); auto victims = filterByNumEvictableSlabs( stats, stats.getClassIds(), minSlabsPerAllocClass_); diff --git a/cachelib/allocator/RandomStrategy.h b/cachelib/allocator/RandomStrategy.h index e8f26d18c..190c2db38 100644 --- a/cachelib/allocator/RandomStrategy.h +++ b/cachelib/allocator/RandomStrategy.h @@ -37,9 +37,9 @@ class RandomStrategy : public RebalanceStrategy { RandomStrategy() = default; explicit RandomStrategy(Config c) : RebalanceStrategy(Random), config_{c} {} - RebalanceContext pickVictimAndReceiverImpl(const CacheBase& cache, - PoolId pid) final { - const auto stats = cache.getPoolStats(pid); + RebalanceContext pickVictimAndReceiverImpl(const CacheBase&, + PoolId, + const PoolStats& stats) final { auto victimIds = filterByNumEvictableSlabs(stats, stats.getClassIds(), config_.minSlabs); const auto victim = pickRandom(victimIds); diff --git a/cachelib/allocator/RebalanceStrategy.cpp b/cachelib/allocator/RebalanceStrategy.cpp index ba082d12a..b3a98e3b9 100644 --- a/cachelib/allocator/RebalanceStrategy.cpp +++ b/cachelib/allocator/RebalanceStrategy.cpp @@ -33,9 +33,9 @@ void RebalanceStrategy::recordCurrentState(PoolId pid, const PoolStats& stats) { } } -ClassId RebalanceStrategy::pickAnyClassIdForResizing(const CacheBase& cache, - PoolId pid) { - const auto stats = cache.getPoolStats(pid); +ClassId RebalanceStrategy::pickAnyClassIdForResizing(const CacheBase&, + PoolId, + const PoolStats& stats) { const auto& candidates = stats.mpStats.classIds; // pick victim by maximum number of slabs. const auto ret = *std::max_element( @@ -200,15 +200,15 @@ RebalanceContext RebalanceStrategy::pickVictimAndReceiver( return executeAndRecordCurrentState( cache, pid, - [&]() { + [&](const PoolStats& stats) { // Pick receiver based on allocation failures. If nothing found, // fall back to strategy specific Impl RebalanceContext ctx; - ctx.receiverClassId = pickReceiverWithAllocFailures(cache, pid); + ctx.receiverClassId = pickReceiverWithAllocFailures(cache, pid, stats); if (ctx.receiverClassId != Slab::kInvalidClassId) { - ctx.victimClassId = pickVictimImpl(cache, pid); + ctx.victimClassId = pickVictimImpl(cache, pid, stats); if (ctx.victimClassId == cachelib::Slab::kInvalidClassId) { - ctx.victimClassId = pickAnyClassIdForResizing(cache, pid); + ctx.victimClassId = pickAnyClassIdForResizing(cache, pid, stats); } if (ctx.victimClassId != Slab::kInvalidClassId && ctx.victimClassId != ctx.receiverClassId && @@ -219,7 +219,7 @@ RebalanceContext RebalanceStrategy::pickVictimAndReceiver( return ctx; } } - return pickVictimAndReceiverImpl(cache, pid); + return pickVictimAndReceiverImpl(cache, pid, stats); }, kNoOpContext); } @@ -231,19 +231,19 @@ ClassId RebalanceStrategy::pickVictimForResizing(const CacheBase& cache, auto victimClassId = executeAndRecordCurrentState( cache, pid, - [&]() { return pickVictimImpl(cache, pid); }, + [&](const PoolStats& stats) { return pickVictimImpl(cache, pid, stats); }, Slab::kInvalidClassId); if (victimClassId == cachelib::Slab::kInvalidClassId) { - victimClassId = pickAnyClassIdForResizing(cache, pid); + const auto poolStats = cache.getPoolStats(pid); + victimClassId = pickAnyClassIdForResizing(cache, pid, poolStats); } return victimClassId; } -ClassId RebalanceStrategy::pickReceiverWithAllocFailures(const CacheBase& cache, - PoolId pid) { - const auto stats = cache.getPoolStats(pid); +ClassId RebalanceStrategy::pickReceiverWithAllocFailures( + const CacheBase&, PoolId pid, const PoolStats& stats) { auto receivers = stats.getClassIds(); const auto receiverWithAllocFailures = @@ -266,7 +266,7 @@ template T RebalanceStrategy::executeAndRecordCurrentState( const CacheBase& cache, PoolId pid, - const std::function& impl, + const std::function& impl, T noOp) { const auto poolStats = cache.getPoolStats(pid); @@ -277,7 +277,7 @@ T RebalanceStrategy::executeAndRecordCurrentState( return noOp; } - auto rv = impl(); + auto rv = impl(poolStats); recordCurrentState(pid, poolStats); diff --git a/cachelib/allocator/RebalanceStrategy.h b/cachelib/allocator/RebalanceStrategy.h index d723b8839..8898e58c3 100644 --- a/cachelib/allocator/RebalanceStrategy.h +++ b/cachelib/allocator/RebalanceStrategy.h @@ -84,11 +84,13 @@ class RebalanceStrategy { explicit RebalanceStrategy(Type strategyType) : type_(strategyType) {} - virtual RebalanceContext pickVictimAndReceiverImpl(const CacheBase&, PoolId) { + virtual RebalanceContext pickVictimAndReceiverImpl(const CacheBase&, + PoolId, + const PoolStats&) { return {}; } - virtual ClassId pickVictimImpl(const CacheBase&, PoolId) { + virtual ClassId pickVictimImpl(const CacheBase&, PoolId, const PoolStats&) { return Slab::kInvalidClassId; } @@ -149,7 +151,9 @@ class RebalanceStrategy { private: // picks any of the class id ordered by the total slabs. - ClassId pickAnyClassIdForResizing(const CacheBase& cache, PoolId pid); + ClassId pickAnyClassIdForResizing(const CacheBase& cache, + PoolId pid, + const PoolStats& poolStats); // initialize the pool's state to the current stats. void initPoolState(PoolId pid, const PoolStats& stats); @@ -160,7 +164,9 @@ class RebalanceStrategy { // Pick a receiver with max alloc failures. If no alloc failures, return // invalid classid. - ClassId pickReceiverWithAllocFailures(const CacheBase& cache, PoolId pid); + ClassId pickReceiverWithAllocFailures(const CacheBase& cache, + PoolId pid, + const PoolStats& stat); // Ensure pool state is initialized before calling impl, and update pool // state after calling impl. @@ -172,7 +178,7 @@ class RebalanceStrategy { template T executeAndRecordCurrentState(const CacheBase& cache, PoolId pid, - const std::function& impl, + const std::function& impl, T noOp); Type type_ = PickNothingOrTest; diff --git a/cachelib/allocator/tests/AllocatorTestUtils.h b/cachelib/allocator/tests/AllocatorTestUtils.h index 58664ee8b..e089f6c14 100644 --- a/cachelib/allocator/tests/AllocatorTestUtils.h +++ b/cachelib/allocator/tests/AllocatorTestUtils.h @@ -33,12 +33,15 @@ struct AlwaysPickOneRebalanceStrategy : public RebalanceStrategy { private: ClassId pickVictim(const CacheBase&, PoolId) { return victim; } - ClassId pickVictimImpl(const CacheBase& allocator, PoolId pid) override { + ClassId pickVictimImpl(const CacheBase& allocator, + PoolId pid, + const PoolStats&) override { return pickVictim(allocator, pid); } RebalanceContext pickVictimAndReceiverImpl(const CacheBase& allocator, - PoolId pid) override { + PoolId pid, + const PoolStats&) override { return {pickVictim(allocator, pid), receiver}; } }; diff --git a/cachelib/allocator/tests/SimpleRebalancingTest.h b/cachelib/allocator/tests/SimpleRebalancingTest.h index c25c6b0d6..634882c73 100644 --- a/cachelib/allocator/tests/SimpleRebalancingTest.h +++ b/cachelib/allocator/tests/SimpleRebalancingTest.h @@ -34,12 +34,12 @@ struct SimpleRebalanceStrategy : public RebalanceStrategy { SimpleRebalanceStrategy() : RebalanceStrategy(PickNothingOrTest) {} private: - ClassId pickVictim(const CacheBase& allocator, PoolId pid) { - auto poolStats = allocator.getPoolStats(pid); + ClassId pickVictim(const CacheBase&, PoolId, const PoolStats& poolStats) { ClassId cid = Slab::kInvalidClassId; uint64_t maxActiveAllocs = 0; for (size_t i = 0; i < poolStats.mpStats.acStats.size(); ++i) { - const auto& acStats = poolStats.mpStats.acStats[static_cast(i)]; + const auto& acStats = + poolStats.mpStats.acStats.at(static_cast(i)); if (maxActiveAllocs < acStats.activeAllocs) { maxActiveAllocs = acStats.activeAllocs; cid = static_cast(i); @@ -48,13 +48,16 @@ struct SimpleRebalanceStrategy : public RebalanceStrategy { return cid; } - ClassId pickVictimImpl(const CacheBase& allocator, PoolId pid) override { - return pickVictim(allocator, pid); + ClassId pickVictimImpl(const CacheBase& allocator, + PoolId pid, + const PoolStats& stats) override { + return pickVictim(allocator, pid, stats); } RebalanceContext pickVictimAndReceiverImpl(const CacheBase& allocator, - PoolId pid) override { - return {pickVictim(allocator, pid), Slab::kInvalidClassId}; + PoolId pid, + const PoolStats& stats) override { + return {pickVictim(allocator, pid, stats), Slab::kInvalidClassId}; } }; From 66874aba3037e7bad866777ca4592dbafe323c35 Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Fri, 17 Mar 2023 19:19:19 -0700 Subject: [PATCH 53/92] PoolRebalancer: add an option to disable waking up PoolRebalancer on alloc failures Summary: This change adds an option to disable waking up PoolRebalancer on alloc failures, where the default is set to false (i.e., enabled). If disabled, PoolRebalancer will only be woken up every poolRebalanceInterval. Reviewed By: therealgymmy Differential Revision: D43964447 fbshipit-source-id: aec6c1742a3b6d2305378e9c4ae59dc923c785ca --- cachelib/allocator/CacheAllocator-inl.h | 2 +- cachelib/allocator/CacheAllocatorConfig.h | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cachelib/allocator/CacheAllocator-inl.h b/cachelib/allocator/CacheAllocator-inl.h index 5c0ddbbea..1e23639ba 100644 --- a/cachelib/allocator/CacheAllocator-inl.h +++ b/cachelib/allocator/CacheAllocator-inl.h @@ -363,7 +363,7 @@ CacheAllocator::allocateInternal(PoolId pid, } else { // failed to allocate memory. (*stats_.allocFailures)[pid][cid].inc(); // wake up rebalancer - if (poolRebalancer_) { + if (!config_.poolRebalancerDisableForcedWakeUp && poolRebalancer_) { poolRebalancer_->wakeUp(); } } diff --git a/cachelib/allocator/CacheAllocatorConfig.h b/cachelib/allocator/CacheAllocatorConfig.h index ec44ff846..9876f33c0 100644 --- a/cachelib/allocator/CacheAllocatorConfig.h +++ b/cachelib/allocator/CacheAllocatorConfig.h @@ -241,10 +241,12 @@ class CacheAllocatorConfig { // slab memory distributed across different allocation classes. For example, // if the 64 bytes allocation classes are receiving for allocation requests, // eventually CacheAllocator will move more memory to it from other allocation - // classes. For more details, see our user guide. + // classes. The rebalancing is triggered every specified interval and + // optionally on allocation failures. For more details, see our user guide. CacheAllocatorConfig& enablePoolRebalancing( std::shared_ptr defaultRebalanceStrategy, - std::chrono::milliseconds interval); + std::chrono::milliseconds interval, + bool disableForcedWakeup = false); // This lets you change pool size during runtime, and the pool resizer // will slowly adjust each pool's memory size to the newly configured sizes. @@ -434,6 +436,9 @@ class CacheAllocatorConfig { // time interval to sleep between iterators of rebalancing the pools. std::chrono::milliseconds poolRebalanceInterval{std::chrono::seconds{1}}; + // disable waking up the PoolRebalancer on alloc failures + bool poolRebalancerDisableForcedWakeUp{false}; + // Free slabs pro-actively if the ratio of number of freeallocs to // the number of allocs per slab in a slab class is above this // threshold @@ -913,10 +918,12 @@ CacheAllocatorConfig& CacheAllocatorConfig::enablePoolOptimizer( template CacheAllocatorConfig& CacheAllocatorConfig::enablePoolRebalancing( std::shared_ptr defaultRebalanceStrategy, - std::chrono::milliseconds interval) { + std::chrono::milliseconds interval, + bool disableForcedWakeup) { if (validateStrategy(defaultRebalanceStrategy)) { defaultPoolRebalanceStrategy = defaultRebalanceStrategy; poolRebalanceInterval = interval; + poolRebalancerDisableForcedWakeUp = disableForcedWakeup; } else { throw std::invalid_argument( "Invalid rebalance strategy for the cache allocator."); From 5e58f073653eda5f0c00d6450423a968957d7ec7 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Fri, 17 Mar 2023 20:19:36 -0700 Subject: [PATCH 54/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/cachelib/commit/66874aba3037e7bad866777ca4592dbafe323c35 https://github.com/facebook/fbthrift/commit/f700edff40ea50e424cec82c38905b875905ac59 https://github.com/facebook/litho/commit/136d58b1e81def847de32f325c89b3584d172ebd https://github.com/facebookincubator/velox/commit/b813180119c98d97f838b826f3def46c379943a1 https://github.com/pytorch/fbgemm/commit/54eeae214af0834cc07632eb916879d71468a4cd Reviewed By: jurajh-fb fbshipit-source-id: 61181cd11538696c3da9a7334ce25c902c4a4517 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 12aae3090..f700edff4 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 12aae3090bf9bafbdb95f7a052efe4bb1a4bd06b +Subproject commit f700edff40ea50e424cec82c38905b875905ac59 From aad47e6ba854474c50b9064054294a55205608b0 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sat, 18 Mar 2023 04:29:47 -0700 Subject: [PATCH 55/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/cb17c257141d8e439c6298fea36c0fa9a88a9c7d https://github.com/facebook/watchman/commit/8a7b51bd3534c27298276d3f7a64f8197c9dd293 Reviewed By: jurajh-fb fbshipit-source-id: 237d9a699489d5b2869c61dd7d70e37ae295db4d --- cachelib/external/fbthrift | 2 +- cachelib/external/wangle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index f700edff4..cb17c2571 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit f700edff40ea50e424cec82c38905b875905ac59 +Subproject commit cb17c257141d8e439c6298fea36c0fa9a88a9c7d diff --git a/cachelib/external/wangle b/cachelib/external/wangle index cfd8a7a37..eb576c9be 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit cfd8a7a37ad102c0bf64f2b09b63036fe3aa7c71 +Subproject commit eb576c9be9d5e7895614d280e0795f68c74b6053 From 63ee3ff317433308aaf37060367c921b9893417c Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sun, 19 Mar 2023 14:10:37 -0700 Subject: [PATCH 56/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/f1e05d4128a6b7098473fea7713c76fa428b46d4 https://github.com/facebookexperimental/rust-shed/commit/2c0609bc2ce59a641aa828e619ceff3c5f6df395 Reviewed By: jurajh-fb fbshipit-source-id: 46288884d2f5b93a66567ec0363117c269d766ba --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index cb17c2571..f1e05d412 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit cb17c257141d8e439c6298fea36c0fa9a88a9c7d +Subproject commit f1e05d4128a6b7098473fea7713c76fa428b46d4 From ec46b29ba1631f79acd01d7945469243ff228de9 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Mon, 20 Mar 2023 14:10:38 -0700 Subject: [PATCH 57/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/d3896efcf2c9c13f0975ab6230b47064b78b14b5 https://github.com/facebook/folly/commit/20a55edc0fac385c626ddd7775e80b501a46679f https://github.com/facebook/proxygen/commit/ffb5803c99e5131c34c5222b482eca6b487c4b4b https://github.com/facebook/rocksdb/commit/cea81cad661f3cecafc1f944240e80d34422d4c8 https://github.com/facebook/wangle/commit/7843da5c509c7a4dce6a540b499b6159bdc4f14e https://github.com/facebookexperimental/edencommon/commit/e1ca4f7b88ea37fe1833e745860a39342a1872c4 https://github.com/facebookincubator/fizz/commit/30686d6cb0ec3a496c3364b4e75228cb4cfd7285 https://github.com/facebookincubator/katran/commit/a5b5b0d74782bb0dbacb62ce86139ad3806c7db9 https://github.com/facebookincubator/mvfst/commit/47a935c7ce861d2c4ebcb2df7f1dc1dc36cefe8e https://github.com/facebookincubator/velox/commit/95ade01d8de13cadf0b8b630e40baba44a530ffd Reviewed By: bigfootjon fbshipit-source-id: 7a1357387fcb55a783a3d60c93b0b2c1ad17dd47 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index f1e05d412..d3896efcf 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit f1e05d4128a6b7098473fea7713c76fa428b46d4 +Subproject commit d3896efcf2c9c13f0975ab6230b47064b78b14b5 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 556c4d162..30686d6cb 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 556c4d1624b06a7f4a8de9f1c0ff932708621bae +Subproject commit 30686d6cb0ec3a496c3364b4e75228cb4cfd7285 diff --git a/cachelib/external/folly b/cachelib/external/folly index 304ee74d4..20a55edc0 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 304ee74d43d0ad0fdbee06c88c63ce5a87d4adcb +Subproject commit 20a55edc0fac385c626ddd7775e80b501a46679f diff --git a/cachelib/external/wangle b/cachelib/external/wangle index eb576c9be..7843da5c5 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit eb576c9be9d5e7895614d280e0795f68c74b6053 +Subproject commit 7843da5c509c7a4dce6a540b499b6159bdc4f14e From 4096277a8c853b8f139a8cfaf020caa840bcf43e Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Tue, 21 Mar 2023 06:42:52 -0700 Subject: [PATCH 58/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/7137d3433d63ff901e8a16f72e48de4b7daa0a6b https://github.com/facebook/litho/commit/7e4ac69fb0a7a4d31f029affa0a7c71b802d68ea https://github.com/facebookincubator/mvfst/commit/eb9b747065f02001eb3c882560df5588e352c0ca https://github.com/facebookincubator/velox/commit/6c0632be3c97fba1d6af82e283d9c7a134b22101 Reviewed By: bigfootjon fbshipit-source-id: a3cff2eff1b324245d3f2caf3dea1bdc81b867ff --- cachelib/external/fbthrift | 2 +- cachelib/external/folly | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index d3896efcf..7137d3433 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit d3896efcf2c9c13f0975ab6230b47064b78b14b5 +Subproject commit 7137d3433d63ff901e8a16f72e48de4b7daa0a6b diff --git a/cachelib/external/folly b/cachelib/external/folly index 20a55edc0..4fa3680ee 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 20a55edc0fac385c626ddd7775e80b501a46679f +Subproject commit 4fa3680ee47f4c8542fd06f873cdc1d5bfccf4f6 From b0ed11a3677e8f445a2c15c6638ce703c7e096bb Mon Sep 17 00:00:00 2001 From: Mark Juggurnauth-Thomas Date: Tue, 21 Mar 2023 10:04:46 -0700 Subject: [PATCH 59/92] remove rust readonly bindings Summary: These bindings are no longer used, so can be removed. Differential Revision: D44174537 fbshipit-source-id: 78544624d92c89d3a457b63e7849fe9f01442309 --- cachelib/rust/readonly/readonly.cpp | 50 ------- cachelib/rust/readonly/readonly.h | 43 ------ cachelib/rust/readonly/readonly.rs | 200 ---------------------------- 3 files changed, 293 deletions(-) delete mode 100644 cachelib/rust/readonly/readonly.cpp delete mode 100644 cachelib/rust/readonly/readonly.h delete mode 100644 cachelib/rust/readonly/readonly.rs diff --git a/cachelib/rust/readonly/readonly.cpp b/cachelib/rust/readonly/readonly.cpp deleted file mode 100644 index 53ed7c6bd..000000000 --- a/cachelib/rust/readonly/readonly.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "cachelib/rust/readonly/readonly.h" - -namespace facebook { -namespace rust { -namespace cachelib { - -std::unique_ptr -ro_cache_view_attach(const std::string& cache_dir) { - return std::make_unique( - cache_dir, false); -} - -std::unique_ptr -ro_cache_view_attach_at_address(const std::string& cache_dir, size_t addr) { - return std::make_unique( - cache_dir, false, (void*)addr); -} - -uintptr_t ro_cache_view_get_shm_mapping_address( - const facebook::cachelib::ReadOnlySharedCacheView& cacheView) { - return cacheView.getShmMappingAddress(); -} - -const uint8_t* ro_cache_view_get_item_ptr_from_offset( - const facebook::cachelib::ReadOnlySharedCacheView& cacheView, - size_t offset) { - return static_cast( - const_cast(cacheView) - .getItemPtrFromOffset(offset)); -} - -} // namespace cachelib -} // namespace rust -} // namespace facebook diff --git a/cachelib/rust/readonly/readonly.h b/cachelib/rust/readonly/readonly.h deleted file mode 100644 index 673593ec3..000000000 --- a/cachelib/rust/readonly/readonly.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include -#include - -#include "cachelib/allocator/ReadOnlySharedCacheView.h" - -namespace facebook { -namespace rust { -namespace cachelib { - -std::unique_ptr -ro_cache_view_attach(const std::string& cache_dir); - -std::unique_ptr -ro_cache_view_attach_at_address(const std::string& cache_dir, size_t); - -uintptr_t ro_cache_view_get_shm_mapping_address( - const facebook::cachelib::ReadOnlySharedCacheView& cache); - -const uint8_t* ro_cache_view_get_item_ptr_from_offset( - const facebook::cachelib::ReadOnlySharedCacheView& cacheView, - size_t offset); -} // namespace cachelib -} // namespace rust -} // namespace facebook diff --git a/cachelib/rust/readonly/readonly.rs b/cachelib/rust/readonly/readonly.rs deleted file mode 100644 index 371b9a159..000000000 --- a/cachelib/rust/readonly/readonly.rs +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -use std::os::unix::ffi::OsStrExt; -use std::path::Path; - -use cxx::let_cxx_string; -use thiserror::Error; - -#[derive(Debug, Error)] -#[error("Failed to attach ReadOnlySharedCacheView: {cxx_exn}")] -pub struct FailedToAttachError { - #[from] - cxx_exn: cxx::Exception, -} - -#[derive(Debug, Error)] -#[error("Invalid remote item handle: {cxx_exn}")] -pub struct InvalidHandleError { - #[from] - cxx_exn: cxx::Exception, -} - -#[cxx::bridge(namespace = "facebook::rust::cachelib")] -mod ffi { - unsafe extern "C++" { - include!("cachelib/rust/readonly/readonly.h"); - - #[namespace = "facebook::cachelib"] - type ReadOnlySharedCacheView; - - fn ro_cache_view_attach( - cache_dir: &CxxString, - ) -> Result>; - fn ro_cache_view_attach_at_address( - cache_dir: &CxxString, - addr: usize, - ) -> Result>; - fn ro_cache_view_get_shm_mapping_address(cache: &ReadOnlySharedCacheView) -> usize; - fn ro_cache_view_get_item_ptr_from_offset( - cache: &ReadOnlySharedCacheView, - offset: usize, - ) -> Result<*const u8>; - } -} - -pub struct ReadOnlySharedCacheView { - cache_view: cxx::UniquePtr, -} - -impl ReadOnlySharedCacheView { - pub fn new(cache_dir: impl AsRef) -> Result { - let_cxx_string!(cache_dir = cache_dir.as_ref().as_os_str().as_bytes()); - let cache_view = ffi::ro_cache_view_attach(&cache_dir)?; - Ok(Self { cache_view }) - } - - pub fn new_at_address( - cache_dir: impl AsRef, - addr: *mut std::ffi::c_void, - ) -> Result { - let_cxx_string!(cache_dir = cache_dir.as_ref().as_os_str().as_bytes()); - let cache_view = ffi::ro_cache_view_attach_at_address(&cache_dir, addr as usize)?; - Ok(Self { cache_view }) - } - - /// Return a byte slice from a (offset, len) pair within the cache. - /// (offset, len) must be retrieved using [get_remote_handle] from an LruCacheHandle. - pub fn get_bytes_from_offset<'a>( - &'a self, - offset: usize, - len: usize, - ) -> Result<&'a [u8], InvalidHandleError> { - let item_ptr = ffi::ro_cache_view_get_item_ptr_from_offset(&*self.cache_view, offset)?; - Ok(unsafe { std::slice::from_raw_parts(item_ptr, len) }) - } - - pub fn shm_mapping_address(&self) -> usize { - let addr = ffi::ro_cache_view_get_shm_mapping_address(&*self.cache_view); - if addr == 0 { - // This shouldn't happen--the whole point of ReadOnlySharedCacheView - // is that it's a view into a cache's shared memory, and - // getShmMappingAddress should return nullptr only when the cache is - // not using shared memory. - panic!("ReadOnlySharedCacheView returned null shm_mapping_address") - } else { - addr - } - } -} - -#[cfg(test)] -mod test { - use std::path::PathBuf; - use std::time::Duration; - - use anyhow::Result; - use bytes::Bytes; - use cachelib::*; - use fbinit::FacebookInit; - use tempdir::TempDir; - - use super::*; - - fn create_temp_dir(dir_prefix: &str) -> TempDir { - TempDir::new(dir_prefix).expect("failed to create temp dir") - } - - fn create_shared_cache(fb: FacebookInit, cache_directory: PathBuf) { - let config = LruCacheConfig::new(128 * 1024 * 1024) - .set_shrinker(ShrinkMonitor { - shrinker_type: ShrinkMonitorType::ResidentSize { - max_process_size_gib: 16, - min_process_size_gib: 1, - }, - interval: Duration::new(1, 0), - max_resize_per_iteration_percent: 10, - max_removed_percent: 90, - strategy: RebalanceStrategy::LruTailAge { - age_difference_ratio: 0.1, - min_retained_slabs: 1, - }, - }) - .set_pool_resizer(PoolResizeConfig { - interval: Duration::new(1, 0), - slabs_per_iteration: 100, - strategy: RebalanceStrategy::LruTailAge { - age_difference_ratio: 0.1, - min_retained_slabs: 1, - }, - }) - .set_cache_dir(cache_directory) - .set_pool_rebalance(PoolRebalanceConfig { - interval: Duration::new(1, 0), - strategy: RebalanceStrategy::LruTailAge { - age_difference_ratio: 0.1, - min_retained_slabs: 1, - }, - }); - - if let Err(e) = init_cache(fb, config) { - panic!("{}", e); - } - } - - #[fbinit::test] - fn test_readonly_shared_cache(fb: FacebookInit) -> Result<()> { - let temp_dir = create_temp_dir("test_shared_cache"); - create_shared_cache(fb, temp_dir.path().into()); - - // Set value in original cache - let pool = get_or_create_pool("find_pool_by_name", 4 * 1024 * 1024)?; - let value = b"I am a fish"; - pool.set(b"test", Bytes::from(value.as_ref()))?; - - let test_handle = pool.get_handle(b"test")?.unwrap(); - let remote_handle = test_handle.get_remote_handle()?; - - // Get value from read-only cache - let ro_cache_view = ReadOnlySharedCacheView::new(&temp_dir.path())?; - let slice = ro_cache_view - .get_bytes_from_offset(remote_handle.get_offset(), remote_handle.get_length())?; - let reader_bytes = Bytes::copy_from_slice(slice); - - // Verify that value is the same - assert_eq!( - reader_bytes, - Bytes::from(b"I am a fish".as_ref()), - "Data does not match!" - ); - - Ok(()) - } - - #[test] - fn test_non_existent_cache_dir() { - let temp_dir = create_temp_dir("test_non_existent_cache_dir"); - - let mut path = temp_dir.path().to_owned(); - path.push("this_dir_does_not_exist"); - - match ReadOnlySharedCacheView::new(&path) { - Ok(_) => panic!("ReadOnlySharedCacheView::new returned Ok for non-existent dir"), - Err(FailedToAttachError { .. }) => {} - } - } -} From 31805c486906ecccd17d7c03e70a58ffd067e5f7 Mon Sep 17 00:00:00 2001 From: Mark Juggurnauth-Thomas Date: Tue, 21 Mar 2023 10:04:46 -0700 Subject: [PATCH 60/92] rust: fix potential integer truncation for oversized cache allocations Summary: Cachelib can only accept allocations up to 4MiB, and as such the size parameter is a `uint32_t`. However, the Rust API currently accepts `usize`, which may be truncated when converted to `uint32_t`. Make this conversion explicit and an error if the `usize` is larger than what will fit in a `uint32_t`. Differential Revision: D44186153 fbshipit-source-id: f5a57e5447cf93211a259f8360e06cafa7564158 --- cachelib/rust/src/cachelib.cpp | 2 +- cachelib/rust/src/cachelib.h | 2 +- cachelib/rust/src/lib.rs | 2 +- cachelib/rust/src/lrucache.rs | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cachelib/rust/src/cachelib.cpp b/cachelib/rust/src/cachelib.cpp index 6a48cbdc3..77e6f7c21 100644 --- a/cachelib/rust/src/cachelib.cpp +++ b/cachelib/rust/src/cachelib.cpp @@ -158,7 +158,7 @@ std::unique_ptr allocate_item( const facebook::cachelib::LruAllocator& cache, facebook::cachelib::PoolId id, folly::StringPiece key, - size_t size, + uint32_t size, uint32_t ttlSecs) { auto item = const_cast(cache).allocate( id, key, size, ttlSecs); diff --git a/cachelib/rust/src/cachelib.h b/cachelib/rust/src/cachelib.h index f7695299d..e9bb535c5 100644 --- a/cachelib/rust/src/cachelib.h +++ b/cachelib/rust/src/cachelib.h @@ -98,7 +98,7 @@ std::unique_ptr allocate_item( const facebook::cachelib::LruAllocator& cache, facebook::cachelib::PoolId id, folly::StringPiece key, - size_t size, + uint32_t size, uint32_t ttlSecs); bool insert_handle(const facebook::cachelib::LruAllocator& cache, diff --git a/cachelib/rust/src/lib.rs b/cachelib/rust/src/lib.rs index 2eaca32d8..67a36d3ea 100644 --- a/cachelib/rust/src/lib.rs +++ b/cachelib/rust/src/lib.rs @@ -137,7 +137,7 @@ mod ffi { cache: &LruAllocator, id: i8, key: StringPiece<'_>, - size: usize, + size: u32, ttl_secs: u32, ) -> Result>; diff --git a/cachelib/rust/src/lrucache.rs b/cachelib/rust/src/lrucache.rs index bf7ddfcb4..110d5bebf 100644 --- a/cachelib/rust/src/lrucache.rs +++ b/cachelib/rust/src/lrucache.rs @@ -28,6 +28,7 @@ use std::sync::Mutex; use std::sync::RwLock; use std::time::Duration; +use anyhow::Context; use anyhow::Error; use anyhow::Result; use bytes::buf::UninitSlice; @@ -720,6 +721,7 @@ impl LruCachePool { .map_or(0, |d| std::cmp::min(d.as_secs(), 1)) .try_into() .unwrap_or(u32::MAX); + let size = size.try_into().context("Cache allocation too large")?; let handle = ffi::allocate_item(cache, self.pool, key, size, ttl_secs)?; if handle.is_null() { Ok(None) From 58fd7bf62ba583b6c45c74b90877a1762334c033 Mon Sep 17 00:00:00 2001 From: Mark Juggurnauth-Thomas Date: Tue, 21 Mar 2023 10:04:46 -0700 Subject: [PATCH 61/92] rust: add type alias for LruAllocator Summary: We would like to be able to select different cache allocator implementations. This is defined by the C++ type that is used for the allocator, which is repeated many times throughout the C++ bindings. Make it easier to change by using a type alias throughout. Reviewed By: therealgymmy Differential Revision: D44174535 fbshipit-source-id: ebb2aa437ebd22a68fa6d7dc18d63e472aec4f42 --- cachelib/rust/src/cachelib.cpp | 77 +++++++++++++++------------------- cachelib/rust/src/cachelib.h | 57 ++++++++++++------------- cachelib/rust/src/lib.rs | 1 - 3 files changed, 59 insertions(+), 76 deletions(-) diff --git a/cachelib/rust/src/cachelib.cpp b/cachelib/rust/src/cachelib.cpp index 77e6f7c21..4e50508e5 100644 --- a/cachelib/rust/src/cachelib.cpp +++ b/cachelib/rust/src/cachelib.cpp @@ -29,20 +29,20 @@ namespace facebook { namespace rust { namespace cachelib { std::unique_ptr make_cacheadmin( - facebook::cachelib::LruAllocator& cache, const std::string& oncall) { + LruAllocator& cache, const std::string& oncall) { facebook::cachelib::CacheAdmin::Config adminConfig; adminConfig.oncall = oncall; return std::make_unique(cache, adminConfig); } -std::unique_ptr make_lru_allocator( +std::unique_ptr make_lru_allocator( std::unique_ptr config) { - return std::make_unique(*config); + return std::make_unique(*config); } -std::unique_ptr make_shm_lru_allocator( +std::unique_ptr make_shm_lru_allocator( std::unique_ptr config) { - return std::make_unique( - facebook::cachelib::LruAllocator::SharedMemNewT::SharedMemNew, *config); + return std::make_unique( + LruAllocator::SharedMemNewT::SharedMemNew, *config); } std::unique_ptr make_lru_allocator_config() { return std::make_unique(); @@ -130,14 +130,13 @@ void set_base_address(LruAllocatorConfig& config, size_t addr) { config.slabMemoryBaseAddr = (void*)addr; } -int8_t add_pool(const facebook::cachelib::LruAllocator& cache, +int8_t add_pool(const LruAllocator& cache, folly::StringPiece name, size_t size) { - return const_cast(cache).addPool(name, - size); + return const_cast(cache).addPool(name, size); } -size_t get_unreserved_size(const facebook::cachelib::LruAllocator& cache) { +size_t get_unreserved_size(const LruAllocator& cache) { return cache.getCacheMemoryStats().unReservedSize; } @@ -148,20 +147,16 @@ const uint8_t* get_memory(const LruItemHandle& handle) { uint8_t* get_writable_memory(LruItemHandle& handle) { return static_cast(handle->getMemory()); } -size_t get_item_ptr_as_offset(const facebook::cachelib::LruAllocator& cache, - const uint8_t* ptr) { - return const_cast(cache) - .getItemPtrAsOffset(ptr); +size_t get_item_ptr_as_offset(const LruAllocator& cache, const uint8_t* ptr) { + return const_cast(cache).getItemPtrAsOffset(ptr); } -std::unique_ptr allocate_item( - const facebook::cachelib::LruAllocator& cache, - facebook::cachelib::PoolId id, - folly::StringPiece key, - uint32_t size, - uint32_t ttlSecs) { - auto item = const_cast(cache).allocate( - id, key, size, ttlSecs); +std::unique_ptr allocate_item(const LruAllocator& cache, + facebook::cachelib::PoolId id, + folly::StringPiece key, + uint32_t size, + uint32_t ttlSecs) { + auto item = const_cast(cache).allocate(id, key, size, ttlSecs); if (item) { return std::make_unique(std::move(item)); } else { @@ -169,22 +164,20 @@ std::unique_ptr allocate_item( } } -bool insert_handle(const facebook::cachelib::LruAllocator& cache, - LruItemHandle& handle) { - return const_cast(cache).insert(handle); +bool insert_handle(const LruAllocator& cache, LruItemHandle& handle) { + return const_cast(cache).insert(handle); } -void insert_or_replace_handle(const facebook::cachelib::LruAllocator& cache, +void insert_or_replace_handle(const LruAllocator& cache, LruItemHandle& handle) { - const_cast(cache).insertOrReplace(handle); + const_cast(cache).insertOrReplace(handle); } -void remove_item(const facebook::cachelib::LruAllocator& cache, - folly::StringPiece key) { - const_cast(cache).remove(key); +void remove_item(const LruAllocator& cache, folly::StringPiece key) { + const_cast(cache).remove(key); } -std::unique_ptr find_item( - const facebook::cachelib::LruAllocator& cache, folly::StringPiece key) { - auto item = const_cast(cache).find(key); +std::unique_ptr find_item(const LruAllocator& cache, + folly::StringPiece key) { + auto item = const_cast(cache).find(key); if (item) { // TODO(jiayueb) remove toWriteHandle() after finishing R/W handle migration return std::make_unique(std::move(item).toWriteHandle()); @@ -192,28 +185,24 @@ std::unique_ptr find_item( return std::unique_ptr(); } } -size_t get_pool_size(const facebook::cachelib::LruAllocator& cache, - facebook::cachelib::PoolId id) { +size_t get_pool_size(const LruAllocator& cache, facebook::cachelib::PoolId id) { return cache.getPool(id).getPoolSize(); } -bool grow_pool(const facebook::cachelib::LruAllocator& cache, +bool grow_pool(const LruAllocator& cache, facebook::cachelib::PoolId id, size_t size) { - return const_cast(cache).growPool(id, - size); + return const_cast(cache).growPool(id, size); } -bool shrink_pool(const facebook::cachelib::LruAllocator& cache, +bool shrink_pool(const LruAllocator& cache, facebook::cachelib::PoolId id, size_t size) { - return const_cast(cache).shrinkPool(id, - size); + return const_cast(cache).shrinkPool(id, size); } -bool resize_pools(const facebook::cachelib::LruAllocator& cache, +bool resize_pools(const LruAllocator& cache, facebook::cachelib::PoolId src, facebook::cachelib::PoolId dst, size_t size) { - return const_cast(cache).resizePools( - src, dst, size); + return const_cast(cache).resizePools(src, dst, size); } } // namespace cachelib } // namespace rust diff --git a/cachelib/rust/src/cachelib.h b/cachelib/rust/src/cachelib.h index e9bb535c5..a51de7e04 100644 --- a/cachelib/rust/src/cachelib.h +++ b/cachelib/rust/src/cachelib.h @@ -26,14 +26,15 @@ namespace facebook { namespace rust { namespace cachelib { -using LruAllocatorConfig = facebook::cachelib::LruAllocator::Config; -using LruItemHandle = facebook::cachelib::LruAllocator::WriteHandle; +using LruAllocator = facebook::cachelib::LruAllocator; +using LruAllocatorConfig = LruAllocator::Config; +using LruItemHandle = LruAllocator::WriteHandle; std::unique_ptr make_cacheadmin( - facebook::cachelib::LruAllocator& cache, const std::string& oncall); -std::unique_ptr make_lru_allocator( + LruAllocator& cache, const std::string& oncall); +std::unique_ptr make_lru_allocator( std::unique_ptr config); -std::unique_ptr make_shm_lru_allocator( +std::unique_ptr make_shm_lru_allocator( std::unique_ptr config); std::unique_ptr make_lru_allocator_config(); @@ -83,42 +84,36 @@ void enable_cache_persistence(LruAllocatorConfig& config, void set_base_address(LruAllocatorConfig& config, size_t addr); -int8_t add_pool(const facebook::cachelib::LruAllocator& cache, +int8_t add_pool(const LruAllocator& cache, folly::StringPiece name, size_t size); -size_t get_unreserved_size(const facebook::cachelib::LruAllocator& cache); +size_t get_unreserved_size(const LruAllocator& cache); size_t get_size(const LruItemHandle& handle); const uint8_t* get_memory(const LruItemHandle& handle); uint8_t* get_writable_memory(LruItemHandle& handle); -size_t get_item_ptr_as_offset(const facebook::cachelib::LruAllocator& cache, - const uint8_t* ptr); - -std::unique_ptr allocate_item( - const facebook::cachelib::LruAllocator& cache, - facebook::cachelib::PoolId id, - folly::StringPiece key, - uint32_t size, - uint32_t ttlSecs); - -bool insert_handle(const facebook::cachelib::LruAllocator& cache, - LruItemHandle& handle); -void insert_or_replace_handle(const facebook::cachelib::LruAllocator& cache, - LruItemHandle& handle); - -void remove_item(const facebook::cachelib::LruAllocator& cache, - folly::StringPiece key); -std::unique_ptr find_item( - const facebook::cachelib::LruAllocator& cache, folly::StringPiece key); -size_t get_pool_size(const facebook::cachelib::LruAllocator& cache, - facebook::cachelib::PoolId id); -bool grow_pool(const facebook::cachelib::LruAllocator& cache, +size_t get_item_ptr_as_offset(const LruAllocator& cache, const uint8_t* ptr); + +std::unique_ptr allocate_item(const LruAllocator& cache, + facebook::cachelib::PoolId id, + folly::StringPiece key, + uint32_t size, + uint32_t ttlSecs); + +bool insert_handle(const LruAllocator& cache, LruItemHandle& handle); +void insert_or_replace_handle(const LruAllocator& cache, LruItemHandle& handle); + +void remove_item(const LruAllocator& cache, folly::StringPiece key); +std::unique_ptr find_item(const LruAllocator& cache, + folly::StringPiece key); +size_t get_pool_size(const LruAllocator& cache, facebook::cachelib::PoolId id); +bool grow_pool(const LruAllocator& cache, facebook::cachelib::PoolId id, size_t size); -bool shrink_pool(const facebook::cachelib::LruAllocator& cache, +bool shrink_pool(const LruAllocator& cache, facebook::cachelib::PoolId id, size_t size); -bool resize_pools(const facebook::cachelib::LruAllocator& cache, +bool resize_pools(const LruAllocator& cache, facebook::cachelib::PoolId src, facebook::cachelib::PoolId dst, size_t size); diff --git a/cachelib/rust/src/lib.rs b/cachelib/rust/src/lib.rs index 67a36d3ea..172765367 100644 --- a/cachelib/rust/src/lib.rs +++ b/cachelib/rust/src/lib.rs @@ -47,7 +47,6 @@ mod ffi { oncall: &CxxString, ) -> Result>; - #[namespace = "facebook::cachelib"] type LruAllocator; fn make_lru_allocator( config: UniquePtr, From 8dc9c54a836b9a4d72acb859cfc3e536a604772e Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Tue, 21 Mar 2023 13:55:14 -0700 Subject: [PATCH 62/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/3061f460cea2eca8f9352cb1e8b21c24d4407832 https://github.com/facebook/litho/commit/88b4d2fe908b19aaa53c8cf1deb2aee2b6e95d2e https://github.com/facebookincubator/fizz/commit/b4ab462a8a03e37d66d6077025b51725cca1d4e5 https://github.com/facebookincubator/katran/commit/57d76b2a708b875de92df508c07a7ebd4190a9ef https://github.com/facebookincubator/mvfst/commit/48992ed15a68f588a7c68915ac19237859e04c55 https://github.com/facebookincubator/velox/commit/ac2c20c05497050e1fbaba2d3a82695f34b5f791 Reviewed By: bigfootjon fbshipit-source-id: 52152944da153f1acfaf429f1d7f80c36953e105 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 7137d3433..3061f460c 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 7137d3433d63ff901e8a16f72e48de4b7daa0a6b +Subproject commit 3061f460cea2eca8f9352cb1e8b21c24d4407832 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 30686d6cb..b4ab462a8 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 30686d6cb0ec3a496c3364b4e75228cb4cfd7285 +Subproject commit b4ab462a8a03e37d66d6077025b51725cca1d4e5 From f49158311607723a66ae0a683cebb52447a4532b Mon Sep 17 00:00:00 2001 From: Peter Dillinger Date: Tue, 21 Mar 2023 14:35:14 -0700 Subject: [PATCH 63/92] Update CachelibWrapperTest for RocksDB 8.1.0 Summary: API change to CacheItemHelper affecting advanced test code like this. Reviewed By: ltamasi Differential Revision: D44245094 fbshipit-source-id: d5686184e6e466c63ef0ed8239ae1eafe22758a5 --- .../tests/CachelibWrapperTest.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/cachelib/adaptor/rocks_secondary_cache/tests/CachelibWrapperTest.cpp b/cachelib/adaptor/rocks_secondary_cache/tests/CachelibWrapperTest.cpp index 5dd416f14..827c25bd6 100644 --- a/cachelib/adaptor/rocks_secondary_cache/tests/CachelibWrapperTest.cpp +++ b/cachelib/adaptor/rocks_secondary_cache/tests/CachelibWrapperTest.cpp @@ -116,6 +116,10 @@ class CachelibWrapperTest : public ::testing::Test { } #endif +#if ROCKSDB_MAJOR > 8 || (ROCKSDB_MAJOR == 8 && ROCKSDB_MINOR >= 1) + static Cache::CacheItemHelper helper_no_secondary_; +#endif + static Cache::CacheItemHelper helper_; static Status SaveToCallbackFail(void* /*obj*/, @@ -191,13 +195,23 @@ class CachelibWrapperTest : public ::testing::Test { std::string path_; }; +#if ROCKSDB_MAJOR > 8 || (ROCKSDB_MAJOR == 8 && ROCKSDB_MINOR >= 1) +Cache::CacheItemHelper CachelibWrapperTest::helper_no_secondary_( + CacheEntryRole::kMisc, CachelibWrapperTest::DeletionCallback); +#endif + Cache::CacheItemHelper CachelibWrapperTest::helper_( #if ROCKSDB_MAJOR > 7 || (ROCKSDB_MAJOR == 7 && ROCKSDB_MINOR >= 10) CacheEntryRole::kMisc, CachelibWrapperTest::DeletionCallback, CachelibWrapperTest::SizeCallback, CachelibWrapperTest::SaveToCallback, +#if ROCKSDB_MAJOR > 8 || (ROCKSDB_MAJOR == 8 && ROCKSDB_MINOR >= 1) + CachelibWrapperTest::CreateCallback, + &CachelibWrapperTest::helper_no_secondary_); +#else CachelibWrapperTest::CreateCallback); +#endif #else CachelibWrapperTest::SizeCallback, CachelibWrapperTest::SaveToCallback, @@ -210,7 +224,12 @@ Cache::CacheItemHelper CachelibWrapperTest::helper_fail_( CachelibWrapperTest::DeletionCallback, CachelibWrapperTest::SizeCallback, CachelibWrapperTest::SaveToCallbackFail, +#if ROCKSDB_MAJOR > 8 || (ROCKSDB_MAJOR == 8 && ROCKSDB_MINOR >= 1) + CachelibWrapperTest::CreateCallback, + &CachelibWrapperTest::helper_no_secondary_); +#else CachelibWrapperTest::CreateCallback); +#endif #else CachelibWrapperTest::SizeCallback, CachelibWrapperTest::SaveToCallbackFail, From c8b48b141d58ed08811fa15a4b1e382cd52940fc Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Tue, 21 Mar 2023 14:53:31 -0700 Subject: [PATCH 64/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/cachelib/commit/8dc9c54a836b9a4d72acb859cfc3e536a604772e https://github.com/facebook/fb303/commit/a7ab488399b4911c780b3c372cc75a92b6c53fcf https://github.com/facebook/fbthrift/commit/eaa6fde63a1330b3fdfefcaae89209f420816844 https://github.com/facebook/folly/commit/29eb23ccdbecbc1e6197570828706742bebc3ece https://github.com/facebook/proxygen/commit/4d560c5a3e9ec1c3ef29b5deea8f12167294c8e3 https://github.com/facebook/wangle/commit/73033504df3b1c28a2e668e0615ba6e7b5739a6b https://github.com/facebook/watchman/commit/54872da7a4873b1d84259209f92ca1817a42a071 https://github.com/facebookexperimental/edencommon/commit/0651eb89714606b9abfe60d2d9add8dea565ff50 https://github.com/facebookexperimental/rust-shed/commit/52e6d84d67a6a45310f554658f794491aa48228b https://github.com/facebookincubator/katran/commit/a1a3a08d698451bdceb7258859ac7957092842e4 https://github.com/facebookincubator/mvfst/commit/bef99ca42a969e2e0045c36e1466cd95c455f558 https://github.com/facebookincubator/velox/commit/89c433b0ff68bc92fcac481e99ba363e8e09bb23 Reviewed By: bigfootjon fbshipit-source-id: 86050d5a10cc21ddab5bbceaf4baaa5ba2591b01 --- cachelib/external/fbthrift | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 3061f460c..eaa6fde63 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 3061f460cea2eca8f9352cb1e8b21c24d4407832 +Subproject commit eaa6fde63a1330b3fdfefcaae89209f420816844 diff --git a/cachelib/external/folly b/cachelib/external/folly index 4fa3680ee..29eb23ccd 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 4fa3680ee47f4c8542fd06f873cdc1d5bfccf4f6 +Subproject commit 29eb23ccdbecbc1e6197570828706742bebc3ece diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 7843da5c5..73033504d 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 7843da5c509c7a4dce6a540b499b6159bdc4f14e +Subproject commit 73033504df3b1c28a2e668e0615ba6e7b5739a6b From bdb1fc6c7b241fd42e55504bec196f72260595e8 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Wed, 22 Mar 2023 06:53:57 -0700 Subject: [PATCH 65/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fb303/commit/5dada62db6b0addaa95b7b4f8e777272bda84ca8 https://github.com/facebook/fbthrift/commit/5782f9406bd343e3807ed1ed175f4bc7882b11d7 https://github.com/facebook/litho/commit/ef3b93e2521cb6bf79e1775360b1d469c6a50f29 https://github.com/facebook/proxygen/commit/9a630964e844ea8b3a66102719b1ca27618a4551 https://github.com/facebook/wangle/commit/8e88e6088495515ac9db73cd33d8696968a45624 https://github.com/facebook/watchman/commit/d2fb4037c0851f95eeb5e24c492257168e3de715 https://github.com/facebookexperimental/edencommon/commit/e04a87f16d1fbbb68ab5f177b01983241c55addd https://github.com/facebookexperimental/rust-shed/commit/e638a9949fa52f51ed6921b3d7cd5acaab8ed83b https://github.com/facebookincubator/fizz/commit/8d6e1c7c34361e53cb8bdfd67a138561879970c9 https://github.com/facebookincubator/katran/commit/14c83d3e4132e9a22a6f21f2c23a792432265ae7 https://github.com/facebookincubator/mvfst/commit/4f24529df06e9155543f1f446e3682d6601830ca https://github.com/facebookincubator/velox/commit/404237b3a34f97a112846d5dc0ea7efa6a076b19 Reviewed By: bigfootjon fbshipit-source-id: 25c61fba0e567a9dc87f6cc7dc5ba7bb0e0ccdaa --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index eaa6fde63..5782f9406 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit eaa6fde63a1330b3fdfefcaae89209f420816844 +Subproject commit 5782f9406bd343e3807ed1ed175f4bc7882b11d7 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index b4ab462a8..8d6e1c7c3 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit b4ab462a8a03e37d66d6077025b51725cca1d4e5 +Subproject commit 8d6e1c7c34361e53cb8bdfd67a138561879970c9 diff --git a/cachelib/external/folly b/cachelib/external/folly index 29eb23ccd..270c5e2bf 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 29eb23ccdbecbc1e6197570828706742bebc3ece +Subproject commit 270c5e2bffd5207a5f2bb4e444e8161e8b976676 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 73033504d..8e88e6088 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 73033504df3b1c28a2e668e0615ba6e7b5739a6b +Subproject commit 8e88e6088495515ac9db73cd33d8696968a45624 From 02ef4a1559516e94c395db04183208162d22d0fa Mon Sep 17 00:00:00 2001 From: Jaesoo Lee Date: Wed, 22 Mar 2023 10:09:11 -0700 Subject: [PATCH 66/92] properly support a file-backed nvm cache Summary: Previously, in order to use a file as the backing store of nvm cache, user needs to create the file with the given size a priori, hurting the usability of the feature. This change fixes it so that the new file with the given size is automatically created if not exist. Also, if the file exists with different size, this change will allow the cachebench to ftruncate or fallocate to the given size automatically. Reviewed By: therealgymmy Differential Revision: D44154281 fbshipit-source-id: c622102d4d67b64da83dcad4fdade66473d70a1f --- cachelib/cachebench/cache/Cache-inl.h | 21 +++++++++++++++++++-- cachelib/cachebench/runner/CacheStressor.h | 10 ++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/cachelib/cachebench/cache/Cache-inl.h b/cachelib/cachebench/cache/Cache-inl.h index dc5e878fc..750abdf43 100644 --- a/cachelib/cachebench/cache/Cache-inl.h +++ b/cachelib/cachebench/cache/Cache-inl.h @@ -124,24 +124,41 @@ Cache::Cache(const CacheConfig& config, // already have a file, user provided it. We will also keep it around // after the tests. auto path = config_.nvmCachePaths[0]; - if (cachelib::util::isDir(path)) { + bool isDir; + try { + isDir = cachelib::util::isDir(path); + } catch (const std::system_error& e) { + XLOGF(INFO, "nvmCachePath {} does not exist", path); + isDir = false; + } + + if (isDir) { const auto uniqueSuffix = folly::sformat("nvmcache_{}_{}", ::getpid(), folly::Random::rand32()); path = path + "/" + uniqueSuffix; util::makeDir(path); nvmCacheFilePath_ = path; + XLOGF(INFO, "Configuring NVM cache: directory {} size {} MB", path, + config_.nvmCacheSizeMB); nvmConfig.navyConfig.setSimpleFile(path + "/navy_cache", config_.nvmCacheSizeMB * MB, true /*truncateFile*/); } else { - nvmConfig.navyConfig.setSimpleFile(path, config_.nvmCacheSizeMB * MB); + XLOGF(INFO, "Configuring NVM cache: simple file {} size {} MB", path, + config_.nvmCacheSizeMB); + nvmConfig.navyConfig.setSimpleFile(path, config_.nvmCacheSizeMB * MB, + true /* truncateFile */); } } else if (config_.nvmCachePaths.size() > 1) { + XLOGF(INFO, "Configuring NVM cache: RAID-0 ({} devices) size {} MB", + config_.nvmCachePaths.size(), config_.nvmCacheSizeMB); // set up a software raid-0 across each nvm cache path. nvmConfig.navyConfig.setRaidFiles(config_.nvmCachePaths, config_.nvmCacheSizeMB * MB); } else { // use memory to mock NVM. + XLOGF(INFO, "Configuring NVM cache: memory file size {} MB", + config_.nvmCacheSizeMB); nvmConfig.navyConfig.setMemoryFile(config_.nvmCacheSizeMB * MB); } nvmConfig.navyConfig.setDeviceMetadataSize(config_.nvmCacheMetadataSizeMB * diff --git a/cachelib/cachebench/runner/CacheStressor.h b/cachelib/cachebench/runner/CacheStressor.h index d2433a734..976414b96 100644 --- a/cachelib/cachebench/runner/CacheStressor.h +++ b/cachelib/cachebench/runner/CacheStressor.h @@ -98,8 +98,14 @@ class CacheStressor : public Stressor { } cacheConfig.nvmWriteBytesCallback = std::bind(&CacheStressor::getNvmBytesWritten, this); - cache_ = std::make_unique(cacheConfig, movingSync, - cacheConfig.cacheDir, config_.touchValue); + try { + cache_ = std::make_unique( + cacheConfig, movingSync, cacheConfig.cacheDir, config_.touchValue); + } catch (const std::exception& e) { + XLOG(INFO) << "Exception while creating cache: " << e.what(); + throw; + } + if (config_.opPoolDistribution.size() > cache_->numPools()) { throw std::invalid_argument(folly::sformat( "more pools specified in the test than in the cache. " From bc4f809d345d0a713d45353ff1228a1761edda1b Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Wed, 22 Mar 2023 11:14:25 -0700 Subject: [PATCH 67/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/cachelib/commit/02ef4a1559516e94c395db04183208162d22d0fa https://github.com/facebook/fbthrift/commit/721caa7ffae522612ee7b362c51a2eef3b301281 https://github.com/facebook/folly/commit/60ffa0fb19839e9f874318c7776d703918a31a8d https://github.com/facebook/litho/commit/47e41c0dd9c66f6de81c2be464a6fddc2f21d1a7 https://github.com/facebookincubator/eigen-fbplugins/commit/742056b0a80350cf2b56a82ed7cbed9be9555de2 https://github.com/facebookincubator/velox/commit/8b883b0b04ae63181650a2fd8a97ffe798269a39 Reviewed By: bigfootjon fbshipit-source-id: 299df33a51a79533d3b9000f087731fa3a71323c --- cachelib/external/fbthrift | 2 +- cachelib/external/folly | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 5782f9406..721caa7ff 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 5782f9406bd343e3807ed1ed175f4bc7882b11d7 +Subproject commit 721caa7ffae522612ee7b362c51a2eef3b301281 diff --git a/cachelib/external/folly b/cachelib/external/folly index 270c5e2bf..60ffa0fb1 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 270c5e2bffd5207a5f2bb4e444e8161e8b976676 +Subproject commit 60ffa0fb19839e9f874318c7776d703918a31a8d From eddfed0daeaf6362718ec6df90064bdf0ece95b1 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Thu, 23 Mar 2023 05:57:00 -0700 Subject: [PATCH 68/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/9b313e2d139b03441c02b3472df288ee52d45697 Reviewed By: bigfootjon fbshipit-source-id: 4398acf93c32d22238246b0df0f01c2605483c97 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 721caa7ff..9b313e2d1 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 721caa7ffae522612ee7b362c51a2eef3b301281 +Subproject commit 9b313e2d139b03441c02b3472df288ee52d45697 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 8d6e1c7c3..9bc6bf2b3 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 8d6e1c7c34361e53cb8bdfd67a138561879970c9 +Subproject commit 9bc6bf2b3c953f7433bc31457bf054665cfacc4d diff --git a/cachelib/external/folly b/cachelib/external/folly index 60ffa0fb1..0c55eb5c0 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 60ffa0fb19839e9f874318c7776d703918a31a8d +Subproject commit 0c55eb5c094858ca76758327080d46d7c1e90d90 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 8e88e6088..d61001ed0 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 8e88e6088495515ac9db73cd33d8696968a45624 +Subproject commit d61001ed00e1f6dc29cfa0f57da31c93dfa377e3 From 4e24c2569a79a2037f6101f914e0993ef49b8d22 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Thu, 23 Mar 2023 23:53:00 -0700 Subject: [PATCH 69/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/6fbae558b056070d5a8ed281e5ec280d3e2296e0 Reviewed By: bigfootjon fbshipit-source-id: 6f8278f6d8c2f25092b24aa41cee5f32c6e5ac3b --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 9b313e2d1..6fbae558b 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 9b313e2d139b03441c02b3472df288ee52d45697 +Subproject commit 6fbae558b056070d5a8ed281e5ec280d3e2296e0 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 9bc6bf2b3..8975eb471 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 9bc6bf2b3c953f7433bc31457bf054665cfacc4d +Subproject commit 8975eb4719d3aafa42707f3663b2e9a7f60a0112 diff --git a/cachelib/external/folly b/cachelib/external/folly index 0c55eb5c0..918bc9df9 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 0c55eb5c094858ca76758327080d46d7c1e90d90 +Subproject commit 918bc9df900c71cd4da36b699738cd222e2c11c2 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index d61001ed0..0571e96ee 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit d61001ed00e1f6dc29cfa0f57da31c93dfa377e3 +Subproject commit 0571e96ee0cfee36748406d3018b23492f55903b From de66749a67676de45c9ffe8d70086e2d9593bfd8 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Fri, 24 Mar 2023 19:08:15 -0700 Subject: [PATCH 70/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/6442718611f3c62c224ffd4e7058ee06370aebbd https://github.com/facebookincubator/fizz/commit/109be99e41b78628cd1c83fe491d8db024bf5e73 Reviewed By: bigfootjon fbshipit-source-id: 9c75f0e170a10e2b6cf1913b407f117f1f4091e5 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 6fbae558b..644271861 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 6fbae558b056070d5a8ed281e5ec280d3e2296e0 +Subproject commit 6442718611f3c62c224ffd4e7058ee06370aebbd diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 8975eb471..109be99e4 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 8975eb4719d3aafa42707f3663b2e9a7f60a0112 +Subproject commit 109be99e41b78628cd1c83fe491d8db024bf5e73 diff --git a/cachelib/external/folly b/cachelib/external/folly index 918bc9df9..77e08c29d 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 918bc9df900c71cd4da36b699738cd222e2c11c2 +Subproject commit 77e08c29d9f3b60b55dd74c1ceede35a8297e586 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 0571e96ee..f5d6dc854 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 0571e96ee0cfee36748406d3018b23492f55903b +Subproject commit f5d6dc8549413ea88025c35652974367f518f8ca From 3c58438e2858963feac904ac9245257198789b53 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sat, 25 Mar 2023 18:03:33 -0700 Subject: [PATCH 71/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/5763f9609bd531166e425ff33903cbbd4c775deb Reviewed By: bigfootjon fbshipit-source-id: 56d3adc9df6b8e900d00622b5a7c08fe75d6c6a5 --- cachelib/external/fbthrift | 2 +- cachelib/external/wangle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 644271861..5763f9609 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 6442718611f3c62c224ffd4e7058ee06370aebbd +Subproject commit 5763f9609bd531166e425ff33903cbbd4c775deb diff --git a/cachelib/external/wangle b/cachelib/external/wangle index f5d6dc854..3f3673fd4 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit f5d6dc8549413ea88025c35652974367f518f8ca +Subproject commit 3f3673fd4696c8e4772b711facc39f65f98cd1ed From d0ec6c7ec718f594ffd389ae8b18d4f4f0203b54 Mon Sep 17 00:00:00 2001 From: generatedunixname89002005287564 Date: Sun, 26 Mar 2023 10:43:31 -0700 Subject: [PATCH 72/92] cachelib_0 Reviewed By: DenisYaroshevskiy Differential Revision: D44396854 fbshipit-source-id: 17d3f4271f1bf8c403519471a54bd910af38814c --- cachelib/cachebench/util/NandWrites.cpp | 4 ++-- .../cachebench/workload/PieceWiseReplayGenerator.cpp | 2 +- cachelib/cachebench/workload/ReplayGeneratorBase.h | 4 ++-- cachelib/shm/ShmCommon.cpp | 12 ++++++------ 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cachelib/cachebench/util/NandWrites.cpp b/cachelib/cachebench/util/NandWrites.cpp index 370ddfa2b..22cfc4d0d 100644 --- a/cachelib/cachebench/util/NandWrites.cpp +++ b/cachelib/cachebench/util/NandWrites.cpp @@ -121,11 +121,11 @@ std::vector getBytesWrittenLine( // /ritten/, so that's what we do here. We just use the first matching // line. std::vector lines; - folly::split("\n", out, lines, true /* ignoreEmpty */); + folly::split('\n', out, lines, true /* ignoreEmpty */); for (const auto& line : lines) { if (line.find("ritten") != std::string::npos) { std::vector fields; - folly::split(" ", line, fields, true /* ignoreEmpty */); + folly::split(' ', line, fields, true /* ignoreEmpty */); return fields; } } diff --git a/cachelib/cachebench/workload/PieceWiseReplayGenerator.cpp b/cachelib/cachebench/workload/PieceWiseReplayGenerator.cpp index 732f2518f..9362a64f7 100644 --- a/cachelib/cachebench/workload/PieceWiseReplayGenerator.cpp +++ b/cachelib/cachebench/workload/PieceWiseReplayGenerator.cpp @@ -90,7 +90,7 @@ void PieceWiseReplayGenerator::getReqFromTrace() { try { std::vector fields; - folly::split(",", line, fields); + folly::split(',', line, fields); // TODO: remove this after legacy data phased out. if (fields.size() > totalFieldCount || diff --git a/cachelib/cachebench/workload/ReplayGeneratorBase.h b/cachelib/cachebench/workload/ReplayGeneratorBase.h index bdff5a59e..ee3e4d980 100644 --- a/cachelib/cachebench/workload/ReplayGeneratorBase.h +++ b/cachelib/cachebench/workload/ReplayGeneratorBase.h @@ -65,7 +65,7 @@ class TraceFileStream { // Parses a line from the trace file into a vector. // Returns an empty vector std::vector splitRow; - folly::split(",", line, splitRow); + folly::split(',', line, splitRow); if (splitRow.size() != columnKeyMap_.size()) { XLOG_EVERY_MS(WARNING, 1000) << "Expected row with " << columnKeyMap_.size() @@ -134,7 +134,7 @@ class TraceFileStream { } void parseHeaderRow(const std::string& header) { - folly::split(",", header, keys_); + folly::split(',', header, keys_); for (size_t i = 0; i < keys_.size(); i++) { columnKeyMap_.emplace(folly::to(keys_[i]), i); } diff --git a/cachelib/shm/ShmCommon.cpp b/cachelib/shm/ShmCommon.cpp index 898d43bf3..f7163f26d 100644 --- a/cachelib/shm/ShmCommon.cpp +++ b/cachelib/shm/ShmCommon.cpp @@ -63,7 +63,7 @@ size_t pageAligned(size_t size, PageSizeT p) { namespace { std::vector getSmapLines(const std::string& smapContent) { std::vector lines; - folly::split("\n", smapContent, lines, true); + folly::split('\n', smapContent, lines, true); XDCHECK(!lines.empty()); return lines; } @@ -81,14 +81,14 @@ bool lineAddressMatches(folly::StringPiece line, uintptr_t addr) { std::vector tokens; // split into tokens by space - folly::split(" ", line, tokens, /* ignore empty */ true); + folly::split(' ', line, tokens, /* ignore empty */ true); XDCHECK(!tokens.empty()); folly::StringPiece startAddr; folly::StringPiece endAddr; // split the first token using the '-' separator - if (!folly::split("-", tokens[0], startAddr, endAddr)) { + if (!folly::split('-', tokens[0], startAddr, endAddr)) { throw std::invalid_argument( folly::sformat("Invalid address field {}", tokens[0])); } @@ -103,7 +103,7 @@ bool isAddressLine(folly::StringPiece line) { // address lines contain lots of fields before the first : // 006de000-01397000 rw-p 00000000 00:00 0 [heap] folly::StringPiece first, second; - folly::split(":", line, first, second); + folly::split(':', line, first, second); return first.find(' ') != std::string::npos; } @@ -133,7 +133,7 @@ PageSizeT getPageSizeInSMap(void* addr) { // Format is the following // KernelPageSize: 4 kB folly::StringPiece fieldName, value; - folly::split(":", line, fieldName, value); + folly::split(':', line, fieldName, value); if (fieldName != "MMUPageSize") { continue; } @@ -142,7 +142,7 @@ PageSizeT getPageSizeInSMap(void* addr) { folly::StringPiece sizeVal; folly::StringPiece unitVal; - folly::split(" ", value, sizeVal, unitVal); + folly::split(' ', value, sizeVal, unitVal); XDCHECK_EQ(unitVal, "kB"); size_t size = folly::to(sizeVal) * 1024; if (size == getPageSize(PageSizeT::TWO_MB)) { From 4388290b04ecf5d72a1ab8ed8aaaa979fe18687b Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sun, 26 Mar 2023 21:47:47 -0700 Subject: [PATCH 73/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/48771f2cb12529fdfb1f8765f4376b5a589bf4cc Reviewed By: bigfootjon fbshipit-source-id: 9c68f2e95e7b8007941238d42a6714682c5e4d68 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 5763f9609..48771f2cb 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 5763f9609bd531166e425ff33903cbbd4c775deb +Subproject commit 48771f2cb12529fdfb1f8765f4376b5a589bf4cc From 150394350316b1201e66b8c2dfdd9383afdc81da Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Mon, 27 Mar 2023 20:09:45 -0700 Subject: [PATCH 74/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/53fffa9bf98364e50dd04593be72cd9c29b37955 https://github.com/facebook/wangle/commit/2ee1978ac4282fb679eec8b39fcef15071caa3c3 https://github.com/facebookexperimental/edencommon/commit/deb808973dff0e513a25668a34e1317b37b8f320 https://github.com/facebookincubator/fizz/commit/71ea881f4402f4caf1190fb8cd2bc33db37617da https://github.com/facebookincubator/katran/commit/25da03aede15dea3d3ec8fce7f25532e5f2fcf4f https://github.com/facebookincubator/mvfst/commit/bf7de7f41265ad1c68a1d22bf2ab1184c087320d https://github.com/facebookincubator/velox/commit/651e597c38c447c660d40dfa89777000de5c105c Reviewed By: jailby fbshipit-source-id: f87121525892ad347dcf6d8d9d809828fc737de5 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 48771f2cb..53fffa9bf 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 48771f2cb12529fdfb1f8765f4376b5a589bf4cc +Subproject commit 53fffa9bf98364e50dd04593be72cd9c29b37955 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 109be99e4..71ea881f4 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 109be99e41b78628cd1c83fe491d8db024bf5e73 +Subproject commit 71ea881f4402f4caf1190fb8cd2bc33db37617da diff --git a/cachelib/external/folly b/cachelib/external/folly index 77e08c29d..ac8a5b46e 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 77e08c29d9f3b60b55dd74c1ceede35a8297e586 +Subproject commit ac8a5b46e2e79668e14248b56e25b42e714492e5 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 3f3673fd4..2ee1978ac 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 3f3673fd4696c8e4772b711facc39f65f98cd1ed +Subproject commit 2ee1978ac4282fb679eec8b39fcef15071caa3c3 From f373e231f65ad0f47ebeb898e53d2959ccce6c30 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Tue, 28 Mar 2023 08:18:40 -0700 Subject: [PATCH 75/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/7ab0a877d94a75b92c9dabbcf6ac1002a9f012b9 https://github.com/facebook/proxygen/commit/22104db7374844d28af446e1429994ca4ad63862 https://github.com/facebook/watchman/commit/43ed48ac18131c275d87e10d8e5fb1c03e5f20bb https://github.com/facebookincubator/katran/commit/926b507cdf5e07083bc0b2d03c9e9cefa2661729 https://github.com/facebookincubator/velox/commit/3159ba91de55af0dabdb724130a5461049fbb6f6 Reviewed By: jailby fbshipit-source-id: 25e30991c7cb2da16ff3966627ff5a7fc182a553 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 53fffa9bf..7ab0a877d 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 53fffa9bf98364e50dd04593be72cd9c29b37955 +Subproject commit 7ab0a877d94a75b92c9dabbcf6ac1002a9f012b9 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 71ea881f4..803468b20 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 71ea881f4402f4caf1190fb8cd2bc33db37617da +Subproject commit 803468b20f74826479d448a4b044a9973b78e736 diff --git a/cachelib/external/folly b/cachelib/external/folly index ac8a5b46e..3f0f544ba 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit ac8a5b46e2e79668e14248b56e25b42e714492e5 +Subproject commit 3f0f544ba4b6743836e4d30a0af848b1218f0bcb From 22d3fe6db4928007c597eca37d559854f45fd5df Mon Sep 17 00:00:00 2001 From: Jiayue Bao Date: Tue, 28 Mar 2023 10:11:29 -0700 Subject: [PATCH 76/92] Track object size for mutated objects Summary: When size-awareness is enabled for mutable workloads, user must call `objCache_->mutateObject(objPtr, mutationCb)` so that object-cache can track the updated size. What should happen inside `mutationCb`? 1. a construction of the new value with deep copy 2. if the new value is going to replace an old value, a destruction of the old value See unit test for examples. ----- Reviewed By: jaesoo-fb Differential Revision: D42872059 fbshipit-source-id: b94eddd6d640a04ee7974f9273509e60d5aa6915 --- .../experimental/objcache2/ObjectCache-inl.h | 43 ++++ cachelib/experimental/objcache2/ObjectCache.h | 34 ++- .../objcache2/tests/ObjectCacheTest.cpp | 239 ++++++++++++++++++ 3 files changed, 315 insertions(+), 1 deletion(-) diff --git a/cachelib/experimental/objcache2/ObjectCache-inl.h b/cachelib/experimental/objcache2/ObjectCache-inl.h index 9f1b91631..18aae657c 100644 --- a/cachelib/experimental/objcache2/ObjectCache-inl.h +++ b/cachelib/experimental/objcache2/ObjectCache-inl.h @@ -415,6 +415,49 @@ bool ObjectCache::recover() { return restorer.run(); } +template +template +void ObjectCache::mutateObject(const std::shared_ptr& object, + std::function mutateCb, + const std::string& mutateCtx) { + if (!object) { + return; + } + + cachelib::objcache2::ThreadMemoryTracker tMemTracker; + size_t memUsageBefore = tMemTracker.getMemUsageBytes(); + mutateCb(); + size_t memUsageAfter = tMemTracker.getMemUsageBytes(); + + auto& hdl = getWriteHandleRefInternal(object); + size_t memUsageDiff = 0; + size_t oldObjectSize = 0; + if (memUsageAfter > memUsageBefore) { // updated to a larger value + memUsageDiff = memUsageAfter - memUsageBefore; + // do atomic update on objectSize + oldObjectSize = __sync_fetch_and_add( + &(reinterpret_cast(hdl->getMemory())->objectSize), + memUsageDiff); + totalObjectSizeBytes_.fetch_add(memUsageDiff, std::memory_order_relaxed); + } else if (memUsageAfter < memUsageBefore) { // updated to a smaller value + memUsageDiff = memUsageBefore - memUsageAfter; + // do atomic update on objectSize + oldObjectSize = __sync_fetch_and_sub( + &(reinterpret_cast(hdl->getMemory())->objectSize), + memUsageDiff); + totalObjectSizeBytes_.fetch_sub(memUsageDiff, std::memory_order_relaxed); + } + + // TODO T149177357: for debugging purpose, remove the log later + XLOGF_EVERY_MS( + INFO, 60'000, + "[Object-Cache mutate][{}] type: {}, memUsageBefore: {}, memUsageAfter: " + "{}, memUsageDiff:{}, oldObjectSize: {}, curObjectSize: {}, " + "curTotalObjectSize: {}", + mutateCtx, typeid(T).name(), memUsageBefore, memUsageAfter, memUsageDiff, + oldObjectSize, getObjectSize(object), getTotalObjectSize()); +} + } // namespace objcache2 } // namespace cachelib } // namespace facebook diff --git a/cachelib/experimental/objcache2/ObjectCache.h b/cachelib/experimental/objcache2/ObjectCache.h index 125321328..934d4c92d 100644 --- a/cachelib/experimental/objcache2/ObjectCache.h +++ b/cachelib/experimental/objcache2/ObjectCache.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "cachelib/allocator/CacheAllocator.h" @@ -38,6 +39,7 @@ #include "cachelib/experimental/objcache2/ObjectCacheSizeController.h" #include "cachelib/experimental/objcache2/persistence/Persistence.h" #include "cachelib/experimental/objcache2/persistence/gen-cpp2/persistent_data_types.h" +#include "cachelib/experimental/objcache2/util/ThreadMemoryTracker.h" namespace facebook { namespace cachelib { @@ -324,6 +326,36 @@ class ObjectCache : public ObjectCacheBase { return getWriteHandleRefInternal(object)->extendTTL(ttl); } + // Mutate object and update the object size + // When size-awareness is enabled, users must call this API to mutate the + // object. Otherwise, we won't be able to track the updated object size + // + // @param object shared pointer of the object to be mutated (must be + // fetched from ObjectCache APIs) + // @param mutateCb callback containing the mutation logic + // @param mutateCtx context string of this mutation operation, for + // logging purpose + template + void mutateObject(const std::shared_ptr& object, + std::function mutateCb, + const std::string& mutateCtx = ""); + + // Get the size of the object + // + // @param object object shared pointer returned from ObjectCache APIs + // + // @return the object size if size-awareness is enabled + // 0 otherwise + template + size_t getObjectSize(const std::shared_ptr& object) const { + if (!object) { + return 0; + } + return reinterpret_cast( + getReadHandleRefInternal(object)->getMemory()) + ->objectSize; + } + protected: // Serialize cache allocator config for exporting to Scuba std::map serializeConfigParams() const override; @@ -378,7 +410,7 @@ class ObjectCache : public ObjectCacheBase { // Get a WriteHandle reference from the object shared_ptr template typename AllocatorT::WriteHandle& getWriteHandleRefInternal( - std::shared_ptr& object) { + const std::shared_ptr& object) { auto* deleter = std::get_deleter>(object); XDCHECK(deleter != nullptr); auto& hdl = deleter->getWriteHandleRef(); diff --git a/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp b/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp index 701654cd1..dbfcd5b6a 100644 --- a/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp +++ b/cachelib/experimental/objcache2/tests/ObjectCacheTest.cpp @@ -16,6 +16,9 @@ #include +#include +#include + #include "cachelib/allocator/CacheAllocator.h" #include "cachelib/experimental/objcache2/ObjectCache.h" #include "cachelib/experimental/objcache2/persistence/gen-cpp2/persistent_data_types.h" @@ -569,6 +572,235 @@ class ObjectCacheTest : public ::testing::Test { EXPECT_EQ(3, found2->c); } + template + void checkObjectSizeTracking(ObjectCache& objcache, + const std::shared_ptr& object, + std::function mutateCb) { + objcache.mutateObject(object, std::move(mutateCb)); + + ThreadMemoryTracker tMemTracker; + auto memUsage1 = tMemTracker.getMemUsageBytes(); + auto objectCopy = std::make_unique(*object); + auto memUsage2 = tMemTracker.getMemUsageBytes(); + + EXPECT_EQ(memUsage2 - memUsage1, objcache.template getObjectSize(object)); + } + + void checkTotalObjectSize(ObjectCache& objcache) { + size_t totalObjectSize = 0; + for (auto itr = objcache.getL1Cache().begin(); + itr != objcache.getL1Cache().end(); + ++itr) { + totalObjectSize += + reinterpret_cast(itr.asHandle()->getMemory()) + ->objectSize; + } + EXPECT_EQ(totalObjectSize, objcache.getTotalObjectSize()); + } + + void checkObjectSizeTrackingUnorderedMap() { + using ObjectType = std::unordered_map; + ObjectCacheConfig config; + config.setCacheName("test") + .setCacheCapacity(10'000 /* l1EntriesLimit*/) + .setItemDestructor([&](ObjectCacheDestructorData data) { + data.deleteObject(); + }); + config.objectSizeTrackingEnabled = true; + auto objcache = ObjectCache::create(config); + + // create an empty map + ThreadMemoryTracker tMemTracker; + auto memUsage1 = tMemTracker.getMemUsageBytes(); + auto map = std::make_unique(); + auto memUsage2 = tMemTracker.getMemUsageBytes(); + + auto [_, ptr, __] = objcache->insertOrReplace("cacheKey", std::move(map), + memUsage2 - memUsage1); + EXPECT_EQ(memUsage2 - memUsage1, objcache->template getObjectSize(ptr)); + EXPECT_EQ(memUsage2 - memUsage1, objcache->getTotalObjectSize()); + + auto found = objcache->template findToWrite("cacheKey"); + ASSERT_NE(nullptr, found); + + // add an entry + auto cb1 = [&found]() { (*found)["key"] = "tiny"; }; + // replace the entry with a longer string + auto cb2 = [&found]() { + (*found)["key"] = "longgggggggggggggggggggggggggggstringgggggggggggg"; + }; + // replace the entry with a shorter string + auto cb3 = [&found]() { + auto tmp = std::make_unique("short"); + using std::swap; + swap((*found)["key"], *tmp); + }; + // remove the entry + auto cb4 = [&found]() { found->erase("key"); }; + + checkObjectSizeTracking(*objcache, found, std::move(cb1)); + checkTotalObjectSize(*objcache); + + checkObjectSizeTracking(*objcache, found, std::move(cb2)); + checkTotalObjectSize(*objcache); + + checkObjectSizeTracking(*objcache, found, std::move(cb3)); + checkTotalObjectSize(*objcache); + + checkObjectSizeTracking(*objcache, found, std::move(cb4)); + checkTotalObjectSize(*objcache); + } + + void checkObjectSizeTrackingVector() { + using ObjectType = std::vector; + ObjectCacheConfig config; + config.setCacheName("test") + .setCacheCapacity(10'000 /* l1EntriesLimit*/) + .setItemDestructor([&](ObjectCacheDestructorData data) { + data.deleteObject(); + }); + config.objectSizeTrackingEnabled = true; + auto objcache = ObjectCache::create(config); + + // create an empty vector + ThreadMemoryTracker tMemTracker; + auto memUsage1 = tMemTracker.getMemUsageBytes(); + auto vec = std::make_unique(); + auto memUsage2 = tMemTracker.getMemUsageBytes(); + + auto [_, ptr, __] = objcache->insertOrReplace("cacheKey", std::move(vec), + memUsage2 - memUsage1); + EXPECT_EQ(memUsage2 - memUsage1, objcache->template getObjectSize(ptr)); + EXPECT_EQ(memUsage2 - memUsage1, objcache->getTotalObjectSize()); + + auto found = objcache->template findToWrite("cacheKey"); + ASSERT_NE(nullptr, found); + + // add an entry using emplace_back + auto cb1 = [&found]() { found->emplace_back(Foo{1, 2, 3}); }; + + // add another entry using push_back + auto cb2 = [&found]() { found->push_back(Foo{4, 5, 6}); }; + + // remove the entry from the end using pop_back + auto cb3 = [&found]() { + found->pop_back(); + found->shrink_to_fit(); + }; + + checkObjectSizeTracking(*objcache, found, std::move(cb1)); + checkTotalObjectSize(*objcache); + + checkObjectSizeTracking(*objcache, found, std::move(cb2)); + checkTotalObjectSize(*objcache); + + checkObjectSizeTracking(*objcache, found, std::move(cb3)); + checkTotalObjectSize(*objcache); + } + + void checkObjectSizeTrackingString() { + using ObjectType = std::string; + ObjectCacheConfig config; + config.setCacheName("test") + .setCacheCapacity(10'000 /* l1EntriesLimit*/) + .setItemDestructor([&](ObjectCacheDestructorData data) { + data.deleteObject(); + }); + config.objectSizeTrackingEnabled = true; + auto objcache = ObjectCache::create(config); + + // create an empty string + ThreadMemoryTracker tMemTracker; + auto memUsage1 = tMemTracker.getMemUsageBytes(); + auto str = std::make_unique(); + auto memUsage2 = tMemTracker.getMemUsageBytes(); + + auto [_, ptr, __] = objcache->insertOrReplace("cacheKey", std::move(str), + memUsage2 - memUsage1); + EXPECT_EQ(memUsage2 - memUsage1, objcache->template getObjectSize(ptr)); + EXPECT_EQ(memUsage2 - memUsage1, objcache->getTotalObjectSize()); + + auto found = objcache->template findToWrite("cacheKey"); + ASSERT_NE(nullptr, found); + + // set a value + auto cb1 = [&found]() { *found = "tiny"; }; + // replace the value with a longer string + auto cb2 = [&found]() { + *found = "longgggggggggggggggggggggggggggstringgggggggggggg"; + }; + // replace the value with a shorter string + auto cb3 = [&found]() { + *found = "short"; + (*found).shrink_to_fit(); + }; + + checkObjectSizeTracking(*objcache, found, std::move(cb1)); + checkTotalObjectSize(*objcache); + + checkObjectSizeTracking(*objcache, found, std::move(cb2)); + checkTotalObjectSize(*objcache); + + checkObjectSizeTracking(*objcache, found, std::move(cb3)); + checkTotalObjectSize(*objcache); + } + + void testObjectSizeTrackingWithMutation() { + if (!folly::usingJEMalloc()) { + return; + } + + checkObjectSizeTrackingUnorderedMap(); + checkObjectSizeTrackingVector(); + checkObjectSizeTrackingString(); + } + + void testMultithreadObjectSizeTrackingWithMutation() { + if (!folly::usingJEMalloc()) { + return; + } + + using ObjectType = std::unordered_map; + + ObjectCacheConfig config; + config.setCacheName("test") + .setCacheCapacity(10'000 /* l1EntriesLimit*/) + .setItemDestructor([&](ObjectCacheDestructorData data) { + data.deleteObject(); + }); + config.objectSizeTrackingEnabled = true; + auto objcache = ObjectCache::create(config); + + // create an empty map + ThreadMemoryTracker tMemTracker; + auto memUsage1 = tMemTracker.getMemUsageBytes(); + auto map = std::make_unique(); + auto memUsage2 = tMemTracker.getMemUsageBytes(); + + objcache->insertOrReplace("cacheKey", std::move(map), + memUsage2 - memUsage1); + + auto runMutateObjectOps = [&](int i) { + auto found = objcache->template findToWrite("cacheKey"); + ASSERT_NE(nullptr, found); + objcache->mutateObject(found, [&found, i]() { + (*found)[folly::sformat("key_{}", i)] = folly::sformat("value_{}", i); + }); + }; + + std::vector rs; + for (int i = 0; i < 10; i++) { + rs.push_back(std::thread{runMutateObjectOps, i + 1}); + } + for (int i = 0; i < 10; i++) { + rs[i].join(); + } + + auto found = objcache->template find("cacheKey"); + EXPECT_EQ(objcache->template getObjectSize(found), + objcache->getTotalObjectSize()); + } + void testPersistence() { auto persistBaseFilePath = std::tmpnam(nullptr); ThriftFoo foo1; @@ -1198,6 +1430,13 @@ TYPED_TEST(ObjectCacheTest, ObjectSizeTrackingBasics) { TYPED_TEST(ObjectCacheTest, ObjectSizeTrackingUniqueInsert) { this->testObjectSizeTrackingUniqueInsert(); } +TYPED_TEST(ObjectCacheTest, ObjectSizeTrackingWithMutation) { + this->testObjectSizeTrackingWithMutation(); +} +TYPED_TEST(ObjectCacheTest, MultithreadObjectSizeTrackingWithMutation) { + this->testMultithreadObjectSizeTrackingWithMutation(); +} + TYPED_TEST(ObjectCacheTest, Persistence) { this->testPersistence(); } TYPED_TEST(ObjectCacheTest, PersistenceMultiType) { this->testPersistenceMultiType(); From 6934e0c46ddf9c3418f8d6942832ab8e7e96f5b7 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Tue, 28 Mar 2023 11:59:09 -0700 Subject: [PATCH 77/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/737cfa05e81e552597ca6e295949b2236aa30c44 https://github.com/facebookincubator/mvfst/commit/24e04e1e6412f6d9b39b4aff5961bfe1ada6f06d https://github.com/facebookincubator/velox/commit/55daa3e5de0ebadd52686ba898686e065c8bbaa8 https://github.com/fairinternal/egohowto/commit/f8b18701f1c9f1d18dfc7dbcfbd3a9f2ee0c815d Reviewed By: jailby fbshipit-source-id: e801db60548241573e35446c8676039a893752a9 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 7ab0a877d..737cfa05e 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 7ab0a877d94a75b92c9dabbcf6ac1002a9f012b9 +Subproject commit 737cfa05e81e552597ca6e295949b2236aa30c44 From 9103a54cf047f7065dda1427b1cec79e366ae912 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Wed, 29 Mar 2023 11:57:29 -0700 Subject: [PATCH 78/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/ef080b38796981410965193920960f439a3bce2a https://github.com/facebook/proxygen/commit/a2d125b0707b3c039d6190ede9a138189e98ba6c Reviewed By: jailby fbshipit-source-id: 1b820a1e3c85011c2b6f535caca237a74ec69568 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/wangle | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 737cfa05e..ef080b387 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 737cfa05e81e552597ca6e295949b2236aa30c44 +Subproject commit ef080b38796981410965193920960f439a3bce2a diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 803468b20..5ff0e1302 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 803468b20f74826479d448a4b044a9973b78e736 +Subproject commit 5ff0e1302ceeb8fbc1b40be2605e8a439a72a83f diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 2ee1978ac..8284ac345 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 2ee1978ac4282fb679eec8b39fcef15071caa3c3 +Subproject commit 8284ac3453ed5ba9c78b856cfac7a374acf32a0e From 8a62373249530f9b5e761a424b855f8a9640d143 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Wed, 29 Mar 2023 14:55:53 -0700 Subject: [PATCH 79/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/6b2d7a9eba2871cc7f28ccf3e84bdd8b673a62b4 Reviewed By: jailby fbshipit-source-id: 3ccc40b3a1956cde45388e7e0ffad5d6196c517b --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index ef080b387..6b2d7a9eb 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit ef080b38796981410965193920960f439a3bce2a +Subproject commit 6b2d7a9eba2871cc7f28ccf3e84bdd8b673a62b4 From 7886d6d47d762c237177d6584dbe31756aaed56f Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Wed, 29 Mar 2023 15:53:50 -0700 Subject: [PATCH 80/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/639434b242b94290672b89abfb9d9d2c452a1740 https://github.com/facebook/proxygen/commit/a628b5aabb629775357afbefe423168407f42956 https://github.com/facebook/watchman/commit/2fc3dbac1818de069918621774ea49e13d4eee90 https://github.com/facebookincubator/velox/commit/38d76017914ed7798147e639cb63ed0afef20c5f Reviewed By: jailby fbshipit-source-id: 607d6696a1b803a79a4509c55de96e307f3b698a --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 6b2d7a9eb..639434b24 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 6b2d7a9eba2871cc7f28ccf3e84bdd8b673a62b4 +Subproject commit 639434b242b94290672b89abfb9d9d2c452a1740 From 4f917bbd45037d418992b54b72fc7cb17f5d331e Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Thu, 30 Mar 2023 15:17:19 -0700 Subject: [PATCH 81/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/33a57fc1dd0e5b4fcad29fd98844af1ba47a0e3e Reviewed By: yns88 fbshipit-source-id: a8cc153a7b8c1491ae264b42e4d1aaf6d637aefe --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 639434b24..33a57fc1d 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 639434b242b94290672b89abfb9d9d2c452a1740 +Subproject commit 33a57fc1dd0e5b4fcad29fd98844af1ba47a0e3e diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 5ff0e1302..d17e5d6d5 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 5ff0e1302ceeb8fbc1b40be2605e8a439a72a83f +Subproject commit d17e5d6d5f0ea59707ec5445b0c6b38e3dc68e6f diff --git a/cachelib/external/folly b/cachelib/external/folly index 3f0f544ba..9b2984fee 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 3f0f544ba4b6743836e4d30a0af848b1218f0bcb +Subproject commit 9b2984feea5833dc21ff7dd643a8510a193ba652 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 8284ac345..6f9adcbae 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 8284ac3453ed5ba9c78b856cfac7a374acf32a0e +Subproject commit 6f9adcbae804cbafd671c2fe602d5bb1e7447b0b From dd5a1fd592b97b025d76a4ea9463c07c772dc234 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Fri, 31 Mar 2023 13:59:57 -0700 Subject: [PATCH 82/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fb303/commit/28cfb1dc5077ee6b862b38734fd6729e234502e6 https://github.com/facebook/fbthrift/commit/bb45e17a679c53f5076b13a1985d012edf9c1f82 https://github.com/facebook/watchman/commit/7aa562b9a6a00a6a4d4571de70577bf144f4ddbf https://github.com/facebookexperimental/rust-shed/commit/47f504b7575226d036797821988dce9050b25d06 https://github.com/facebookincubator/velox/commit/58a8e261a6c06746d54dea333ff8b99d88b1cc5c Reviewed By: yns88 fbshipit-source-id: e56b09ecacd3bb3a4a8e7a16148faf44d5b0a437 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 33a57fc1d..bb45e17a6 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 33a57fc1dd0e5b4fcad29fd98844af1ba47a0e3e +Subproject commit bb45e17a679c53f5076b13a1985d012edf9c1f82 From b65597e5283bd48f0ba70bde53e0bc8b08630275 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sat, 1 Apr 2023 00:06:16 -0700 Subject: [PATCH 83/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/d0d294343f0ac0e40a505f0819be83e60cf25604 https://github.com/facebook/proxygen/commit/ce6978b9247f449d3c8a6a4bce1625ed5ccfb373 https://github.com/facebookincubator/velox/commit/aed1ddf1eb96a99664129a7b2678ca3afecbb45a Reviewed By: yns88 fbshipit-source-id: 87cf81b096e7501d13a70ea6062da3e72a39aa65 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index bb45e17a6..d0d294343 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit bb45e17a679c53f5076b13a1985d012edf9c1f82 +Subproject commit d0d294343f0ac0e40a505f0819be83e60cf25604 diff --git a/cachelib/external/fizz b/cachelib/external/fizz index d17e5d6d5..96586696b 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit d17e5d6d5f0ea59707ec5445b0c6b38e3dc68e6f +Subproject commit 96586696b2ea6d93582d0b1cdb5d69182b242742 diff --git a/cachelib/external/folly b/cachelib/external/folly index 9b2984fee..407652256 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 9b2984feea5833dc21ff7dd643a8510a193ba652 +Subproject commit 40765225648a6937622d4c309da429e14542f321 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 6f9adcbae..8ee592d57 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 6f9adcbae804cbafd671c2fe602d5bb1e7447b0b +Subproject commit 8ee592d5750b46c4a7cf4468be3afbaed16c2e3e From 26f4c32a60f4168494f1a7b0f791edfe80d628f8 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sat, 1 Apr 2023 22:47:13 -0700 Subject: [PATCH 84/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/eb2041cfd35e478d41c1c3fe3c20ab4763d8414b https://github.com/facebook/proxygen/commit/c23cd09bd0ee7729d00c3b0642eb59daf7ce058e Reviewed By: yns88 fbshipit-source-id: df09b7f4c50e00d5a1491740c999b9008ccfed0e --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/folly | 2 +- cachelib/external/wangle | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index d0d294343..eb2041cfd 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit d0d294343f0ac0e40a505f0819be83e60cf25604 +Subproject commit eb2041cfd35e478d41c1c3fe3c20ab4763d8414b diff --git a/cachelib/external/fizz b/cachelib/external/fizz index 96586696b..fc2ac83bd 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit 96586696b2ea6d93582d0b1cdb5d69182b242742 +Subproject commit fc2ac83bd90bdbc7183aee6d007286031e95ac01 diff --git a/cachelib/external/folly b/cachelib/external/folly index 407652256..b8b3ed56e 160000 --- a/cachelib/external/folly +++ b/cachelib/external/folly @@ -1 +1 @@ -Subproject commit 40765225648a6937622d4c309da429e14542f321 +Subproject commit b8b3ed56ecd1aff05abe7c2e5085da40e9ffad5f diff --git a/cachelib/external/wangle b/cachelib/external/wangle index 8ee592d57..cb7b7d721 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit 8ee592d5750b46c4a7cf4468be3afbaed16c2e3e +Subproject commit cb7b7d721acb5d26c7adb709fea713b8a5b8a735 From a1df8cdc944894342eb730044b78bba8e5798c7f Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Sun, 2 Apr 2023 23:23:07 -0700 Subject: [PATCH 85/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/ea52832e1283042b58262897c97527b8c2f4698f https://github.com/facebook/proxygen/commit/a080dfe9b4970b0fa432898de4b27796063e7408 https://github.com/facebook/wangle/commit/a153b33438e47b9fb1a8967d923ff72af24582f9 https://github.com/facebookincubator/katran/commit/c24fd07b1435e692461117966ce01d8465c21d49 Reviewed By: yns88 fbshipit-source-id: 9e77bc08070edf5c78c85e856c57defc3b19f454 --- cachelib/external/fbthrift | 2 +- cachelib/external/fizz | 2 +- cachelib/external/wangle | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index eb2041cfd..ea52832e1 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit eb2041cfd35e478d41c1c3fe3c20ab4763d8414b +Subproject commit ea52832e1283042b58262897c97527b8c2f4698f diff --git a/cachelib/external/fizz b/cachelib/external/fizz index fc2ac83bd..459b56077 160000 --- a/cachelib/external/fizz +++ b/cachelib/external/fizz @@ -1 +1 @@ -Subproject commit fc2ac83bd90bdbc7183aee6d007286031e95ac01 +Subproject commit 459b560771a0d67ae33e2a97dc670ec64a074f45 diff --git a/cachelib/external/wangle b/cachelib/external/wangle index cb7b7d721..a153b3343 160000 --- a/cachelib/external/wangle +++ b/cachelib/external/wangle @@ -1 +1 @@ -Subproject commit cb7b7d721acb5d26c7adb709fea713b8a5b8a735 +Subproject commit a153b33438e47b9fb1a8967d923ff72af24582f9 From 206a49e3235f4f23b11bb87c6ae157af549d5440 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Mon, 3 Apr 2023 02:12:35 -0700 Subject: [PATCH 86/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/cd36a5332be67e0465b02cfc3ceb196f07a05696 https://github.com/facebook/watchman/commit/b8c7a3dda03007e824a9c13718f7da884b3522ac Reviewed By: yns88 fbshipit-source-id: a1ce2257a8630a9098f239ca49e294cf3dc6bce0 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index ea52832e1..cd36a5332 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit ea52832e1283042b58262897c97527b8c2f4698f +Subproject commit cd36a5332be67e0465b02cfc3ceb196f07a05696 From aeb15c36fc59c710cfc5501f9530accd2f897859 Mon Sep 17 00:00:00 2001 From: Jiayue Bao Date: Mon, 3 Apr 2023 08:38:33 -0700 Subject: [PATCH 87/92] Make the user-configured entries limit the hard upper bound Summary: As title Reviewed By: jaesoo-fb Differential Revision: D44358110 fbshipit-source-id: d9359f25b9f6f58dd7f22cb0b45dd71b6a73848b --- .../objcache2/ObjectCacheSizeController-inl.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cachelib/experimental/objcache2/ObjectCacheSizeController-inl.h b/cachelib/experimental/objcache2/ObjectCacheSizeController-inl.h index 2bf5de445..66bb5309b 100644 --- a/cachelib/experimental/objcache2/ObjectCacheSizeController-inl.h +++ b/cachelib/experimental/objcache2/ObjectCacheSizeController-inl.h @@ -33,6 +33,9 @@ void ObjectCacheSizeController::work() { objCache_.config_.l1EntriesLimit / 100) { auto averageObjSize = totalObjSize / currentNumEntries; auto newEntriesLimit = objCache_.config_.cacheSizeLimit / averageObjSize; + // entriesLimit should never exceed the configured entries limit + newEntriesLimit = + std::min(newEntriesLimit, objCache_.config_.l1EntriesLimit); if (newEntriesLimit < currentEntriesLimit_ && currentNumEntries >= newEntriesLimit) { // shrink cache when getting a lower new limit and current entries num @@ -46,7 +49,7 @@ void ObjectCacheSizeController::work() { } XLOGF_EVERY_MS(INFO, 60'000, - "CacheLib object-cache: total object size = {}, current " + "CacheLib size-controller: total object size = {}, current " "entries = {}, average object size = " "{}, new entries limit = {}, current entries limit = {}", totalObjSize, currentNumEntries, averageObjSize, @@ -73,7 +76,7 @@ void ObjectCacheSizeController::shrinkCacheByEntriesNum( XLOGF_EVERY_MS( INFO, 60'000, - "CacheLib object-cache: request to shrink cache by {} entries. " + "CacheLib size-controller: request to shrink cache by {} entries. " "Placeholders num before: {}, after: {}. currentEntriesLimit: {}", entries, size, objCache_.placeholders_.size(), currentEntriesLimit_); } @@ -92,7 +95,7 @@ void ObjectCacheSizeController::expandCacheByEntriesNum( XLOGF_EVERY_MS( INFO, 60'000, - "CacheLib object-cache: request to expand cache by {} entries. " + "CacheLib size-controller: request to expand cache by {} entries. " "Placeholders num before: {}, after: {}. currentEntriesLimit: {}", entries, size, objCache_.placeholders_.size(), currentEntriesLimit_); } From f24408d62102008ddbab19e3dc49d517283a5c57 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Mon, 3 Apr 2023 08:45:15 -0700 Subject: [PATCH 88/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fbthrift/commit/59053eb8167b5dc4d6d4f9dc7dd273b73ed0daf8 Reviewed By: yns88 fbshipit-source-id: aea2de1893720da1b9b811c1fe00f3ad432fbfc5 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index cd36a5332..59053eb81 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit cd36a5332be67e0465b02cfc3ceb196f07a05696 +Subproject commit 59053eb8167b5dc4d6d4f9dc7dd273b73ed0daf8 From 6ca670a49f6ec90f524aecd0c972490cd9f182a4 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Mon, 3 Apr 2023 09:40:17 -0700 Subject: [PATCH 89/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/cachelib/commit/f24408d62102008ddbab19e3dc49d517283a5c57 https://github.com/facebook/fb303/commit/f94200e0c20aa468df18bc4b87111fa1e31a72cb https://github.com/facebook/fbthrift/commit/37243b45012920e65255ee1de381ce6f1daca049 https://github.com/facebook/watchman/commit/c875359b1becc9980219377e7b416441af73269b https://github.com/facebookexperimental/rust-shed/commit/2308da6af899c9a165eca4a374222ef5a1342956 https://github.com/facebookresearch/vrs/commit/b14c3eeacc9314fb2d3dd11d6dbec0b113b50dfb Reviewed By: yns88 fbshipit-source-id: 9fc017f649e948fecee547f0afe1569a43dc03f1 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 59053eb81..37243b450 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 59053eb8167b5dc4d6d4f9dc7dd273b73ed0daf8 +Subproject commit 37243b45012920e65255ee1de381ce6f1daca049 From e4d1a9d580d2b89c8f092e5401016a1b29816513 Mon Sep 17 00:00:00 2001 From: Jimmy Lu Date: Mon, 3 Apr 2023 10:00:29 -0700 Subject: [PATCH 90/92] Enable enableFastNegativeLookups by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This should be enabled by default It is an improvement in all cases. It’s roughly the same for hit-path. And, it helps miss path performance since it performs all the checks inline as opposed to thread-hop. Reviewed By: jaesoo-fb Differential Revision: D44554147 fbshipit-source-id: 6ec59d9ac1548ce30199ee1f3c495b92287fb739 --- cachelib/allocator/nvmcache/NvmCache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/allocator/nvmcache/NvmCache.h b/cachelib/allocator/nvmcache/NvmCache.h index c9f5c753f..e00969b51 100644 --- a/cachelib/allocator/nvmcache/NvmCache.h +++ b/cachelib/allocator/nvmcache/NvmCache.h @@ -111,7 +111,7 @@ class NvmCache { // when enabled, nvmcache will attempt to resolve misses without incurring // thread hops by using synchronous methods. - bool enableFastNegativeLookups{false}; + bool enableFastNegativeLookups{true}; // serialize the config for debugging purposes std::map serialize() const; From db523157cbe7c88e6089db99d126ec2dd75b5873 Mon Sep 17 00:00:00 2001 From: Open Source Bot Date: Mon, 3 Apr 2023 10:43:56 -0700 Subject: [PATCH 91/92] Updating submodules Summary: GitHub commits: https://github.com/facebook/fb303/commit/e3d5fe9f25845f1d872971d0fb88aaa4efcb4343 https://github.com/facebook/fbthrift/commit/62c333519d7ee3a47f2d89daf5ae3b164b10560a https://github.com/facebookexperimental/rust-shed/commit/cf98c92130aed51c4d33045ee537474b84a0bacf https://github.com/facebookincubator/velox/commit/0e5889c0d2f048b6dee4e1b09590be1535cc43f7 Reviewed By: yns88 fbshipit-source-id: a4281211b976f5c65929bbc3bd0305225ecabd38 --- cachelib/external/fbthrift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cachelib/external/fbthrift b/cachelib/external/fbthrift index 37243b450..62c333519 160000 --- a/cachelib/external/fbthrift +++ b/cachelib/external/fbthrift @@ -1 +1 @@ -Subproject commit 37243b45012920e65255ee1de381ce6f1daca049 +Subproject commit 62c333519d7ee3a47f2d89daf5ae3b164b10560a From 9187ab7cc8d9283869d71a94f03b70e1b84c808e Mon Sep 17 00:00:00 2001 From: Daniel Byrne Date: Wed, 4 Jan 2023 06:40:10 -0800 Subject: [PATCH 92/92] - Change the cache size calculation to use getCacheSize() - Switch to isUsingPosixShm() method --- cachelib/allocator/CacheAllocator-inl.h | 19 ++++++++++--------- cachelib/allocator/CacheAllocatorConfig.h | 2 +- cachelib/allocator/memory/SlabAllocator.cpp | 4 +++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/cachelib/allocator/CacheAllocator-inl.h b/cachelib/allocator/CacheAllocator-inl.h index 1e23639ba..d18aa8b68 100644 --- a/cachelib/allocator/CacheAllocator-inl.h +++ b/cachelib/allocator/CacheAllocator-inl.h @@ -54,11 +54,11 @@ CacheAllocator::CacheAllocator( : config.memMonitoringEnabled()}, config_(config.validate()), tempShm_(type == InitMemType::kNone && isOnShm_ - ? std::make_unique(config_.size) + ? std::make_unique(config_.getCacheSize()) : nullptr), shmManager_(type != InitMemType::kNone ? std::make_unique(config_.cacheDir, - config_.usePosixShm) + config_.isUsingPosixShm()) : nullptr), deserializer_(type == InitMemType::kMemAttach ? createDeserializer() : nullptr), @@ -122,10 +122,10 @@ CacheAllocator::createNewMemoryAllocator() { return std::make_unique( getAllocatorConfig(config_), shmManager_ - ->createShm(detail::kShmCacheName, config_.size, + ->createShm(detail::kShmCacheName, config_.getCacheSize(), config_.slabMemoryBaseAddr, createShmCacheOpts()) .addr, - config_.size); + config_.getCacheSize()); } template @@ -137,7 +137,7 @@ CacheAllocator::restoreMemoryAllocator() { ->attachShm(detail::kShmCacheName, config_.slabMemoryBaseAddr, createShmCacheOpts()) .addr, - config_.size, + config_.getCacheSize(), config_.disableFullCoredump); } @@ -242,11 +242,12 @@ std::unique_ptr CacheAllocator::initAllocator( InitMemType type) { if (type == InitMemType::kNone) { if (isOnShm_ == true) { - return std::make_unique( - getAllocatorConfig(config_), tempShm_->getAddr(), config_.size); + return std::make_unique(getAllocatorConfig(config_), + tempShm_->getAddr(), + config_.getCacheSize()); } else { return std::make_unique(getAllocatorConfig(config_), - config_.size); + config_.getCacheSize()); } } else if (type == InitMemType::kMemNew) { return createNewMemoryAllocator(); @@ -2259,7 +2260,7 @@ PoolEvictionAgeStats CacheAllocator::getPoolEvictionAgeStats( template CacheMetadata CacheAllocator::getCacheMetadata() const noexcept { return CacheMetadata{kCachelibVersion, kCacheRamFormatVersion, - kCacheNvmFormatVersion, config_.size}; + kCacheNvmFormatVersion, config_.getCacheSize()}; } template diff --git a/cachelib/allocator/CacheAllocatorConfig.h b/cachelib/allocator/CacheAllocatorConfig.h index 9876f33c0..59846b806 100644 --- a/cachelib/allocator/CacheAllocatorConfig.h +++ b/cachelib/allocator/CacheAllocatorConfig.h @@ -1092,7 +1092,7 @@ std::map CacheAllocatorConfig::serialize() const { configMap["size"] = std::to_string(size); configMap["cacheDir"] = cacheDir; - configMap["posixShm"] = usePosixShm ? "set" : "empty"; + configMap["posixShm"] = isUsingPosixShm() ? "set" : "empty"; configMap["defaultAllocSizes"] = ""; // Stringify std::set diff --git a/cachelib/allocator/memory/SlabAllocator.cpp b/cachelib/allocator/memory/SlabAllocator.cpp index ade5a8e53..0106f1bf4 100644 --- a/cachelib/allocator/memory/SlabAllocator.cpp +++ b/cachelib/allocator/memory/SlabAllocator.cpp @@ -40,7 +40,9 @@ using namespace facebook::cachelib; namespace { -size_t roundDownToSlabSize(size_t size) { return size - (size % sizeof(Slab)); } +static inline size_t roundDownToSlabSize(size_t size) { + return size - (size % sizeof(Slab)); +} } // namespace // definitions to avoid ODR violation.