OmniSciDB  04ee39c94c
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 #ifndef DATAMGR_MEMORY_BUFFER_BUFFERMGR_H
26 #define DATAMGR_MEMORY_BUFFER_BUFFERMGR_H
27 
28 #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED 1
29 
30 #include <boost/stacktrace.hpp>
31 #include <iostream>
32 #include <list>
33 #include <map>
34 #include <mutex>
35 #include "../../Shared/types.h"
36 #include "../AbstractBuffer.h"
37 #include "../AbstractBufferMgr.h"
38 #include "BufferSeg.h"
39 
40 class OutOfMemory : public std::runtime_error {
41  public:
42  OutOfMemory(size_t numBytes)
43  : std::runtime_error(parse_error_str("OutOfMemory", numBytes)) {
44  VLOG(1) << "Failed to allocate " << numBytes << " bytes";
45  VLOG(1) << boost::stacktrace::stacktrace();
46  };
47 
48  OutOfMemory(const std::string& err) : std::runtime_error(parse_error_str(err, 0)) {
49  VLOG(1) << "Failed with OutOfMemory, condition " << err;
50  VLOG(1) << boost::stacktrace::stacktrace();
51  };
52 
53  OutOfMemory(const std::string& err, size_t numBytes)
54  : std::runtime_error(parse_error_str(err, numBytes)) {
55  VLOG(1) << "Failed to allocate " << numBytes << " bytes with condition " << err;
56  VLOG(1) << boost::stacktrace::stacktrace();
57  };
58 
59  private:
60  std::string parse_error_str(const std::string& err, const size_t numBytes = 0) {
61  if (numBytes) {
62  return err + ": Failed to allocate " + std::to_string(numBytes) + " bytes";
63  } else {
64  return "Failed to allocate memory with condition " + err;
65  }
66  }
67 };
68 
70  public:
71  FailedToCreateFirstSlab(size_t numBytes)
72  : OutOfMemory("FailedToCreateFirstSlab", numBytes) {}
73 };
74 
76  public:
77  FailedToCreateSlab(size_t numBytes) : OutOfMemory("FailedToCreateSlab", numBytes) {}
78 };
79 
80 class TooBigForSlab : public OutOfMemory {
81  public:
82  TooBigForSlab(size_t numBytes) : OutOfMemory("TooBigForSlab", numBytes) {}
83 };
84 
85 using namespace Data_Namespace;
86 
87 namespace Buffer_Namespace {
88 
96 class BufferMgr : public AbstractBufferMgr { // implements
97 
98  public:
100  //@todo change this to size_t
101  // explicit BufferMgr(const size_t bufferSize, const size_t pageSize);
102  BufferMgr(const int deviceId,
103  const size_t maxBufferSize,
104  const size_t maxSlabSize = 2147483648,
105  const size_t pageSize = 512,
106  AbstractBufferMgr* parentMgr = 0);
107 
109  ~BufferMgr() override;
110  void reinit();
111 
112  void clear();
113 
114  std::string printSlab(size_t slabNum);
115  std::string printSlabs() override;
116  void clearSlabs() override;
117  std::string printMap();
118  void printSegs();
119  std::string printSeg(BufferList::iterator& segIt);
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 pageSize = 0,
133  const size_t initialSize = 0) override;
134 
136  void deleteBuffer(const ChunkKey& key, const bool purge = true) override;
137  void deleteBuffersWithPrefix(const ChunkKey& keyPrefix,
138  const bool purge = true) override;
139 
141  AbstractBuffer* getBuffer(const ChunkKey& key, const size_t numBytes = 0) override;
142 
149  bool isBufferOnDevice(const ChunkKey& key) override;
150  void fetchBuffer(const ChunkKey& key,
151  AbstractBuffer* destBuffer,
152  const size_t numBytes = 0) override;
153  AbstractBuffer* putBuffer(const ChunkKey& key,
154  AbstractBuffer* d,
155  const size_t numBytes = 0) override;
156  void checkpoint() override;
157  void checkpoint(const int db_id, const int tb_id) override;
158 
159  // Buffer API
160  AbstractBuffer* alloc(const size_t numBytes = 0) override;
161  void free(AbstractBuffer* buffer) override;
162  // virtual AbstractBuffer* putBuffer(AbstractBuffer *d);
163 
165  size_t size();
166  size_t getNumChunks() override;
167 
168  BufferList::iterator reserveBuffer(BufferList::iterator& segIt, const size_t numBytes);
169  void getChunkMetadataVec(
170  std::vector<std::pair<ChunkKey, ChunkMetadata>>& chunkMetadataVec) override;
171  void getChunkMetadataVecForKeyPrefix(
172  std::vector<std::pair<ChunkKey, ChunkMetadata>>& chunkMetadataVec,
173  const ChunkKey& keyPrefix) override;
174 
175  protected:
176  std::vector<int8_t*> slabs_;
177  std::vector<BufferList> slabSegments_;
179  size_t pageSize_;
180 
181  private:
182  BufferMgr(const BufferMgr&); // private copy constructor
183  BufferMgr& operator=(const BufferMgr&); // private assignment
184  void removeSegment(BufferList::iterator& segIt);
185  BufferList::iterator findFreeBufferInSlab(const size_t slabNum,
186  const size_t numPagesRequested);
187  int getBufferId();
188  virtual void addSlab(const size_t slabSize) = 0;
189  virtual void freeAllMem() = 0;
190  virtual void allocateBuffer(BufferList::iterator segIt,
191  const size_t pageSize,
192  const size_t numBytes) = 0;
193  std::mutex chunkIndexMutex_;
194  std::mutex sizedSegsMutex_;
195  std::mutex unsizedSegsMutex_;
196  std::mutex bufferIdMutex_;
197  std::mutex globalMutex_;
198 
199  std::map<ChunkKey, BufferList::iterator> chunkIndex_;
200  size_t maxBufferSize_;
201  size_t maxNumPages_;
205  size_t maxSlabSize_;
206  bool allocationsCapped_;
210  unsigned int bufferEpoch_;
211  // File_Namespace::FileMgr *fileMgr_;
212 
214  //@todo change this to multimap
215  // std::multimap<size_t, int8_t *> freeMem_;
217  // std::map<size_t, int8_t *> freeMem_;
218 
219  BufferList::iterator evict(BufferList::iterator& evictStart,
220  const size_t numPagesRequested,
221  const int slabNum);
222  BufferList::iterator findFreeBuffer(size_t numBytes);
223 
237 };
238 
239 } // namespace Buffer_Namespace
240 
241 #endif // DATAMGR_MEMORY_BUFFER_BUFFERMGR_H
void d(const SQLTypes expected_type, const std::string &str)
Definition: ImportTest.cpp:268
std::map< ChunkKey, BufferList::iterator > chunkIndex_
Definition: BufferMgr.h:199
AbstractBufferMgr * parentMgr_
Definition: BufferMgr.h:208
BufferList unsizedSegs_
Maps sizes of free memory areas to host buffer pool memory addresses.
Definition: BufferMgr.h:216
std::string to_string(char const *&&v)
FailedToCreateFirstSlab(size_t numBytes)
Definition: BufferMgr.h:71
Note(s): Forbid Copying Idiom 4.1.
Definition: BufferMgr.h:96
OutOfMemory(const std::string &err)
Definition: BufferMgr.h:48
OutOfMemory(size_t numBytes)
Definition: BufferMgr.h:42
An AbstractBuffer is a unit of data management for a data manager.
size_t maxNumPages_
max number of bytes allocated for the buffer pool
Definition: BufferMgr.h:201
std::string parse_error_str(const std::string &err, const size_t numBytes=0)
Definition: BufferMgr.h:60
std::vector< int > ChunkKey
Definition: types.h:35
FailedToCreateSlab(size_t numBytes)
Definition: BufferMgr.h:77
std::vector< int8_t * > slabs_
Definition: BufferMgr.h:176
OutOfMemory(const std::string &err, size_t numBytes)
Definition: BufferMgr.h:53
TooBigForSlab(size_t numBytes)
Definition: BufferMgr.h:82
std::list< BufferSeg > BufferList
Definition: BufferSeg.h:69
#define VLOG(n)
Definition: Logger.h:277