1 /*******************************************************************************
2 
3     Basic preallocated pool of a fixed number of value type items, all items are
4     stored in one dynamic array.
5     Uses malloc() instead of D memory managed allocation for two reasons:
6       1. The exact size is specified at instantiation so allocating extra space
7          as the D memory manager does is not desired.
8       2. The elements do not contain references to D memory managed objects so
9          they can be invisible to the GC.
10 
11     Copyright:
12         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
13         All rights reserved.
14 
15     License:
16         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
17         Alternatively, this file may be distributed under the terms of the Tango
18         3-Clause BSD License (see LICENSE_BSD.txt for details).
19 
20 *******************************************************************************/
21 
22 module ocean.util.container.cache.model.containers.ArrayPool;
23 
24 
25 import core.stdc.stdlib: malloc, free;
26 
27 import ocean.core.ExceptionDefinitions: onOutOfMemoryError;
28 
29 /******************************************************************************/
30 
31 class ArrayPool ( T ) : GenericArrayPool
32 {
33     /***************************************************************************
34 
35         Constructor.
36 
37         Params:
38             n = maximum number of elements that can be obtained
39 
40     ***************************************************************************/
41 
42     public this ( size_t n )
43     {
44         super(n, T.sizeof);
45     }
46 
47     /***************************************************************************
48 
49         Obtains the next element in the pool.
50 
51         It is an error to obtain more elements than the value n passed to the
52         constructor. In this case an array out of bounds error is raised.
53 
54         Returns:
55             the next pool element.
56 
57     ****************************************************************************/
58 
59     public override T* next ( )
60     {
61         return cast(T*)super.next;
62     }
63 }
64 
65 /******************************************************************************/
66 
67 class GenericArrayPool
68 {
69     import ocean.core.Verify;
70 
71     /***************************************************************************
72 
73         Byte length of each element.
74 
75     ***************************************************************************/
76 
77     public size_t element_size;
78 
79     /***************************************************************************
80 
81         Element data.
82 
83     ***************************************************************************/
84 
85     private void[] elements;
86 
87     /***********************************************************************
88 
89         Number of elements obtained since instantiation or the last clear()
90         call.
91 
92     ***********************************************************************/
93 
94     private size_t n_created = 0;
95 
96     /***********************************************************************
97 
98         Constructor.
99 
100         Params:
101             n = maximum number of elements in mapping
102             element_size = size of a single element
103 
104     ***********************************************************************/
105 
106     public this ( size_t n, size_t element_size )
107     {
108         verify(element_size > 0, "zero element size specified");
109 
110         n *= (this.element_size = element_size);
111 
112         auto elements_buf = malloc(n);
113 
114         if (elements_buf)
115         {
116             this.elements = elements_buf[0 .. n];
117         }
118         else
119         {
120             onOutOfMemoryError();
121         }
122     }
123 
124     /***************************************************************************
125 
126         Destructor.
127 
128     ***************************************************************************/
129 
130     ~this ( )
131     {
132         if (this.elements.ptr)
133         {
134             free(this.elements.ptr);
135         }
136     }
137 
138     /***************************************************************************
139 
140         Obtains the next element in the pool.
141 
142         It is an error to obtain more elements than the value n passed to the
143         constructor. In this case an array out of bounds error is raised.
144 
145         Returns:
146             a pointer to the next pool element.
147 
148     ****************************************************************************/
149 
150     public void* next ( )
151     {
152         return &this.elements[this.n_created++ * this.element_size];
153     }
154 
155     /***************************************************************************
156 
157         Marks all elements in the pool as free.
158 
159     ****************************************************************************/
160 
161     public void clear ( )
162     {
163         this.n_created = 0;
164     }
165 }