aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
fixedAllocator_inl.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief Inlines of gum::FixedAllocator
25  *
26  * @author Pierre-Henri WUILLEMIN(@LIP6) and Jean-Christophe MAGNAN and Christophe
27  * GONZALES(@AMU)
28  *
29  */
30 // ============================================================================
31 #include <agrum/tools/core/smallobjectallocator/fixedAllocator.h>
32 // ============================================================================
33 
34 namespace gum {
35 
36  // ============================================================================
37  // Initializes a Chunk object
38  // ============================================================================
40  const unsigned char& numBlocks) {
41  // Chunk memory space allocation. A chunk allocates a memory of blockSize *
42  // numBlocks size.
43  // The chunk will then give us numBlocks distinct blocks of blockSize from
44  // that space.
45  _pData_ = new unsigned char[blockSize * numBlocks];
46 
47  // The first available block of memory is logically at the beginning.
49 
50  // The number of block still available is all the blocks at the beginning.
52 
53  // For each unallocated block, the first byte contains a number.
54  // That number is the index of the next available block
55  // Since we're at the beginning, next free block is the next one simply.
56  // Following code initiate those number for each block
57  unsigned char* p = _pData_;
58  for (unsigned char indexBlock = 0; indexBlock != numBlocks; p += blockSize)
59  *p = ++indexBlock;
60  }
61 
62  // ============================================================================
63  // Allocates a block of memory
64  // ============================================================================
66  if (!_blocksAvailable_)
67  // If no block is available return nullptr
68  return NULL;
69 
70  // _pData_ points to the beginning of allocated space.
71  // _firstAvailableBlock_ gives us how many block to pass before getting
72  // the good one. We have to multiply by blockSize to get the good memory
73  // emplacement
74  unsigned char* pResult = _pData_ + (_firstAvailableBlock_ * blockSize);
75 
76  // Remember that the first byte of each block gives us the index of next
77  // available slot.
78  // The new first availble block will be at the index indicating in this
79  // block.
81 
82  // We lose one block
84 
85  return pResult;
86  }
87 
88  // ============================================================================
89  // Deallocates a block of memory
90  // ============================================================================
92  const std::size_t& blockSize) {
93  // first, ensure that deallocated is in this chunk
95 
96  // Conversion pf pointer for handling
97  unsigned char* toRelease = static_cast< unsigned char* >(pDeallocatedBlock);
98 
99  // Alignement check
101 
102  // First byte of toRelease has now to give the index of current first
103  // available block
105 
106  // So that first available block points to it
107  _firstAvailableBlock_ = static_cast< unsigned char >((toRelease - _pData_) / blockSize);
108 
109  // Truncation check
111 
112  // We gain one block, yeah
114  }
115 
116  // ============================================================================
117  // Releases the allocated memory
118  // ============================================================================
120 
121 
122  // ############################################################################
123  // @name Constructors / Destructors
124  // ############################################################################
125 
126  // ============================================================================
127  // Constructor.
128  // ============================================================================
130  const unsigned char& numBlocks) {
131  // GUM_CONSTRUCTOR(FixedAllocator);
136  }
137 
138  // ============================================================================
139  // Destructor.
140  // ============================================================================
143  chunkIter->_release_();
144  // GUM_DESTRUCTOR(FixedAllocator);
145  }
146 
147  // ############################################################################
148  // @name Allocator / Deallocator
149  // ############################################################################
150 
151  // ============================================================================
152  // Allocates a block
153  // ============================================================================
155  if (_chunks_.empty() || _allocChunk_->_blocksAvailable_ == 0) {
156  // no available memory in this chunk
157  // Try to find one with memory available
159  if (chunksIter == _chunks_.end()) {
160  // All chunks are filled up. Adding a new one
161  _chunks_.reserve(_chunks_.size() + 1);
166  --_allocChunk_;
168  break;
169  }
170  if (chunksIter->_blocksAvailable_ > 0) {
171  // Found a chunk
173  break;
174  }
175  }
176  }
178  }
179 
180  // ============================================================================
181  // Deallocates a block
182  // ============================================================================
186  // If not things get ugly
187  // We have to find where the Chunk containing this pointer is
188  std::ptrdiff_t offset = 0;
189 
190  // We perform a bidirectionnal search from _deallocChunk_
191  while (true) {
192  ++offset;
193  // First we look for the one going to the end of the vector
194  if ((_deallocChunk_ + offset) < _chunks_.end()) {
198  // If pointed chunk contains this pointer, deallocation find the
199  // place
201  break;
202  }
203  }
204 
205  // Then we look for the one going to the beginning of the vector
206  if ((_deallocChunk_ - offset) >= _chunks_.begin()) {
210  // If pointed chunk contains this pointer, deallocation find the
211  // place
213  break;
214  }
215  }
216  }
217  }
219  }
220 
221 } // namespace gum
INLINE void emplace(Args &&... args)
Definition: set_tpl.h:643