OmniSciDB  1dac507f6e
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 max_slab_size = 2147483648,
104  const size_t page_size = 512,
105  AbstractBufferMgr* parent_mgr = 0);
106 
108  ~BufferMgr() override;
109  void reinit();
110 
111  void clear();
112 
113  std::string printSlab(size_t slab_num);
114  std::string printSlabs() override;
115  void clearSlabs() override;
116  std::string printMap();
117  void printSegs();
118  std::string printSeg(BufferList::iterator& seg_it);
119  std::string keyToString(const ChunkKey& key);
120  size_t getInUseSize() override;
121  size_t getMaxSize() override;
122  size_t getAllocated() override;
123  size_t getMaxBufferSize();
124  size_t getMaxSlabSize();
125  size_t getPageSize();
126  bool isAllocationCapped() override;
127  const std::vector<BufferList>& getSlabSegments();
128 
130  AbstractBuffer* createBuffer(const ChunkKey& key,
131  const size_t page_size = 0,
132  const size_t initial_size = 0) override;
133 
135  void deleteBuffer(const ChunkKey& key, const bool purge = true) override;
136  void deleteBuffersWithPrefix(const ChunkKey& key_prefix,
137  const bool purge = true) override;
138 
140  AbstractBuffer* getBuffer(const ChunkKey& key, const size_t num_bytes = 0) override;
141 
148  bool isBufferOnDevice(const ChunkKey& key) override;
149  void fetchBuffer(const ChunkKey& key,
150  AbstractBuffer* dest_buffer,
151  const size_t num_bytes = 0) override;
152  AbstractBuffer* putBuffer(const ChunkKey& key,
153  AbstractBuffer* d,
154  const size_t num_bytes = 0) override;
155  void checkpoint() override;
156  void checkpoint(const int db_id, const int tb_id) override;
157 
158  // Buffer API
159  AbstractBuffer* alloc(const size_t num_bytes = 0) override;
160  void free(AbstractBuffer* buffer) override;
161 
163  size_t size();
164  size_t getNumChunks() override;
165 
166  BufferList::iterator reserveBuffer(BufferList::iterator& seg_it,
167  const size_t num_bytes);
168  void getChunkMetadataVec(
169  std::vector<std::pair<ChunkKey, ChunkMetadata>>& chunk_metadata_vec) override;
170  void getChunkMetadataVecForKeyPrefix(
171  std::vector<std::pair<ChunkKey, ChunkMetadata>>& chunk_metadata_vec,
172  const ChunkKey& key_prefix) override;
173 
174  protected:
175  std::vector<int8_t*> slabs_;
176  std::vector<BufferList> slab_segments_;
178  size_t page_size_;
179 
180  private:
181  BufferMgr(const BufferMgr&); // private copy constructor
182  BufferMgr& operator=(const BufferMgr&); // private assignment
183  void removeSegment(BufferList::iterator& seg_it);
184  BufferList::iterator findFreeBufferInSlab(const size_t slab_num,
185  const size_t num_pages_requested);
186  int getBufferId();
187  virtual void addSlab(const size_t slab_size) = 0;
188  virtual void freeAllMem() = 0;
189  virtual void allocateBuffer(BufferList::iterator seg_it,
190  const size_t page_size,
191  const size_t num_bytes) = 0;
192  std::mutex chunk_index_mutex_;
193  std::mutex sized_segs_mutex_;
195  std::mutex buffer_id_mutex_;
196  std::mutex global_mutex_;
197 
198  std::map<ChunkKey, BufferList::iterator> chunk_index_;
204  size_t max_slab_size_;
205  bool allocations_capped_;
209  unsigned int buffer_epoch_;
210 
212 
213  BufferList::iterator evict(BufferList::iterator& evict_start,
214  const size_t num_pages_requested,
215  const int slab_num);
229  BufferList::iterator findFreeBuffer(size_t num_bytes);
230 };
231 
232 } // 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:207
std::vector< int > ChunkKey
Definition: types.h:35
unsigned int buffer_epoch_
Definition: BufferMgr.h:209
OutOfMemory(size_t num_bytes)
Definition: BufferMgr.h:43
std::map< ChunkKey, BufferList::iterator > chunk_index_
Definition: BufferMgr.h:198
std::string to_string(char const *&&v)
Note(s): Forbid Copying Idiom 4.1.
Definition: BufferMgr.h:97
OutOfMemory(const std::string &err)
Definition: BufferMgr.h:49
size_t max_num_pages_
max number of bytes allocated for the buffer pool
Definition: BufferMgr.h:200
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:194
FailedToCreateFirstSlab(size_t num_bytes)
Definition: BufferMgr.h:72
FailedToCreateSlab(size_t num_bytes)
Definition: BufferMgr.h:78
std::vector< int8_t * > slabs_
Definition: BufferMgr.h:175
std::list< BufferSeg > BufferList
Definition: BufferSeg.h:71
#define VLOG(n)
Definition: Logger.h:280