1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4: 3 #ident "$Id$" 4 /*====== 5 This file is part of PerconaFT. 6 7 8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. 9 10 PerconaFT is free software: you can redistribute it and/or modify 11 it under the terms of the GNU General Public License, version 2, 12 as published by the Free Software Foundation. 13 14 PerconaFT is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. 21 22 ---------------------------------------- 23 24 PerconaFT is free software: you can redistribute it and/or modify 25 it under the terms of the GNU Affero General Public License, version 3, 26 as published by the Free Software Foundation. 27 28 PerconaFT is distributed in the hope that it will be useful, 29 but WITHOUT ANY WARRANTY; without even the implied warranty of 30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 GNU Affero General Public License for more details. 32 33 You should have received a copy of the GNU Affero General Public License 34 along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. 35 36 ---------------------------------------- 37 38 Licensed under the Apache License, Version 2.0 (the "License"); 39 you may not use this file except in compliance with the License. 40 You may obtain a copy of the License at 41 42 http://www.apache.org/licenses/LICENSE-2.0 43 44 Unless required by applicable law or agreed to in writing, software 45 distributed under the License is distributed on an "AS IS" BASIS, 46 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 47 See the License for the specific language governing permissions and 48 limitations under the License. 49 ======= */ 50 51 #ident \ 52 "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." 53 54 #pragma once 55 56 #include <stdlib.h> 57 58 /* 59 * A memarena is used to efficiently store a collection of objects that never 60 * move The pattern is allocate more and more stuff and free all of the items at 61 * once. The underlying memory will store 1 or more objects per chunk. Each 62 * chunk is contiguously laid out in memory but chunks are not necessarily 63 * contiguous with each other. 64 */ 65 class memarena { 66 public: memarena()67 memarena() 68 : _current_chunk(arena_chunk()), 69 _other_chunks(nullptr), 70 _n_other_chunks(0), 71 _size_of_other_chunks(0), 72 _footprint_of_other_chunks(0) {} 73 74 // Effect: Create a memarena with the specified initial size 75 void create(size_t initial_size); 76 77 void destroy(void); 78 79 // Effect: Allocate some memory. The returned value remains valid until the 80 // memarena is cleared or closed. 81 // In case of ENOMEM, aborts. 82 void *malloc_from_arena(size_t size); 83 84 // Effect: Move all the memory from this memarena into DEST. 85 // When SOURCE is closed the memory won't be freed. 86 // When DEST is closed, the memory will be freed, unless DEST moves 87 // its memory to another memarena... 88 void move_memory(memarena *dest); 89 90 // Effect: Calculate the amount of memory used by a memory arena. 91 size_t total_memory_size(void) const; 92 93 // Effect: Calculate the used space of the memory arena (ie: excludes unused 94 // space) 95 size_t total_size_in_use(void) const; 96 97 // Effect: Calculate the amount of memory used, according to 98 // toku_memory_footprint(), 99 // which is a more expensive but more accurate count of memory used. 100 size_t total_footprint(void) const; 101 102 // iterator over the underlying chunks that store objects in the memarena. 103 // a chunk is represented by a pointer to const memory and a usable byte 104 // count. 105 class chunk_iterator { 106 public: chunk_iterator(const memarena * ma)107 chunk_iterator(const memarena *ma) : _ma(ma), _chunk_idx(-1) {} 108 109 // returns: base pointer to the current chunk 110 // *used set to the number of usable bytes 111 // if more() is false, returns nullptr and *used = 0 112 const void *current(size_t *used) const; 113 114 // requires: more() is true 115 void next(); 116 117 bool more() const; 118 119 private: 120 // -1 represents the 'initial' chunk in a memarena, ie: ma->_current_chunk 121 // >= 0 represents the i'th chunk in the ma->_other_chunks array 122 const memarena *_ma; 123 int _chunk_idx; 124 }; 125 126 private: 127 struct arena_chunk { arena_chunkarena_chunk128 arena_chunk() : buf(nullptr), used(0), size(0) {} 129 char *buf; 130 size_t used; 131 size_t size; 132 }; 133 134 struct arena_chunk _current_chunk; 135 struct arena_chunk *_other_chunks; 136 int _n_other_chunks; 137 size_t _size_of_other_chunks; // the buf_size of all the other chunks. 138 size_t _footprint_of_other_chunks; // the footprint of all the other chunks. 139 140 friend class memarena_unit_test; 141 }; 142