Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
mem-pool.h
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 
16 #ifndef IMPALA_RUNTIME_MEM_POOL_H
17 #define IMPALA_RUNTIME_MEM_POOL_H
18 
19 #include <stdio.h>
20 #include <algorithm>
21 #include <vector>
22 #include <string>
23 
24 #include "common/logging.h"
25 #include "util/runtime-profile.h"
26 
27 namespace impala {
28 
29 class MemTracker;
30 
35 //
40 //
48 //
68 //
76 
77 class MemPool {
78  public:
83  MemPool(MemTracker* mem_tracker, int chunk_size = 0);
84 
87  ~MemPool();
88 
92  uint8_t* Allocate(int size) {
93  return Allocate<false>(size);
94  }
95 
100  uint8_t* TryAllocate(int size) {
101  return Allocate<true>(size);
102  }
103 
107  void ReturnPartialAllocation(int byte_size) {
108  DCHECK_GE(byte_size, 0);
109  DCHECK(current_chunk_idx_ != -1);
111  DCHECK(info.owns_data);
112  DCHECK_GE(info.allocated_bytes, byte_size);
113  info.allocated_bytes -= byte_size;
114  total_allocated_bytes_ -= byte_size;
115  }
116 
118  void Clear() {
119  current_chunk_idx_ = -1;
120  for (std::vector<ChunkInfo>::iterator chunk = chunks_.begin();
121  chunk != chunks_.end(); ++chunk) {
122  chunk->cumulative_allocated_bytes = 0;
123  chunk->allocated_bytes = 0;
124  }
126  DCHECK(CheckIntegrity(false));
127  }
128 
131  void FreeAll();
132 
137  void AcquireData(MemPool* src, bool keep_current);
138 
144  bool Contains(uint8_t* ptr, int size);
145 
146  std::string DebugString();
147 
148  int64_t total_allocated_bytes() const { return total_allocated_bytes_; }
149  int64_t peak_allocated_bytes() const { return peak_allocated_bytes_; }
150  int64_t total_reserved_bytes() const { return total_reserved_bytes_; }
152 
154  int64_t GetTotalChunkSizes() const;
155 
159  int GetOffset(uint8_t* data);
160 
163  int GetCurrentOffset() const { return total_allocated_bytes_; }
164 
167  uint8_t* GetDataPtr(int offset);
168 
170  void GetChunkInfo(std::vector<std::pair<uint8_t*, int> >* chunk_info);
171 
173  std::string DebugPrint();
174 
177  static const char* LLVM_CLASS_NAME;
178 
179  private:
180  friend class MemPoolTest;
181  static const int DEFAULT_INITIAL_CHUNK_SIZE = 4 * 1024;
182 
183  struct ChunkInfo {
184  bool owns_data; // true if we eventually need to dealloc data
185  uint8_t* data;
186  int size; // in bytes
187 
192 
195 
196  explicit ChunkInfo(int size);
197 
199  : owns_data(true),
200  data(NULL),
201  size(0),
203  allocated_bytes(0) {}
204  };
205 
212 
216 
217  int chunk_size_; // if != 0, use this size for new chunks
218 
221 
224 
227 
228  std::vector<ChunkInfo> chunks_;
229 
233 
239  bool FindChunk(int min_size, bool check_limits);
240 
244  bool CheckIntegrity(bool current_chunk_empty);
245 
246  int GetOffsetHelper(uint8_t* data);
247  uint8_t* GetDataPtrHelper(int offset);
248 
250  int GetFreeOffset() const {
251  if (current_chunk_idx_ == -1) return 0;
252  return chunks_[current_chunk_idx_].allocated_bytes;
253  }
254 
255  template <bool CHECK_LIMIT_FIRST>
256  uint8_t* Allocate(int size) {
257  if (size == 0) return NULL;
258 
259  int num_bytes = ((size + 7) / 8) * 8; // round up to nearest 8 bytes
260  if (current_chunk_idx_ == -1
261  || num_bytes + chunks_[current_chunk_idx_].allocated_bytes
262  > chunks_[current_chunk_idx_].size) {
263  if (CHECK_LIMIT_FIRST) {
264  // If we couldn't allocate a new chunk, return NULL.
265  if (!FindChunk(num_bytes, true)) return NULL;
266  } else {
267  FindChunk(num_bytes, false);
268  }
269  }
271  DCHECK(info.owns_data);
272  uint8_t* result = info.data + info.allocated_bytes;
273  DCHECK_LE(info.allocated_bytes + num_bytes, info.size);
274  info.allocated_bytes += num_bytes;
275  total_allocated_bytes_ += num_bytes;
276  DCHECK_LE(current_chunk_idx_, chunks_.size() - 1);
277  peak_allocated_bytes_ = std::max(total_allocated_bytes_, peak_allocated_bytes_);
278  return result;
279  }
280 };
281 
282 inline
283 int MemPool::GetOffset(uint8_t* data) {
286  if (info.data <= data && info.data + info.allocated_bytes > data) {
287  return info.cumulative_allocated_bytes + data - info.data;
288  }
289  }
290  return GetOffsetHelper(data);
291 }
292 
293 inline
297  if (info.cumulative_allocated_bytes <= offset
298  && info.cumulative_allocated_bytes + info.allocated_bytes > offset) {
299  return info.data + offset - info.cumulative_allocated_bytes;
300  }
301  }
302  return GetDataPtrHelper(offset);
303 }
304 
305 }
306 
307 #endif
int last_offset_conversion_chunk_idx_
Definition: mem-pool.h:215
bool CheckIntegrity(bool current_chunk_empty)
Definition: mem-pool.cc:265
int GetFreeOffset() const
Return offset to unoccpied space in current chunk.
Definition: mem-pool.h:250
MemTracker * mem_tracker_
Definition: mem-pool.h:232
bool Contains(uint8_t *ptr, int size)
Definition: mem-pool.cc:223
int64_t peak_allocated_bytes() const
Definition: mem-pool.h:149
int allocated_bytes
bytes allocated via Allocate() in this chunk
Definition: mem-pool.h:194
bool FindChunk(int min_size, bool check_limits)
Definition: mem-pool.cc:92
uint8_t * GetDataPtr(int offset)
Definition: mem-pool.h:294
uint8_t * TryAllocate(int size)
Definition: mem-pool.h:100
int64_t total_allocated_bytes() const
Definition: mem-pool.h:148
std::vector< ChunkInfo > chunks_
Definition: mem-pool.h:228
uint8_t * Allocate(int size)
Definition: mem-pool.h:256
std::string DebugPrint()
Print allocated bytes from all chunks.
Definition: mem-pool.cc:332
int64_t GetTotalChunkSizes() const
Return sum of chunk_sizes_.
Definition: mem-pool.cc:257
void AcquireData(MemPool *src, bool keep_current)
Definition: mem-pool.cc:161
static const int DEFAULT_INITIAL_CHUNK_SIZE
Definition: mem-pool.h:181
void Clear()
Makes all allocated chunks available for re-use, but doesn't delete any chunks.
Definition: mem-pool.h:118
void ReturnPartialAllocation(int byte_size)
Definition: mem-pool.h:107
uint8_t * GetDataPtrHelper(int offset)
Definition: mem-pool.cc:311
int64_t total_allocated_bytes_
sum of allocated_bytes_
Definition: mem-pool.h:220
void FreeAll()
Definition: mem-pool.cc:73
void GetChunkInfo(std::vector< std::pair< uint8_t *, int > > *chunk_info)
Return (data ptr, allocated bytes) pairs for all chunks owned by this mempool.
Definition: mem-pool.cc:325
MemTracker * mem_tracker()
Definition: mem-pool.h:151
int64_t peak_allocated_bytes_
Maximum number of bytes allocated from this pool at one time.
Definition: mem-pool.h:223
int GetCurrentOffset() const
Definition: mem-pool.h:163
int64_t total_reserved_bytes() const
Definition: mem-pool.h:150
This class is thread-safe.
Definition: mem-tracker.h:61
static const char * LLVM_CLASS_NAME
Definition: mem-pool.h:177
MemPool(MemTracker *mem_tracker, int chunk_size=0)
Definition: mem-pool.cc:33
int current_chunk_idx_
Definition: mem-pool.h:211
int64_t total_reserved_bytes_
sum of all bytes allocated in chunks_
Definition: mem-pool.h:226
uint8_t offset[7 *64-sizeof(uint64_t)]
int GetOffset(uint8_t *data)
Definition: mem-pool.h:283
std::string DebugString()
Definition: mem-pool.cc:238
int GetOffsetHelper(uint8_t *data)
Definition: mem-pool.cc:296
uint8_t * Allocate(int size)
Definition: mem-pool.h:92