1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 
5 #ifndef STORAGE_LEVELDB_UTIL_ARENA_H_
6 #define STORAGE_LEVELDB_UTIL_ARENA_H_
7 
8 #include <atomic>
9 #include <cassert>
10 #include <cstddef>
11 #include <cstdint>
12 #include <vector>
13 
14 namespace leveldb {
15 
16 class Arena {
17  public:
18   Arena();
19 
20   Arena(const Arena&) = delete;
21   Arena& operator=(const Arena&) = delete;
22 
23   ~Arena();
24 
25   // Return a pointer to a newly allocated memory block of "bytes" bytes.
26   char* Allocate(size_t bytes);
27 
28   // Allocate memory with the normal alignment guarantees provided by malloc.
29   char* AllocateAligned(size_t bytes);
30 
31   // Returns an estimate of the total memory usage of data allocated
32   // by the arena.
MemoryUsage()33   size_t MemoryUsage() const {
34     return memory_usage_.load(std::memory_order_relaxed);
35   }
36 
37  private:
38   char* AllocateFallback(size_t bytes);
39   char* AllocateNewBlock(size_t block_bytes);
40 
41   // Allocation state
42   char* alloc_ptr_;
43   size_t alloc_bytes_remaining_;
44 
45   // Array of new[] allocated memory blocks
46   std::vector<char*> blocks_;
47 
48   // Total memory usage of the arena.
49   //
50   // TODO(costan): This member is accessed via atomics, but the others are
51   //               accessed without any locking. Is this OK?
52   std::atomic<size_t> memory_usage_;
53 };
54 
Allocate(size_t bytes)55 inline char* Arena::Allocate(size_t bytes) {
56   // The semantics of what to return are a bit messy if we allow
57   // 0-byte allocations, so we disallow them here (we don't need
58   // them for our internal use).
59   assert(bytes > 0);
60   if (bytes <= alloc_bytes_remaining_) {
61     char* result = alloc_ptr_;
62     alloc_ptr_ += bytes;
63     alloc_bytes_remaining_ -= bytes;
64     return result;
65   }
66   return AllocateFallback(bytes);
67 }
68 
69 }  // namespace leveldb
70 
71 #endif  // STORAGE_LEVELDB_UTIL_ARENA_H_
72