// Copyright (c) 2015 Baidu, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Author: Ge,Jun (gejun@baidu.com) // Date: Fri Jun 5 18:25:40 CST 2015 // Do small memory allocations on continuous blocks. #ifndef BUTIL_ARENA_H #define BUTIL_ARENA_H #include <stdint.h> #include "butil/macros.h" namespace butil { struct ArenaOptions { size_t initial_block_size; size_t max_block_size; // Constructed with default options. ArenaOptions(); }; // Just a proof-of-concept, will be refactored in future CI. class Arena { public: explicit Arena(const ArenaOptions& options = ArenaOptions()); ~Arena(); void swap(Arena&); void* allocate(size_t n); void* allocate_aligned(size_t n); // not implemented. void clear(); private: DISALLOW_COPY_AND_ASSIGN(Arena); struct Block { uint32_t left_space() const { return size - alloc_size; } Block* next; uint32_t alloc_size; uint32_t size; char data[0]; }; void* allocate_in_other_blocks(size_t n); void* allocate_new_block(size_t n); Block* pop_block(Block* & head) { Block* saved_head = head; head = head->next; return saved_head; } Block* _cur_block; Block* _isolated_blocks; size_t _block_size; ArenaOptions _options; }; inline void* Arena::allocate(size_t n) { if (_cur_block != NULL && _cur_block->left_space() >= n) { void* ret = _cur_block->data + _cur_block->alloc_size; _cur_block->alloc_size += n; return ret; } return allocate_in_other_blocks(n); } } // namespace butil #endif // BUTIL_ARENA_H