2 * Copyright 2002 Adrian Thurston <thurston@cs.queensu.ca>
5 /* This file is part of Aapl.
7 * Aapl is free software; you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free
9 * Software Foundation; either version 2.1 of the License, or (at your option)
12 * Aapl is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with Aapl; if not, write to the Free Software Foundation, Inc., 59
19 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #ifndef _AAPL_RESIZE_H
23 #define _AAPL_RESIZE_H
31 /* This step is expressed in units of T. Changing this requires changes to
32 * docs in ResizeLin constructor. */
33 #define LIN_DEFAULT_STEP 256
36 * Resizing macros giving different resize methods.
39 /* If needed is greater than existing, give twice needed. */
40 #define EXPN_UP( existing, needed ) \
41 needed > existing ? (needed<<1) : existing
43 /* If needed is less than 1 quarter existing, give twice needed. */
44 #define EXPN_DOWN( existing, needed ) \
45 needed < (existing>>2) ? (needed<<1) : existing
47 /* If needed is greater than existing, give needed plus step. */
48 #define LIN_UP( existing, needed ) \
49 needed > existing ? (needed+step) : existing
51 /* If needed is less than existing - 2 * step then give needed plus step. */
52 #define LIN_DOWN( existing, needed ) \
53 needed < (existing-(step<<1)) ? (needed+step) : existing
55 /* Return existing. */
56 #define CONST_UP( existing, needed ) existing
58 /* Return existing. */
59 #define CONST_DOWN( existing, needed ) existing
67 * \brief Linear table resizer.
69 * When an up resize or a down resize is needed, ResizeLin allocates the space
70 * needed plus some user defined step. The result is that when growing the
71 * vector in a linear fashion, the number of resizes is also linear.
73 * If only up resizing is done, then there will never be more than step unused
74 * spaces in the vector. If down resizing is done as well, there will never be
75 * more than 2*step unused spaces in the vector. The up resizing and down
76 * resizing policies are offset to improve performance when repeatedly
77 * inserting and removing a small number of elements relative to the step.
78 * This scheme guarantees that repetitive inserting and removing of a small
79 * number of elements will never result in repetative reallocation.
81 * The vectors pass sizes to the resizer in units of T, so the step gets
82 * interpreted as units of T.
87 /* Linear resizing. */
92 * \brief Default constructor.
94 * Intializes resize step to 256 units of the table type T.
96 ResizeLin() : step(LIN_DEFAULT_STEP
) { }
99 * \brief Determine the new table size when up resizing.
101 * If the existing size is insufficient for the space needed, then allocate
102 * the space needed plus the step. The step is in units of T.
104 inline long upResize( long existing
, long needed
)
105 { return LIN_UP(existing
, needed
); }
108 * \brief Determine the new table size when down resizing.
110 * If space needed is less than the existing - 2*step, then allocate the
111 * space needed space plus the step. The step is in units of T.
113 inline long downResize( long existing
, long needed
)
114 { return LIN_DOWN(existing
, needed
); }
118 * \brief Step for linear resize.
120 * Amount of extra space in units of T added each time a resize must take
121 * place. This may be changed at any time. The step should be >= 0.
131 /** \class ResizeCtLin
132 * \brief Linear table resizer with compile time step.
134 * When an up resize or a down resize is needed, ResizeCtLin allocates the
135 * space needed plus some compile time defined step. The result is that when
136 * growing the vector in a linear fashion, the number of resizes is also
139 * If only up resizing is done, then there will never be more than step unused
140 * spaces in the vector. If down resizing is done as well, there will never be
141 * more than 2*step unused spaces in the vector. The up resizing and down
142 * resizing policies are offset to improve performance when repeatedly
143 * inserting and removing a small number of elements relative to the step.
144 * This scheme guarantees that repetitive inserting and removing of a small
145 * number of elements will never result in repetative reallocation.
147 * The vectors pass sizes to the resizer in units of T, so the step gets
148 * interpreted as units of T.
153 /* Linear resizing. */
154 template <long step
> class ResizeCtLin
158 * \brief Determine the new table size when up resizing.
160 * If the existing size is insufficient for the space needed, then allocate
161 * the space needed plus the step. The step is in units of T.
163 inline long upResize( long existing
, long needed
)
164 { return LIN_UP(existing
, needed
); }
167 * \brief Determine the new table size when down resizing.
169 * If space needed is less than the existing - 2*step, then allocate the
170 * space needed space plus the step. The step is in units of T.
172 inline long downResize( long existing
, long needed
)
173 { return LIN_DOWN(existing
, needed
); }
181 /** \class ResizeConst
182 * \brief Constant table resizer.
184 * When an up resize is needed the existing size is always used. ResizeConst
185 * does not allow dynamic resizing. To use ResizeConst, the vector needs to be
186 * constructed with and initial allocation amount otherwise it will be
192 /* Constant table resizing. */
196 /* Assert don't need more than exists. Return existing. */
197 static inline long upResize( long existing
, long needed
);
200 * \brief Determine the new table size when down resizing.
202 * Always returns the existing table size.
204 static inline long downResize( long existing
, long needed
)
205 { return CONST_DOWN(existing
, needed
); }
209 * \brief Determine the new table size when up resizing.
211 * If the existing size is insufficient for the space needed, then an assertion
212 * will fail. Otherwise returns the existing size.
214 inline long ResizeConst::upResize( long existing
, long needed
)
216 assert( needed
<= existing
);
217 return CONST_UP(existing
, needed
);
225 /** \class ResizeRunTime
226 * \brief Run time settable table resizer.
228 * ResizeRunTime can have it's up and down resizing policies set at run time.
229 * Both up and down policies can be set independently to one of Exponential,
230 * Linear, or Constant. See the documentation for ResizeExpn, ResizeLin, and
231 * ResizeConst for the details of the resizing policies.
233 * The policies may be changed at any time. The default policies are
239 /* Run time resizing. */
244 * \brief Default constuctor.
246 * The up and down resizing it initialized to Exponetial. The step
247 * defaults to 256 units of T.
249 inline ResizeRunTime();
252 * \brief Resizing policies.
255 Exponential
, /*!< Exponential resizing. */
256 Linear
, /*!< Linear resizing. */
257 Constant
/*!< Constant table size. */
260 inline long upResize( long existing
, long needed
);
261 inline long downResize( long existing
, long needed
);
265 * \brief Step for linear resize.
267 * Amount of extra space in units of T added each time a resize must take
268 * place. This may be changed at any time. The step should be >= 0.
273 * \brief Up resizing policy.
275 ResizeType upResizeType
;
278 * \brief Down resizing policy.
280 ResizeType downResizeType
;
283 inline ResizeRunTime::ResizeRunTime()
285 step( LIN_DEFAULT_STEP
),
286 upResizeType( Exponential
),
287 downResizeType( Exponential
)
292 * \brief Determine the new table size when up resizing.
294 * Type of up resizing is determined by upResizeType. Exponential, Linear and
295 * Constant resizing is the same as that of ResizeExpn, ResizeLin and
298 inline long ResizeRunTime::upResize( long existing
, long needed
)
300 switch ( upResizeType
) {
302 return EXPN_UP(existing
, needed
);
304 return LIN_UP(existing
, needed
);
306 assert( needed
<= existing
);
307 return CONST_UP(existing
, needed
);
313 * \brief Determine the new table size when down resizing.
315 * Type of down resizing is determined by downResiizeType. Exponential, Linear
316 * and Constant resizing is the same as that of ResizeExpn, ResizeLin and
319 inline long ResizeRunTime::downResize( long existing
, long needed
)
321 switch ( downResizeType
) {
323 return EXPN_DOWN(existing
, needed
);
325 return LIN_DOWN(existing
, needed
);
327 return CONST_DOWN(existing
, needed
);
332 /* Don't need these anymore. */
340 #ifdef AAPL_NAMESPACE
344 #endif /* _AAPL_RESIZE_H */