1 /**
2  * @file   buffer_lru_cache.h
3  *
4  * @section LICENSE
5  *
6  * The MIT License
7  *
8  * @copyright Copyright (c) 2017-2021 TileDB, Inc.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  *
28  * @section DESCRIPTION
29  *
30  * This file defines class BufferLRUCache.
31  */
32 
33 #ifndef TILEDB_BUFFER_LRU_CACHE_H
34 #define TILEDB_BUFFER_LRU_CACHE_H
35 
36 #include "tiledb/common/status.h"
37 #include "tiledb/sm/cache/lru_cache.h"
38 
39 #include <list>
40 #include <map>
41 #include <mutex>
42 
43 using namespace tiledb::common;
44 
45 namespace tiledb {
46 namespace sm {
47 
48 class Buffer;
49 
50 /**
51  * Provides a least-recently used cache for `Buffer` objects
52  * mapped by a `std::string` key. The maximum capacity of the
53  * cache is defined as a total allocated byte size among all
54  * `Buffer` objects.
55  *
56  * This class is thread-safe.
57  */
58 class BufferLRUCache : public LRUCache<std::string, Buffer> {
59  public:
60   /* ********************************* */
61   /*     CONSTRUCTORS & DESTRUCTORS    */
62   /* ********************************* */
63 
64   /**
65    * Constructor.
66    *
67    * @param size The maximum cache byte size.
68    */
69   BufferLRUCache(uint64_t max_size);
70 
71   /** Destructor. */
72   virtual ~BufferLRUCache() = default;
73 
74   /* ********************************* */
75   /*                API                */
76   /* ********************************* */
77 
78   /**
79    * Inserts an object with a given key and size into the cache. Note that
80    * the cache *owns* the object after insertion.
81    *
82    * @param key The key that describes the inserted object.
83    * @param buffer The buffer to store.
84    * @param overwrite If `true`, if the object exists in the cache it will be
85    *     overwritten. Otherwise, the new object will be deleted.
86    * @return Status
87    */
88   Status insert(const std::string& key, Buffer&& buffer, bool overwrite = true);
89 
90   /**
91    * Reads a portion of the object labeled by `key`.
92    *
93    * @param key The label of the object to be read.
94    * @param buffer The buffer that will store the data to be read.
95    * @param offset The offset where the read will start.
96    * @param nbytes The number of bytes to be read.
97    * @param success `true` if the data were read from the cache and `false`
98    *     otherwise.
99    * @return Status.
100    */
101   Status read(
102       const std::string& key,
103       Buffer* buffer,
104       uint64_t offset,
105       uint64_t nbytes,
106       bool* success);
107 
108   /** Clears the cache, deleting all cached items. */
109   void clear();
110 
111   /**
112    * Invalidates and evicts the object in the cache with the given key.
113    *
114    * @param key The key that describes the object to be invalidated.
115    * @param success Set to `true` if the object was removed successfully; if
116    *    the object did not exist in the cache, set to `false`.
117    * @return Status
118    */
119   Status invalidate(const std::string& key, bool* success);
120 
121   /**
122    * Returns a constant iterator at the beginning of the linked list of
123    * cached items, where items closest to the head (beginning) are going
124    * to be evicted from the cache sooner. This is public for unit test
125    * purposes only.
126    */
127   typename std::list<LRUCacheItem>::const_iterator item_iter_begin() const;
128 
129   /**
130    * Returns a constant iterator at the end of the linked list of
131    * cached items, where items closest to the head (beginning) are going
132    * to be evicted from the cache sooner. This is public for unit test
133    * purposes only.
134    */
135   typename std::list<LRUCacheItem>::const_iterator item_iter_end() const;
136 
137  private:
138   /* ********************************* */
139   /*         PRIVATE ATTRIBUTES        */
140   /* ********************************* */
141 
142   // Protects LRUCache routines.
143   mutable std::mutex lru_mtx_;
144 };
145 
146 }  // namespace sm
147 }  // namespace tiledb
148 
149 #endif  // TILEDB_BUFFER_LRU_CACHE_H
150