aboutsummaryrefslogtreecommitdiff
path: root/arena.cuh
diff options
context:
space:
mode:
Diffstat (limited to 'arena.cuh')
-rw-r--r--arena.cuh68
1 files changed, 68 insertions, 0 deletions
diff --git a/arena.cuh b/arena.cuh
new file mode 100644
index 0000000..20da470
--- /dev/null
+++ b/arena.cuh
@@ -0,0 +1,68 @@
+//
+// Created by user on 20/10/2021.
+//
+
+#ifndef CLEVELDB_ARENA_CUH
+#define CLEVELDB_ARENA_CUH
+
+
+#include <atomic>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+namespace cleveldb {
+
+
+class Arena {
+public:
+ Arena();
+ Arena(const Arena &) = delete;
+
+ Arena& operator=(const Arena&) = delete;
+
+ ~Arena();
+
+ // Return a pointer to a newly allocated memory block of "bytes" bytes.
+ char* Allocate(size_t bytes);
+
+ // Allocate memory with the normal alignment guarantees provided by malloc.
+ char* AllocateAligned(size_t bytes);
+
+ // Returns an estimate of the total memory usage of data allocated
+ // by the arena.
+ size_t MemoryUsage() const {
+ return memory_usage_.load(std::memory_order_relaxed);
+ }
+
+private:
+ char* AllocateFallback(size_t bytes);
+ char* AllocateNewBlock(size_t block_bytes);
+
+ char* alloc_ptr_;
+ size_t alloc_bytes_remaining_;
+
+ std::vector<char*> blocks_;
+
+ std::atomic<size_t> memory_usage_;
+};
+
+inline char* Arena::Allocate(size_t bytes) {
+ // The semantics of what to return are a bit messy if we allow
+ // 0-byte allocations, so we disallow them here (we don't need
+ // them for our internal use).
+ assert(bytes > 0);
+ if (bytes <= alloc_bytes_remaining_) {
+ char* result = alloc_ptr_;
+ alloc_ptr_ += bytes;
+ alloc_bytes_remaining_ -= bytes;
+ return result;
+ }
+ return AllocateFallback(bytes);
+}
+
+
+} // namespace cleveldb
+
+#endif //CLEVELDB_ARENA_CUH