1+ /*
2+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3+ *
4+ * Licensed under the Apache License, Version 2.0 (the "License");
5+ * you may not use this file except in compliance with the License.
6+ * You may obtain a copy of the License at
7+ *
8+ * http://www.apache.org/licenses/LICENSE-2.0
9+ *
10+ * Unless required by applicable law or agreed to in writing, software
11+ * distributed under the License is distributed on an "AS IS" BASIS,
12+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+ * See the License for the specific language governing permissions and
14+ * limitations under the License.
15+ */
16+
17+ #include " cachelib/allocator/CacheAllocator.h"
18+ #include " cachelib/allocator/MemoryTierCacheConfig.h"
19+ #include " folly/init/Init.h"
20+
21+ namespace facebook {
22+ namespace cachelib_examples {
23+ using Cache = cachelib::LruAllocator; // or Lru2QAllocator, or TinyLFUAllocator
24+ using CacheConfig = typename Cache::Config;
25+ using CacheKey = typename Cache::Key;
26+ using CacheReadHandle = typename Cache::ReadHandle;
27+ using MemoryTierCacheConfig = typename cachelib::MemoryTierCacheConfig;
28+ using NumaBitMask = typename cachelib::NumaBitMask;
29+
30+ // Global cache object and a default cache pool
31+ std::unique_ptr<Cache> gCache_ ;
32+ cachelib::PoolId defaultPool_;
33+
34+ void initializeCache () {
35+ CacheConfig config;
36+ config
37+ .setCacheSize (48 * 1024 * 1024 ) // 48 MB
38+ .setCacheName (" SingleTier Cache" )
39+ .enableCachePersistence (" /tmp/simple-tier-cache" )
40+ .setAccessConfig (
41+ {25 /* bucket power */ , 10 /* lock power */ }) // assuming caching 20
42+ // million items
43+ .configureMemoryTiers ({
44+ MemoryTierCacheConfig::fromShm ()
45+ .setRatio (1 )
46+ .setMemBind (NumaBitMask ().setBit (0 ))}) // allocate only from NUMA node 0
47+ .validate (); // will throw if bad config
48+ gCache_ = std::make_unique<Cache>(Cache::SharedMemNew, config);
49+ defaultPool_ =
50+ gCache_ ->addPool (" default" , gCache_ ->getCacheMemoryStats ().cacheSize );
51+ }
52+
53+ void destroyCache () { gCache_ .reset (); }
54+
55+ CacheReadHandle get (CacheKey key) { return gCache_ ->find (key); }
56+
57+ bool put (CacheKey key, const std::string& value) {
58+ auto handle = gCache_ ->allocate (defaultPool_, key, value.size ());
59+ if (!handle) {
60+ return false ; // cache may fail to evict due to too many pending writes
61+ }
62+ std::memcpy (handle->getMemory (), value.data (), value.size ());
63+ gCache_ ->insertOrReplace (handle);
64+ return true ;
65+ }
66+ } // namespace cachelib_examples
67+ } // namespace facebook
68+
69+ using namespace facebook ::cachelib_examples;
70+
71+ int main (int argc, char ** argv) {
72+ folly::init (&argc, &argv);
73+
74+ initializeCache ();
75+
76+ std::string value (4 *1024 , ' X' ); // 4 KB value
77+ const size_t NUM_ITEMS = 13000 ;
78+
79+ // Use cache
80+ {
81+ for (size_t i = 0 ; i < NUM_ITEMS; ++i) {
82+ std::string key = " key" + std::to_string (i);
83+ auto res = put (key, value);
84+
85+ std::ignore = res;
86+ assert (res);
87+ }
88+
89+ size_t nFound = 0 ;
90+ size_t nNotFound = 0 ;
91+ for (size_t i = 0 ; i < NUM_ITEMS; ++i) {
92+ std::string key = " key" + std::to_string (i);
93+ auto item = get (key);
94+ if (item) {
95+ ++nFound;
96+ folly::StringPiece sp{reinterpret_cast <const char *>(item->getMemory ()),
97+ item->getSize ()};
98+ std::ignore = sp;
99+ assert (sp == value);
100+ } else {
101+ ++nNotFound;
102+ }
103+ }
104+ std::cout << " Found:\t\t " << nFound << " items\n "
105+ << " Not found:\t " << nNotFound << " items" << std::endl;
106+ }
107+
108+ destroyCache ();
109+ }
0 commit comments