OmniSciDB  8a228a1076
BufferMgr.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017 MapD Technologies, Inc.
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 
25 #pragma once
26 
27 #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED 1
28 
29 #include <iostream>
30 #include <list>
31 #include <map>
32 #include <mutex>
33 
34 #include <boost/stacktrace.hpp>
35 
36 #include "DataMgr/AbstractBuffer.h"
39 #include "Shared/types.h"
40 
41 class OutOfMemory : public std::runtime_error {
42  public:
43  OutOfMemory(size_t num_bytes)
44  : std::runtime_error(parse_error_str("OutOfMemory", num_bytes)) {
45  VLOG(1) << "Failed to allocate " << num_bytes << " bytes";
46  VLOG(1) << boost::stacktrace::stacktrace();
47  };
48 
49  OutOfMemory(const std::string& err) : std::runtime_error(parse_error_str(err, 0)) {
50  VLOG(1) << "Failed with OutOfMemory, condition " << err;
51  VLOG(1) << boost::stacktrace::stacktrace();
52  };
53 
54  OutOfMemory(const std::string& err, size_t num_bytes)
55  : std::runtime_error(parse_error_str(err, num_bytes)) {
56  VLOG(1) << "Failed to allocate " << num_bytes << " bytes with condition " << err;
57  VLOG(1) << boost::stacktrace::stacktrace();
58  };
59 
60  private:
61  std::string parse_error_str(const std::string& err, const size_t num_bytes = 0) {
62  if (num_bytes) {
63  return err + ": Failed to allocate " + std::to_string(num_bytes) + " bytes";
64  } else {
65  return "Failed to allocate memory with condition " + err;
66  }
67  }
68 };
69 
71  public:
72  FailedToCreateFirstSlab(size_t num_bytes)
73  : OutOfMemory("FailedToCreateFirstSlab", num_bytes) {}
74 };
75 
77  public:
78  FailedToCreateSlab(size_t num_bytes) : OutOfMemory("FailedToCreateSlab", num_bytes) {}
79 };
80 
81 class TooBigForSlab : public OutOfMemory {
82  public:
83  TooBigForSlab(size_t num_bytes) : OutOfMemory("TooBigForSlab", num_bytes) {}
84 };
85 
86 using namespace Data_Namespace;
87 
88 namespace Buffer_Namespace {
89 
97 class BufferMgr : public AbstractBufferMgr { // implements
98 
99  public:
101  BufferMgr(const int device_id,
102  const size_t max_buffer_size,
103  const size_t min_slab_size,
104  const size_t max_slab_size,
105  const size_t page_size,
106  AbstractBufferMgr* parent_mgr = 0);
107 
109  ~BufferMgr() override;
110  void reinit();
111 
112  void clear();
113 
114  std::string printSlab(size_t slab_num);
115  std::string printSlabs() override;
116  void clearSlabs() override;
117  std::string printMap();
118  void printSegs();
119  std::string printSeg(BufferList::iterator& seg_it);
120  std::string keyToString(const ChunkKey& key);
121  size_t getInUseSize() override;
122  size_t getMaxSize() override;
123  size_t getAllocated() override;
124  size_t getMaxBufferSize();
125  size_t getMaxSlabSize();
126  size_t getPageSize();
127  bool isAllocationCapped() override;
128  const std::vector<BufferList>& getSlabSegments();
129 
131  AbstractBuffer* createBuffer(const ChunkKey& key,
132  const size_t page_size = 0,
133  const size_t initial_size = 0) override;
134 
136  void deleteBuffer(const ChunkKey& key, const bool purge = true) override;
137  void deleteBuffersWithPrefix(const ChunkKey& key_prefix,
138  const bool purge = true) override;
139 
141  AbstractBuffer* getBuffer(const ChunkKey& key, const size_t num_bytes = 0) override;
142 
149  bool isBufferOnDevice(const ChunkKey& key) override;
150  void fetchBuffer(const ChunkKey& key,
151  AbstractBuffer* dest_buffer,
152  const size_t num_bytes = 0) override;
153  AbstractBuffer* putBuffer(const ChunkKey& key,
154  AbstractBuffer* d,
155  const size_t num_bytes = 0) override;
156  void checkpoint() override;
157  void checkpoint(const int db_id, const int tb_id) override;
158  void removeTableRelatedDS(const int db_id, const int table_id) override;
159 
160  // Buffer API
161  AbstractBuffer* alloc(const size_t num_bytes = 0) override;
162  void free(AbstractBuffer* buffer) override;
163 
165  size_t size();
166  size_t getNumChunks() override;
167 
168  BufferList::iterator reserveBuffer(BufferList::iterator& seg_it,
169  const size_t num_bytes);
170  void getChunkMetadataVec(ChunkMetadataVector& chunk_metadata_vec) override;
171  void getChunkMetadataVecForKeyPrefix(ChunkMetadataVector& chunk_metadata_vec,
172  const ChunkKey& key_prefix) override;
173 
174  protected:
175  const size_t
177  const size_t min_slab_size_;
178  const size_t max_slab_size_;
180  const size_t page_size_;
182  std::vector<int8_t*> slabs_;
183  std::vector<BufferList> slab_segments_;
185 
186  private:
187  BufferMgr(const BufferMgr&); // private copy constructor
188  BufferMgr& operator=(const BufferMgr&); // private assignment
189  void removeSegment(BufferList::iterator& seg_it);
190  BufferList::iterator findFreeBufferInSlab(const size_t slab_num,
191  const size_t num_pages_requested);
192  int getBufferId();
193  virtual void addSlab(const size_t slab_size) = 0;
194  virtual void freeAllMem() = 0;
195  virtual void allocateBuffer(BufferList::iterator seg_it,
196  const size_t page_size,
197  const size_t num_bytes) = 0;
198  std::mutex chunk_index_mutex_;
199  std::mutex sized_segs_mutex_;
201  std::mutex buffer_id_mutex_;
202  std::mutex global_mutex_;
203 
204  std::map<ChunkKey, BufferList::iterator> chunk_index_;
205  size_t max_buffer_pool_num_pages_; // max number of pages for buffer pool
211  AbstractBufferMgr* parent_mgr_;
213  unsigned int buffer_epoch_;
214 
216 
217  BufferList::iterator evict(BufferList::iterator& evict_start,
218  const size_t num_pages_requested,
219  const int slab_num);
233  BufferList::iterator findFreeBuffer(size_t num_bytes);
234 };
235 
236 } // namespace Buffer_Namespace
std::string parse_error_str(const std::string &err, const size_t num_bytes=0)
Definition: BufferMgr.h:61
AbstractBufferMgr * parent_mgr_
Definition: BufferMgr.h:211
const size_t max_buffer_pool_size_
Definition: BufferMgr.h:176
unsigned int buffer_epoch_
Definition: BufferMgr.h:213
OutOfMemory(size_t num_bytes)
Definition: BufferMgr.h:43
std::map< ChunkKey, BufferList::iterator > chunk_index_
Definition: BufferMgr.h:204
std::string to_string(char const *&&v)
const size_t min_slab_size_
max number of bytes allocated for the buffer pool
Definition: BufferMgr.h:177
Note(s): Forbid Copying Idiom 4.1.
Definition: BufferMgr.h:97
OutOfMemory(const std::string &err)
Definition: BufferMgr.h:49
TooBigForSlab(size_t num_bytes)
Definition: BufferMgr.h:83
An AbstractBuffer is a unit of data management for a data manager.
OutOfMemory(const std::string &err, size_t num_bytes)
Definition: BufferMgr.h:54
std::mutex unsized_segs_mutex_
Definition: BufferMgr.h:200
FailedToCreateFirstSlab(size_t num_bytes)
Definition: BufferMgr.h:72
FailedToCreateSlab(size_t num_bytes)
Definition: BufferMgr.h:78
std::vector< int > ChunkKey
Definition: types.h:35
std::vector< std::pair< ChunkKey, std::shared_ptr< ChunkMetadata > >> ChunkMetadataVector
std::vector< int8_t * > slabs_
Definition: BufferMgr.h:182
std::list< BufferSeg > BufferList
Definition: BufferSeg.h:71
#define VLOG(n)
Definition: Logger.h:291