| 586 | } |
| 587 | |
| 588 | TEST_F(AsyncDataCacheTest, pin) { |
| 589 | constexpr int64_t kSize = 25000; |
| 590 | initializeCache(1 << 20); |
| 591 | auto& exec = folly::QueuedImmediateExecutor::instance(); |
| 592 | |
| 593 | StringIdLease file(fileIds(), std::string_view("testingfile")); |
| 594 | uint64_t offset = 1000; |
| 595 | folly::SemiFuture<bool> wait(false); |
| 596 | RawFileCacheKey key{file.id(), offset}; |
| 597 | auto pin = cache_->findOrCreate(key, kSize, &wait); |
| 598 | EXPECT_FALSE(pin.empty()); |
| 599 | EXPECT_TRUE(wait.isReady()); |
| 600 | EXPECT_TRUE(pin.entry()->isExclusive()); |
| 601 | pin.entry()->setPrefetch(); |
| 602 | EXPECT_LE(kSize, pin.entry()->data().byteSize()); |
| 603 | EXPECT_LT(0, cache_->incrementPrefetchPages(0)); |
| 604 | auto stats = cache_->refreshStats(); |
| 605 | EXPECT_EQ(1, stats.numExclusive); |
| 606 | EXPECT_LE(kSize, stats.largeSize); |
| 607 | |
| 608 | CachePin otherPin; |
| 609 | EXPECT_THROW(otherPin = pin, BoltException); |
| 610 | EXPECT_TRUE(otherPin.empty()); |
| 611 | |
| 612 | // Second reference to an exclusive entry. |
| 613 | otherPin = cache_->findOrCreate(key, kSize, &wait); |
| 614 | EXPECT_FALSE(wait.isReady()); |
| 615 | EXPECT_TRUE(otherPin.empty()); |
| 616 | bool noLongerExclusive = false; |
| 617 | std::move(wait).via(&exec).thenValue([&](bool) { noLongerExclusive = true; }); |
| 618 | initializeContents(key.fileNum + key.offset, pin.checkedEntry()->data()); |
| 619 | pin.checkedEntry()->setExclusiveToShared(); |
| 620 | pin.clear(); |
| 621 | EXPECT_TRUE(pin.empty()); |
| 622 | |
| 623 | EXPECT_TRUE(noLongerExclusive); |
| 624 | |
| 625 | pin = cache_->findOrCreate(key, kSize, &wait); |
| 626 | EXPECT_TRUE(pin.entry()->isShared()); |
| 627 | EXPECT_TRUE(pin.entry()->getAndClearFirstUseFlag()); |
| 628 | EXPECT_FALSE(pin.entry()->getAndClearFirstUseFlag()); |
| 629 | checkContents(*pin.entry()); |
| 630 | otherPin = pin; |
| 631 | EXPECT_EQ(2, pin.entry()->numPins()); |
| 632 | EXPECT_FALSE(pin.entry()->isPrefetch()); |
| 633 | auto largerPin = cache_->findOrCreate(key, kSize * 2, &wait); |
| 634 | // We expect a new uninitialized entry with a larger size to displace the |
| 635 | // previous one. |
| 636 | |
| 637 | EXPECT_TRUE(largerPin.checkedEntry()->isExclusive()); |
| 638 | largerPin.checkedEntry()->setExclusiveToShared(); |
| 639 | largerPin.clear(); |
| 640 | pin.clear(); |
| 641 | otherPin.clear(); |
| 642 | stats = cache_->refreshStats(); |
| 643 | EXPECT_LE(kSize * 2, stats.largeSize); |
| 644 | EXPECT_EQ(1, stats.numEntries); |
| 645 | EXPECT_EQ(0, stats.numShared); |
nothing calls this directly
no test coverage detected