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. |
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 | |
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 | |