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