1 // Copyright (c) 2020-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 #include "test_util/testharness.h"
7 
8 #ifdef OS_LINUX
9 #include "env/io_posix.h"
10 #include "rocksdb/db.h"
11 #include "rocksdb/env.h"
12 
13 namespace ROCKSDB_NAMESPACE {
14 class EnvWithCustomLogicalBlockSizeCache : public EnvWrapper {
15  public:
EnvWithCustomLogicalBlockSizeCache(Env * env,LogicalBlockSizeCache * cache)16   EnvWithCustomLogicalBlockSizeCache(Env* env, LogicalBlockSizeCache* cache)
17       : EnvWrapper(env), cache_(cache) {}
18 
RegisterDbPaths(const std::vector<std::string> & paths)19   Status RegisterDbPaths(const std::vector<std::string>& paths) override {
20     return cache_->RefAndCacheLogicalBlockSize(paths);
21   }
22 
UnregisterDbPaths(const std::vector<std::string> & paths)23   Status UnregisterDbPaths(const std::vector<std::string>& paths) override {
24     cache_->UnrefAndTryRemoveCachedLogicalBlockSize(paths);
25     return Status::OK();
26   }
27 
28  private:
29   LogicalBlockSizeCache* cache_;
30 };
31 
32 class DBLogicalBlockSizeCacheTest : public testing::Test {
33  public:
DBLogicalBlockSizeCacheTest()34   DBLogicalBlockSizeCacheTest()
35       : dbname_(test::PerThreadDBPath("logical_block_size_cache_test")),
36         data_path_0_(dbname_ + "/data_path_0"),
37         data_path_1_(dbname_ + "/data_path_1"),
38         cf_path_0_(dbname_ + "/cf_path_0"),
39         cf_path_1_(dbname_ + "/cf_path_1") {
40     auto get_fd_block_size = [&](int fd) { return fd; };
41     auto get_dir_block_size = [&](const std::string& /*dir*/, size_t* size) {
42       *size = 1024;
43       return Status::OK();
44     };
45     cache_.reset(
46         new LogicalBlockSizeCache(get_fd_block_size, get_dir_block_size));
47     env_.reset(
48         new EnvWithCustomLogicalBlockSizeCache(Env::Default(), cache_.get()));
49   }
50 
51  protected:
52   std::string dbname_;
53   std::string data_path_0_;
54   std::string data_path_1_;
55   std::string cf_path_0_;
56   std::string cf_path_1_;
57   std::unique_ptr<LogicalBlockSizeCache> cache_;
58   std::unique_ptr<Env> env_;
59 };
60 
TEST_F(DBLogicalBlockSizeCacheTest,OpenClose)61 TEST_F(DBLogicalBlockSizeCacheTest, OpenClose) {
62   // Tests that Open will cache the logical block size for data paths,
63   // and Close will remove the cached sizes.
64   Options options;
65   options.create_if_missing = true;
66   options.env = env_.get();
67   options.db_paths = {{data_path_0_, 2048}, {data_path_1_, 2048}};
68 
69   for (int i = 0; i < 2; i++) {
70     DB* db;
71     if (!i) {
72       printf("Open\n");
73       ASSERT_OK(DB::Open(options, dbname_, &db));
74     } else {
75 #ifdef ROCKSDB_LITE
76       break;
77 #else
78       printf("OpenForReadOnly\n");
79       ASSERT_OK(DB::OpenForReadOnly(options, dbname_, &db));
80 #endif
81     }
82     ASSERT_EQ(2, cache_->Size());
83     ASSERT_TRUE(cache_->Contains(data_path_0_));
84     ASSERT_EQ(1, cache_->GetRefCount(data_path_0_));
85     ASSERT_TRUE(cache_->Contains(data_path_1_));
86     ASSERT_EQ(1, cache_->GetRefCount(data_path_1_));
87     ASSERT_OK(db->Close());
88     ASSERT_EQ(0, cache_->Size());
89     delete db;
90   }
91   ASSERT_OK(DestroyDB(dbname_, options, {}));
92 }
93 
TEST_F(DBLogicalBlockSizeCacheTest,OpenDelete)94 TEST_F(DBLogicalBlockSizeCacheTest, OpenDelete) {
95   // Tests that Open will cache the logical block size for data paths,
96   // and delete the db pointer will remove the cached sizes.
97   Options options;
98   options.create_if_missing = true;
99   options.env = env_.get();
100 
101   for (int i = 0; i < 2; i++) {
102     DB* db;
103     if (!i) {
104       printf("Open\n");
105       ASSERT_OK(DB::Open(options, dbname_, &db));
106     } else {
107 #ifdef ROCKSDB_LITE
108       break;
109 #else
110       printf("OpenForReadOnly\n");
111       ASSERT_OK(DB::OpenForReadOnly(options, dbname_, &db));
112 #endif
113     }
114     ASSERT_EQ(1, cache_->Size());
115     ASSERT_TRUE(cache_->Contains(dbname_));
116     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
117     delete db;
118     ASSERT_EQ(0, cache_->Size());
119   }
120   ASSERT_OK(DestroyDB(dbname_, options, {}));
121 }
122 
TEST_F(DBLogicalBlockSizeCacheTest,CreateColumnFamily)123 TEST_F(DBLogicalBlockSizeCacheTest, CreateColumnFamily) {
124   // Tests that CreateColumnFamily will cache the cf_paths,
125   // drop the column family handle won't drop the cache,
126   // drop and then delete the column family handle will drop the cache.
127   Options options;
128   options.create_if_missing = true;
129   options.env = env_.get();
130   ColumnFamilyOptions cf_options;
131   cf_options.cf_paths = {{cf_path_0_, 1024}, {cf_path_1_, 2048}};
132 
133   DB* db;
134   ASSERT_OK(DB::Open(options, dbname_, &db));
135   ASSERT_EQ(1, cache_->Size());
136   ASSERT_TRUE(cache_->Contains(dbname_));
137   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
138 
139   ColumnFamilyHandle* cf = nullptr;
140   ASSERT_OK(db->CreateColumnFamily(cf_options, "cf", &cf));
141   ASSERT_EQ(3, cache_->Size());
142   ASSERT_TRUE(cache_->Contains(dbname_));
143   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
144   ASSERT_TRUE(cache_->Contains(cf_path_0_));
145   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
146   ASSERT_TRUE(cache_->Contains(cf_path_1_));
147   ASSERT_EQ(1, cache_->GetRefCount(cf_path_1_));
148 
149   // Drop column family does not drop cache.
150   ASSERT_OK(db->DropColumnFamily(cf));
151   ASSERT_EQ(3, cache_->Size());
152   ASSERT_TRUE(cache_->Contains(dbname_));
153   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
154   ASSERT_TRUE(cache_->Contains(cf_path_0_));
155   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
156   ASSERT_TRUE(cache_->Contains(cf_path_1_));
157   ASSERT_EQ(1, cache_->GetRefCount(cf_path_1_));
158 
159   // Delete handle will drop cache.
160   ASSERT_OK(db->DestroyColumnFamilyHandle(cf));
161   ASSERT_TRUE(cache_->Contains(dbname_));
162   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
163 
164   delete db;
165   ASSERT_EQ(0, cache_->Size());
166   ASSERT_OK(DestroyDB(dbname_, options, {{"cf", cf_options}}));
167 }
168 
TEST_F(DBLogicalBlockSizeCacheTest,CreateColumnFamilies)169 TEST_F(DBLogicalBlockSizeCacheTest, CreateColumnFamilies) {
170   // Tests that CreateColumnFamilies will cache the cf_paths,
171   // drop the column family handle won't drop the cache,
172   // drop and then delete the column family handle will drop the cache.
173   Options options;
174   options.create_if_missing = true;
175   options.env = env_.get();
176   ColumnFamilyOptions cf_options;
177   cf_options.cf_paths = {{cf_path_0_, 1024}};
178 
179   DB* db;
180   ASSERT_OK(DB::Open(options, dbname_, &db));
181   ASSERT_EQ(1, cache_->Size());
182   ASSERT_TRUE(cache_->Contains(dbname_));
183   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
184 
185   std::vector<ColumnFamilyHandle*> cfs;
186   ASSERT_OK(db->CreateColumnFamilies(cf_options, {"cf1", "cf2"}, &cfs));
187   ASSERT_EQ(2, cache_->Size());
188   ASSERT_TRUE(cache_->Contains(dbname_));
189   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
190   ASSERT_TRUE(cache_->Contains(cf_path_0_));
191   ASSERT_EQ(2, cache_->GetRefCount(cf_path_0_));
192 
193   // Drop column family does not drop cache.
194   for (ColumnFamilyHandle* cf : cfs) {
195     ASSERT_OK(db->DropColumnFamily(cf));
196     ASSERT_EQ(2, cache_->Size());
197     ASSERT_TRUE(cache_->Contains(dbname_));
198     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
199     ASSERT_TRUE(cache_->Contains(cf_path_0_));
200     ASSERT_EQ(2, cache_->GetRefCount(cf_path_0_));
201   }
202 
203   // Delete one handle will not drop cache because another handle is still
204   // referencing cf_path_0_.
205   ASSERT_OK(db->DestroyColumnFamilyHandle(cfs[0]));
206   ASSERT_EQ(2, cache_->Size());
207   ASSERT_TRUE(cache_->Contains(dbname_));
208   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
209   ASSERT_TRUE(cache_->Contains(cf_path_0_));
210   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
211 
212   // Delete the last handle will drop cache.
213   ASSERT_OK(db->DestroyColumnFamilyHandle(cfs[1]));
214   ASSERT_EQ(1, cache_->Size());
215   ASSERT_TRUE(cache_->Contains(dbname_));
216   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
217 
218   delete db;
219   ASSERT_EQ(0, cache_->Size());
220   ASSERT_OK(DestroyDB(dbname_, options,
221       {{"cf1", cf_options}, {"cf2", cf_options}}));
222 }
223 
TEST_F(DBLogicalBlockSizeCacheTest,OpenWithColumnFamilies)224 TEST_F(DBLogicalBlockSizeCacheTest, OpenWithColumnFamilies) {
225   // Tests that Open two column families with the same cf_path will cache the
226   // cf_path and have 2 references to the cached size,
227   // drop the column family handle won't drop the cache,
228   // drop and then delete the column family handle will drop the cache.
229   Options options;
230   options.create_if_missing = true;
231   options.env = env_.get();
232 
233   ColumnFamilyOptions cf_options;
234   cf_options.cf_paths = {{cf_path_0_, 1024}};
235 
236   for (int i = 0; i < 2; i++) {
237     DB* db;
238     ColumnFamilyHandle* cf1 = nullptr;
239     ColumnFamilyHandle* cf2 = nullptr;
240     ASSERT_OK(DB::Open(options, dbname_, &db));
241     ASSERT_OK(db->CreateColumnFamily(cf_options, "cf1", &cf1));
242     ASSERT_OK(db->CreateColumnFamily(cf_options, "cf2", &cf2));
243     ASSERT_OK(db->DestroyColumnFamilyHandle(cf1));
244     ASSERT_OK(db->DestroyColumnFamilyHandle(cf2));
245     delete db;
246     ASSERT_EQ(0, cache_->Size());
247 
248     std::vector<ColumnFamilyHandle*> cfs;
249     if (!i) {
250       printf("Open\n");
251       ASSERT_OK(DB::Open(options, dbname_,
252                          {{"cf1", cf_options},
253                           {"cf2", cf_options},
254                           {"default", ColumnFamilyOptions()}},
255                          &cfs, &db));
256     } else {
257 #ifdef ROCKSDB_LITE
258       break;
259 #else
260       printf("OpenForReadOnly\n");
261       ASSERT_OK(DB::OpenForReadOnly(options, dbname_,
262                                     {{"cf1", cf_options},
263                                      {"cf2", cf_options},
264                                      {"default", ColumnFamilyOptions()}},
265                                     &cfs, &db));
266 #endif
267     }
268 
269     // Logical block sizes of dbname_ and cf_path_0_ are cached during Open.
270     ASSERT_EQ(2, cache_->Size());
271     ASSERT_TRUE(cache_->Contains(dbname_));
272     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
273     ASSERT_TRUE(cache_->Contains(cf_path_0_));
274     ASSERT_EQ(2, cache_->GetRefCount(cf_path_0_));
275 
276     // Drop handles won't drop the cache.
277     ASSERT_OK(db->DropColumnFamily(cfs[0]));
278     ASSERT_OK(db->DropColumnFamily(cfs[1]));
279     ASSERT_EQ(2, cache_->Size());
280     ASSERT_TRUE(cache_->Contains(dbname_));
281     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
282     ASSERT_TRUE(cache_->Contains(cf_path_0_));
283     ASSERT_EQ(2, cache_->GetRefCount(cf_path_0_));
284 
285     // Delete 1st handle won't drop the cache for cf_path_0_.
286     ASSERT_OK(db->DestroyColumnFamilyHandle(cfs[0]));
287     ASSERT_EQ(2, cache_->Size());
288     ASSERT_TRUE(cache_->Contains(dbname_));
289     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
290     ASSERT_TRUE(cache_->Contains(cf_path_0_));
291     ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
292 
293     // Delete 2nd handle will drop the cache for cf_path_0_.
294     ASSERT_OK(db->DestroyColumnFamilyHandle(cfs[1]));
295     ASSERT_EQ(1, cache_->Size());
296     ASSERT_TRUE(cache_->Contains(dbname_));
297     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
298 
299     // Delete the default handle won't affect the cache because db still refers
300     // to the default CF.
301     ASSERT_OK(db->DestroyColumnFamilyHandle(cfs[2]));
302     ASSERT_EQ(1, cache_->Size());
303     ASSERT_TRUE(cache_->Contains(dbname_));
304     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
305 
306     delete db;
307     ASSERT_EQ(0, cache_->Size());
308   }
309   ASSERT_OK(DestroyDB(dbname_, options,
310       {{"cf1", cf_options}, {"cf2", cf_options}}));
311 }
312 
TEST_F(DBLogicalBlockSizeCacheTest,DestroyColumnFamilyHandle)313 TEST_F(DBLogicalBlockSizeCacheTest, DestroyColumnFamilyHandle) {
314   // Tests that destroy column family without dropping won't drop the cache,
315   // because compaction and flush might still need to get logical block size
316   // when opening new files.
317   Options options;
318   options.create_if_missing = true;
319   options.env = env_.get();
320   ColumnFamilyOptions cf_options;
321   cf_options.cf_paths = {{cf_path_0_, 1024}};
322 
323   DB* db;
324   ASSERT_OK(DB::Open(options, dbname_, &db));
325   ASSERT_EQ(1, cache_->Size());
326   ASSERT_TRUE(cache_->Contains(dbname_));
327   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
328   ColumnFamilyHandle* cf = nullptr;
329   ASSERT_OK(db->CreateColumnFamily(cf_options, "cf", &cf));
330   ASSERT_EQ(2, cache_->Size());
331   ASSERT_TRUE(cache_->Contains(dbname_));
332   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
333   ASSERT_TRUE(cache_->Contains(cf_path_0_));
334   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
335 
336   // Delete handle won't drop cache.
337   ASSERT_OK(db->DestroyColumnFamilyHandle(cf));
338   ASSERT_EQ(2, cache_->Size());
339   ASSERT_TRUE(cache_->Contains(dbname_));
340   ASSERT_EQ(1, cache_->GetRefCount(dbname_));
341   ASSERT_TRUE(cache_->Contains(cf_path_0_));
342   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
343 
344   delete db;
345   ASSERT_EQ(0, cache_->Size());
346 
347   // Open with column families.
348   std::vector<ColumnFamilyHandle*> cfs;
349   for (int i = 0; i < 2; i++) {
350     if (!i) {
351       printf("Open\n");
352       ASSERT_OK(DB::Open(
353           options, dbname_,
354           {{"cf", cf_options}, {"default", ColumnFamilyOptions()}}, &cfs, &db));
355     } else {
356 #ifdef ROCKSDB_LITE
357       break;
358 #else
359       printf("OpenForReadOnly\n");
360       ASSERT_OK(DB::OpenForReadOnly(
361           options, dbname_,
362           {{"cf", cf_options}, {"default", ColumnFamilyOptions()}}, &cfs, &db));
363 #endif
364     }
365     // cf_path_0_ and dbname_ are cached.
366     ASSERT_EQ(2, cache_->Size());
367     ASSERT_TRUE(cache_->Contains(dbname_));
368     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
369     ASSERT_TRUE(cache_->Contains(cf_path_0_));
370     ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
371 
372     // Deleting handle won't drop cache.
373     ASSERT_OK(db->DestroyColumnFamilyHandle(cfs[0]));
374     ASSERT_OK(db->DestroyColumnFamilyHandle(cfs[1]));
375     ASSERT_EQ(2, cache_->Size());
376     ASSERT_TRUE(cache_->Contains(dbname_));
377     ASSERT_EQ(1, cache_->GetRefCount(dbname_));
378     ASSERT_TRUE(cache_->Contains(cf_path_0_));
379     ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
380 
381     delete db;
382     ASSERT_EQ(0, cache_->Size());
383   }
384   ASSERT_OK(DestroyDB(dbname_, options, {{"cf", cf_options}}));
385 }
386 
TEST_F(DBLogicalBlockSizeCacheTest,MultiDBWithDifferentPaths)387 TEST_F(DBLogicalBlockSizeCacheTest, MultiDBWithDifferentPaths) {
388   // Tests the cache behavior when there are multiple DBs sharing the same env
389   // with different db_paths and cf_paths.
390   Options options;
391   options.create_if_missing = true;
392   options.env = env_.get();
393 
394   ASSERT_OK(env_->CreateDirIfMissing(dbname_));
395 
396   DB* db0;
397   ASSERT_OK(DB::Open(options, data_path_0_, &db0));
398   ASSERT_EQ(1, cache_->Size());
399   ASSERT_TRUE(cache_->Contains(data_path_0_));
400 
401   ColumnFamilyOptions cf_options0;
402   cf_options0.cf_paths = {{cf_path_0_, 1024}};
403   ColumnFamilyHandle* cf0;
404   db0->CreateColumnFamily(cf_options0, "cf", &cf0);
405   ASSERT_EQ(2, cache_->Size());
406   ASSERT_TRUE(cache_->Contains(data_path_0_));
407   ASSERT_EQ(1, cache_->GetRefCount(data_path_0_));
408   ASSERT_TRUE(cache_->Contains(cf_path_0_));
409   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
410 
411   DB* db1;
412   ASSERT_OK(DB::Open(options, data_path_1_, &db1));
413   ASSERT_EQ(3, cache_->Size());
414   ASSERT_TRUE(cache_->Contains(data_path_0_));
415   ASSERT_EQ(1, cache_->GetRefCount(data_path_0_));
416   ASSERT_TRUE(cache_->Contains(cf_path_0_));
417   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
418   ASSERT_TRUE(cache_->Contains(data_path_1_));
419   ASSERT_EQ(1, cache_->GetRefCount(data_path_1_));
420 
421   ColumnFamilyOptions cf_options1;
422   cf_options1.cf_paths = {{cf_path_1_, 1024}};
423   ColumnFamilyHandle* cf1;
424   db1->CreateColumnFamily(cf_options1, "cf", &cf1);
425   ASSERT_EQ(4, cache_->Size());
426   ASSERT_TRUE(cache_->Contains(data_path_0_));
427   ASSERT_EQ(1, cache_->GetRefCount(data_path_0_));
428   ASSERT_TRUE(cache_->Contains(cf_path_0_));
429   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
430   ASSERT_TRUE(cache_->Contains(data_path_1_));
431   ASSERT_EQ(1, cache_->GetRefCount(data_path_1_));
432   ASSERT_TRUE(cache_->Contains(cf_path_1_));
433   ASSERT_EQ(1, cache_->GetRefCount(cf_path_1_));
434 
435   db0->DestroyColumnFamilyHandle(cf0);
436   delete db0;
437   ASSERT_EQ(2, cache_->Size());
438   ASSERT_TRUE(cache_->Contains(data_path_1_));
439   ASSERT_EQ(1, cache_->GetRefCount(data_path_1_));
440   ASSERT_TRUE(cache_->Contains(cf_path_1_));
441   ASSERT_EQ(1, cache_->GetRefCount(cf_path_1_));
442   ASSERT_OK(DestroyDB(data_path_0_, options, {{"cf", cf_options0}}));
443 
444   db1->DestroyColumnFamilyHandle(cf1);
445   delete db1;
446   ASSERT_EQ(0, cache_->Size());
447   ASSERT_OK(DestroyDB(data_path_1_, options, {{"cf", cf_options1}}));
448 }
449 
TEST_F(DBLogicalBlockSizeCacheTest,MultiDBWithSamePaths)450 TEST_F(DBLogicalBlockSizeCacheTest, MultiDBWithSamePaths) {
451   // Tests the cache behavior when there are multiple DBs sharing the same env
452   // with the same db_paths and cf_paths.
453   Options options;
454   options.create_if_missing = true;
455   options.env = env_.get();
456   options.db_paths = {{data_path_0_, 1024}};
457   ColumnFamilyOptions cf_options;
458   cf_options.cf_paths = {{cf_path_0_, 1024}};
459 
460   ASSERT_OK(env_->CreateDirIfMissing(dbname_));
461 
462   DB* db0;
463   ASSERT_OK(DB::Open(options, dbname_ + "/db0", &db0));
464   ASSERT_EQ(1, cache_->Size());
465   ASSERT_TRUE(cache_->Contains(data_path_0_));
466   ASSERT_EQ(1, cache_->GetRefCount(data_path_0_));
467 
468   ColumnFamilyHandle* cf0;
469   db0->CreateColumnFamily(cf_options, "cf", &cf0);
470   ASSERT_EQ(2, cache_->Size());
471   ASSERT_TRUE(cache_->Contains(data_path_0_));
472   ASSERT_EQ(1, cache_->GetRefCount(data_path_0_));
473   ASSERT_TRUE(cache_->Contains(cf_path_0_));
474   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
475 
476   DB* db1;
477   ASSERT_OK(DB::Open(options, dbname_ + "/db1", &db1));
478   ASSERT_EQ(2, cache_->Size());
479   ASSERT_TRUE(cache_->Contains(data_path_0_));
480   ASSERT_EQ(2, cache_->GetRefCount(data_path_0_));
481   ASSERT_TRUE(cache_->Contains(cf_path_0_));
482   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
483 
484   ColumnFamilyHandle* cf1;
485   db1->CreateColumnFamily(cf_options, "cf", &cf1);
486   ASSERT_EQ(2, cache_->Size());
487   ASSERT_TRUE(cache_->Contains(data_path_0_));
488   ASSERT_EQ(2, cache_->GetRefCount(data_path_0_));
489   ASSERT_TRUE(cache_->Contains(cf_path_0_));
490   ASSERT_EQ(2, cache_->GetRefCount(cf_path_0_));
491 
492   db0->DestroyColumnFamilyHandle(cf0);
493   delete db0;
494   ASSERT_EQ(2, cache_->Size());
495   ASSERT_TRUE(cache_->Contains(data_path_0_));
496   ASSERT_EQ(1, cache_->GetRefCount(data_path_0_));
497   ASSERT_TRUE(cache_->Contains(cf_path_0_));
498   ASSERT_EQ(1, cache_->GetRefCount(cf_path_0_));
499   ASSERT_OK(DestroyDB(dbname_ + "/db0", options, {{"cf", cf_options}}));
500 
501   db1->DestroyColumnFamilyHandle(cf1);
502   delete db1;
503   ASSERT_EQ(0, cache_->Size());
504   ASSERT_OK(DestroyDB(dbname_ + "/db1", options, {{"cf", cf_options}}));
505 }
506 
507 }  // namespace ROCKSDB_NAMESPACE
508 #endif  // OS_LINUX
509 
main(int argc,char ** argv)510 int main(int argc, char** argv) {
511   ::testing::InitGoogleTest(&argc, argv);
512   return RUN_ALL_TESTS();
513 }
514