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)55inline 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