write_buffer_manager_test.cc 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #include "rocksdb/write_buffer_manager.h"
  10. #include "test_util/testharness.h"
  11. namespace ROCKSDB_NAMESPACE {
  12. class WriteBufferManagerTest : public testing::Test {};
  13. #ifndef ROCKSDB_LITE
  14. TEST_F(WriteBufferManagerTest, ShouldFlush) {
  15. // A write buffer manager of size 10MB
  16. std::unique_ptr<WriteBufferManager> wbf(
  17. new WriteBufferManager(10 * 1024 * 1024));
  18. wbf->ReserveMem(8 * 1024 * 1024);
  19. ASSERT_FALSE(wbf->ShouldFlush());
  20. // 90% of the hard limit will hit the condition
  21. wbf->ReserveMem(1 * 1024 * 1024);
  22. ASSERT_TRUE(wbf->ShouldFlush());
  23. // Scheduling for freeing will release the condition
  24. wbf->ScheduleFreeMem(1 * 1024 * 1024);
  25. ASSERT_FALSE(wbf->ShouldFlush());
  26. wbf->ReserveMem(2 * 1024 * 1024);
  27. ASSERT_TRUE(wbf->ShouldFlush());
  28. wbf->ScheduleFreeMem(4 * 1024 * 1024);
  29. // 11MB total, 6MB mutable. hard limit still hit
  30. ASSERT_TRUE(wbf->ShouldFlush());
  31. wbf->ScheduleFreeMem(2 * 1024 * 1024);
  32. // 11MB total, 4MB mutable. hard limit stills but won't flush because more
  33. // than half data is already being flushed.
  34. ASSERT_FALSE(wbf->ShouldFlush());
  35. wbf->ReserveMem(4 * 1024 * 1024);
  36. // 15 MB total, 8MB mutable.
  37. ASSERT_TRUE(wbf->ShouldFlush());
  38. wbf->FreeMem(7 * 1024 * 1024);
  39. // 9MB total, 8MB mutable.
  40. ASSERT_FALSE(wbf->ShouldFlush());
  41. }
  42. TEST_F(WriteBufferManagerTest, CacheCost) {
  43. LRUCacheOptions co;
  44. // 1GB cache
  45. co.capacity = 1024 * 1024 * 1024;
  46. co.num_shard_bits = 4;
  47. co.metadata_charge_policy = kDontChargeCacheMetadata;
  48. std::shared_ptr<Cache> cache = NewLRUCache(co);
  49. // A write buffer manager of size 50MB
  50. std::unique_ptr<WriteBufferManager> wbf(
  51. new WriteBufferManager(50 * 1024 * 1024, cache));
  52. // Allocate 333KB will allocate 512KB
  53. wbf->ReserveMem(333 * 1024);
  54. ASSERT_GE(cache->GetPinnedUsage(), 2 * 256 * 1024);
  55. ASSERT_LT(cache->GetPinnedUsage(), 2 * 256 * 1024 + 10000);
  56. // Allocate another 512KB
  57. wbf->ReserveMem(512 * 1024);
  58. ASSERT_GE(cache->GetPinnedUsage(), 4 * 256 * 1024);
  59. ASSERT_LT(cache->GetPinnedUsage(), 4 * 256 * 1024 + 10000);
  60. // Allocate another 10MB
  61. wbf->ReserveMem(10 * 1024 * 1024);
  62. ASSERT_GE(cache->GetPinnedUsage(), 11 * 1024 * 1024);
  63. ASSERT_LT(cache->GetPinnedUsage(), 11 * 1024 * 1024 + 10000);
  64. // Free 1MB will not cause any change in cache cost
  65. wbf->FreeMem(1024 * 1024);
  66. ASSERT_GE(cache->GetPinnedUsage(), 11 * 1024 * 1024);
  67. ASSERT_LT(cache->GetPinnedUsage(), 11 * 1024 * 1024 + 10000);
  68. ASSERT_FALSE(wbf->ShouldFlush());
  69. // Allocate another 41MB
  70. wbf->ReserveMem(41 * 1024 * 1024);
  71. ASSERT_GE(cache->GetPinnedUsage(), 51 * 1024 * 1024);
  72. ASSERT_LT(cache->GetPinnedUsage(), 51 * 1024 * 1024 + 10000);
  73. ASSERT_TRUE(wbf->ShouldFlush());
  74. ASSERT_TRUE(wbf->ShouldFlush());
  75. wbf->ScheduleFreeMem(20 * 1024 * 1024);
  76. ASSERT_GE(cache->GetPinnedUsage(), 51 * 1024 * 1024);
  77. ASSERT_LT(cache->GetPinnedUsage(), 51 * 1024 * 1024 + 10000);
  78. // Still need flush as the hard limit hits
  79. ASSERT_TRUE(wbf->ShouldFlush());
  80. // Free 20MB will releae 256KB from cache
  81. wbf->FreeMem(20 * 1024 * 1024);
  82. ASSERT_GE(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 256 * 1024);
  83. ASSERT_LT(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 256 * 1024 + 10000);
  84. ASSERT_FALSE(wbf->ShouldFlush());
  85. // Every free will release 256KB if still not hit 3/4
  86. wbf->FreeMem(16 * 1024);
  87. ASSERT_GE(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 2 * 256 * 1024);
  88. ASSERT_LT(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 2 * 256 * 1024 + 10000);
  89. wbf->FreeMem(16 * 1024);
  90. ASSERT_GE(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 3 * 256 * 1024);
  91. ASSERT_LT(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 3 * 256 * 1024 + 10000);
  92. // Reserve 512KB will not cause any change in cache cost
  93. wbf->ReserveMem(512 * 1024);
  94. ASSERT_GE(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 3 * 256 * 1024);
  95. ASSERT_LT(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 3 * 256 * 1024 + 10000);
  96. wbf->FreeMem(16 * 1024);
  97. ASSERT_GE(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 4 * 256 * 1024);
  98. ASSERT_LT(cache->GetPinnedUsage(), 51 * 1024 * 1024 - 4 * 256 * 1024 + 10000);
  99. // Destory write buffer manger should free everything
  100. wbf.reset();
  101. ASSERT_LT(cache->GetPinnedUsage(), 1024 * 1024);
  102. }
  103. TEST_F(WriteBufferManagerTest, NoCapCacheCost) {
  104. // 1GB cache
  105. std::shared_ptr<Cache> cache = NewLRUCache(1024 * 1024 * 1024, 4);
  106. // A write buffer manager of size 256MB
  107. std::unique_ptr<WriteBufferManager> wbf(new WriteBufferManager(0, cache));
  108. // Allocate 1.5MB will allocate 2MB
  109. wbf->ReserveMem(10 * 1024 * 1024);
  110. ASSERT_GE(cache->GetPinnedUsage(), 10 * 1024 * 1024);
  111. ASSERT_LT(cache->GetPinnedUsage(), 10 * 1024 * 1024 + 10000);
  112. ASSERT_FALSE(wbf->ShouldFlush());
  113. wbf->FreeMem(9 * 1024 * 1024);
  114. for (int i = 0; i < 40; i++) {
  115. wbf->FreeMem(4 * 1024);
  116. }
  117. ASSERT_GE(cache->GetPinnedUsage(), 1024 * 1024);
  118. ASSERT_LT(cache->GetPinnedUsage(), 1024 * 1024 + 10000);
  119. }
  120. #endif // ROCKSDB_LITE
  121. } // namespace ROCKSDB_NAMESPACE
  122. int main(int argc, char** argv) {
  123. ::testing::InitGoogleTest(&argc, argv);
  124. return RUN_ALL_TESTS();
  125. }