1 /******************************************************************************* 2 3 Pool class template which stores class instances, has the 4 following features: 5 * Get and recycle items. Recycled items will be re-used before creating 6 new items. 7 * The total number of items, as well as the number of idle or busy items 8 in the pool can be queried. 9 * A limit can be applied to the pool, which prevents more than the 10 specified number of items from being created. 11 * A specified number of items can be pre-allocated in the pool using the 12 fill() method. 13 * The entire pool can be emptied, returning all items to the idle state, 14 with clear(). 15 * Iteration over all items in the pool, or all busy or idle items. (See 16 further notes in the super class.) 17 * For classes with a default (parameterless) constructor, get() and 18 fill() methods exist which automatically create new pool items, 19 without requiring them to be passed via a lazy argument. 20 21 An additional class template exists, the AutoCtorPool, which automatically 22 creates new instances of the specified class by calling the constructor 23 with a fixed set of parameters. 24 25 Also see: ocean.util.container.pool.model.IAggregatePool, for more detailed 26 documentation and usage examples. 27 28 Copyright: 29 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 30 All rights reserved. 31 32 License: 33 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 34 Alternatively, this file may be distributed under the terms of the Tango 35 3-Clause BSD License (see LICENSE_BSD.txt for details). 36 37 *******************************************************************************/ 38 39 module ocean.util.container.pool.ObjectPool; 40 41 42 43 44 import ocean.util.container.pool.model.IAggregatePool; 45 import ocean.util.container.pool.model.IResettable; 46 47 import ocean.transition; 48 49 /******************************************************************************* 50 51 Manages a pool of class instances of type T. 52 53 Does not create the items ("new T") internally but receives them as lazy 54 arguments in get(). 55 56 Params: 57 T = type stored in pool 58 59 *******************************************************************************/ 60 61 public class ObjectPool ( T ) : IAggregatePool!(T) 62 { 63 /*************************************************************************** 64 65 Asserts that T is a class. 66 67 ***************************************************************************/ 68 69 static assert(is(T == class)); 70 71 /*************************************************************************** 72 73 Resets item. 74 75 Params: 76 item = item to reset 77 78 ***************************************************************************/ 79 80 protected override void resetItem ( Item item ) 81 { 82 static if (is(T : Resettable)) 83 { 84 this.fromItem(item).reset(); 85 } 86 } 87 } 88 89 90 91 /******************************************************************************* 92 93 Extends ObjectPool by creating items (instances of T) automatically with 94 "new T(Args)". 95 96 Params: 97 T = type stored in pool 98 Args = tuple of T constructor argument types. 99 100 *******************************************************************************/ 101 102 public class AutoCtorPool ( T, Args ... ) : ObjectPool!(T) 103 { 104 /*************************************************************************** 105 106 Asserts that at least one constructor argument is specified in the Args 107 tuple. 108 109 ***************************************************************************/ 110 111 static assert(Args.length > 0, "if you want to use a constructor with no arguments, just use ObjectPool"); 112 113 /*************************************************************************** 114 115 Arguments used to construct pool items. These items are set in the 116 class' constructor and are then used to construct all requested pool 117 items. 118 119 ***************************************************************************/ 120 121 private Args args; 122 123 /*************************************************************************** 124 125 Constructor 126 127 Params: 128 args = T constructor arguments to be used each time an 129 object is created 130 131 ***************************************************************************/ 132 133 public this ( Args args ) 134 { 135 this.args = args; 136 } 137 138 /************************************************************************** 139 140 Gets an object from the object pool. 141 142 Returns: 143 object from the object pool 144 145 **************************************************************************/ 146 147 public ItemType get ( ) 148 { 149 return super.get(new T(args)); 150 } 151 152 /************************************************************************** 153 154 Ensures that the pool contains at least the specified number of items. 155 Useful to pre-allocate a pool of a certain size. 156 157 Params: 158 num = minimum number of items desired in pool 159 160 Returns: 161 this 162 163 Throws: 164 LimitExceededException if the requested number of items exceeds 165 the previously specified limit. 166 167 **************************************************************************/ 168 169 public typeof(this) fill ( size_t num ) 170 { 171 super.fill_(num, this.toItem(new T(args))); 172 return this; 173 } 174 175 /************************************************************************** 176 177 Creates a new instance. 178 179 Params: 180 args = T constructor arguments to be used each time an object is 181 created 182 183 **************************************************************************/ 184 185 static typeof (this) newPool ( Args args ) 186 { 187 return new typeof (this)(args); 188 } 189 } 190 191 192 193 version ( UnitTest ) 194 { 195 class Class 196 { 197 size_t object_pool_index; 198 199 mixin(genOpEquals(` 200 { 201 auto crhs = cast(typeof(this)) rhs; 202 return this.i == crhs.i && this.s == crhs.s; 203 }`)); 204 205 size_t i; 206 char[] s; 207 } 208 209 import ocean.core.Test; 210 211 alias ObjectPool!(Class) MyPool; 212 class ObjectPoolTester : IAggregatePoolTester!(Class) 213 { 214 215 public this ( ) 216 { 217 super(new MyPool); 218 } 219 220 protected override Item newItem ( ) 221 { 222 return new Class; 223 } 224 225 protected override void setItem ( ref Item item, size_t i ) 226 { 227 item.i = i; 228 item.s.length = 1; 229 item.s[0] = cast(char)(i + 32); 230 } 231 232 protected override void checkItem ( ref Item item, size_t i ) 233 { 234 .test!("==")(item.i, i, "item integer wrong"); 235 .test!("==")(item.s.length, 1, "item string length wrong"); 236 .test!("==")(item.s[0], cast(char)(i + 32), "item string content wrong"); 237 } 238 } 239 } 240 241 unittest 242 { 243 scope op = new ObjectPoolTester; 244 op.test(); 245 } 246