1 /*******************************************************************************
2 3 Interface for an object allocator.
4 5 Copyright:
6 Copyright (c) 2009-2016 dunnhumby Germany GmbH.
7 All rights reserved.
8 9 License:
10 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
11 Alternatively, this file may be distributed under the terms of the Tango
12 3-Clause BSD License (see LICENSE_BSD.txt for details).
13 14 *******************************************************************************/15 16 moduleocean.util.container.map.model.IAllocator;
17 18 /******************************************************************************/19 20 21 22 abstractclassIAllocator23 {
24 /***************************************************************************
25 26 Tracks amount of memory used by this allocator.
27 28 ***************************************************************************/29 30 privatesize_tused_memory;
31 32 /***************************************************************************
33 34 Stores the size of a single allocated element.
35 36 ***************************************************************************/37 38 protectedsize_tbucket_element_size;
39 40 41 /***************************************************************************
42 43 Constructor.
44 45 Params:
46 bucket_element_sizeof = the amount of memory used by each allocated
47 element.
48 49 ***************************************************************************/50 51 publicthis ( size_tbucket_element_sizeof )
52 {
53 this.bucket_element_size = bucket_element_sizeof;
54 }
55 56 /***************************************************************************
57 58 Gets or allocates an object
59 60 Returns:
61 an object that is ready to use.
62 63 ***************************************************************************/64 65 publicvoid* get ( )
66 {
67 this.used_memory += this.bucket_element_size;
68 returnthis.allocate();
69 }
70 71 /***************************************************************************
72 73 Performs the actual allocation of an object
74 75 Returns:
76 an object that is ready to use.
77 78 ***************************************************************************/79 80 protectedabstractvoid* allocate ();
81 82 /***************************************************************************
83 84 Recycles or deletes an object that is no longer used.
85 86 Note: Strictly specking old should be a ref to satisfy D's delete
87 expression which wants the pointer as an lvalue in order to set it to
88 null after deletion. However, would make code more complex and isn't
89 actually necessary in the particular use case of this interface (see
90 BucketSet.remove()/clear()).
91 92 Params:
93 old = old object
94 95 ***************************************************************************/96 97 publicvoidrecycle ( void* old )
98 {
99 this.used_memory -= this.bucket_element_size;
100 returnthis.deallocate(old);
101 }
102 103 /***************************************************************************
104 105 Performs the actual recycling of an object. See recycle() documentation.
106 107 Params:
108 old = old object
109 110 ***************************************************************************/111 112 protectedabstractvoiddeallocate ( void* old );
113 114 /***************************************************************************
115 116 Return the amount of memory currently used.
117 118 Returns:
119 the size of the memory allocated by this allocator
120 121 ***************************************************************************/122 123 publicsize_tmemoryUsed ()
124 {
125 returnthis.used_memory;
126 }
127 128 /***************************************************************************
129 130 Helper class to temprarily park a certain number of objects.
131 132 ***************************************************************************/133 134 staticabstract/* scope */classIParkingStack135 {
136 importocean.core.Verify;
137 138 /**********************************************************************
139 140 Maximum number of objects as passed to the constructor.
141 142 **********************************************************************/143 144 publicsize_tmax_length ( )
145 {
146 returnthis._max_length;
147 }
148 149 privatesize_t_max_length;
150 151 /**********************************************************************
152 153 Number of elements currently on the stack. This value is always
154 at most max_length.
155 156 **********************************************************************/157 158 privatesize_tn = 0;
159 160 invariant ( )
161 {
162 assert(this.n <= this._max_length);
163 }
164 165 /**********************************************************************
166 167 Constructor.
168 169 Params:
170 max_length = maximum number of objects that will be stored
171 172 **********************************************************************/173 174 protectedthis ( size_tmax_length )
175 {
176 this._max_length = max_length;
177 }
178 179 /**********************************************************************
180 181 Pushes an object on the stack.
182 183 Params:
184 object = object to push
185 186 Returns:
187 object
188 189 In:
190 Less than max_length objects may be parked.
191 192 **********************************************************************/193 194 publicvoid* push ( void* object )
195 {
196 verify(this.n < this._max_length);
197 198 this.push_(object, this.n++);
199 200 returnobject;
201 }
202 203 /**********************************************************************
204 205 Pops an object from the stack.
206 207 Returns:
208 object popped from the stack or null if the stack is empty.
209 210 Out:
211 If an element is returned, less than max_length elements must be
212 on the stack, otherwise the stack must be empty.
213 214 **********************************************************************/215 216 publicvoid* pop ( )
217 out (element)
218 {
219 if (element)
220 {
221 assert(this.n < this._max_length);
222 }
223 else224 {
225 assert(!this.n);
226 }
227 }
228 do229 {
230 if (this.n)
231 {
232 returnthis.pop_(--this.n);
233 }
234 else235 {
236 returnnull;
237 }
238 }
239 240 /**********************************************************************
241 242 'foreach' iteration, each cycle pops an element from the stack and
243 iterates over it.
244 245 **********************************************************************/246 247 publicintopApply ( scopeintdelegate ( refvoid* object ) dg )
248 {
249 intr = 0;
250 251 for (void* object = this.pop(); object && !r; object = this.pop())
252 {
253 r = dg(object);
254 }
255 256 returnr;
257 }
258 259 /**********************************************************************
260 261 Pushes an object on the stack.
262 263 Params:
264 object = object to push
265 n = number of parked objects before object is pushed
266 (guaranteed to be less than max_length)
267 268 **********************************************************************/269 270 abstractprotectedvoidpush_ ( void* object, size_tn );
271 272 /**********************************************************************
273 274 Pops an object from the stack. This method is never called if the
275 stack is empty.
276 277 Params:
278 n = number of parked objects after object is popped (guaranteed
279 to be less than max_length)
280 281 Returns:
282 object popped from the stack or null if the stack is empty.
283 284 **********************************************************************/285 286 abstractprotectedvoid* pop_ ( size_tn );
287 }
288 289 /***************************************************************************
290 291 Calls dg with an IParkingStack instance that is set up to keep n
292 elements.
293 294 Params:
295 n = number of elements to park
296 dg = delegate to call with the IParkingStack instance
297 298 ***************************************************************************/299 300 voidparkElements ( size_tn, scopevoiddelegate ( IParkingStackpark ) dg );
301 }