Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

root/trunk/tango/util/container/Container.d

Revision 4008, 15.7 kB (checked in by larsivi, 1 month ago)

Fixed eol style for container package, refs #1303

  • Property svn:eol-style set to native
Line 
1 /*******************************************************************************
2
3         copyright:      Copyright (c) 2008 Kris Bell. All rights reserved
4
5         license:        BSD style: $(LICENSE)
6
7         version:        Apr 2008: Initial release
8
9         authors:        Kris
10
11         Since:          0.99.7
12
13 *******************************************************************************/
14
15 module tango.util.container.Container;
16
17 private import tango.core.Memory;
18
19 private import tango.stdc.stdlib;
20
21 /*******************************************************************************
22
23         Utility functions and constants
24
25 *******************************************************************************/
26
27 struct Container
28 {
29         /***********************************************************************
30         
31                default initial number of buckets of a non-empty hashmap
32
33         ***********************************************************************/
34        
35         static int defaultInitialBuckets = 31;
36
37         /***********************************************************************
38
39                 default load factor for a non-empty hashmap. The hash
40                 table is resized when the proportion of elements per
41                 buckets exceeds this limit
42         
43         ***********************************************************************/
44        
45         static float defaultLoadFactor = 0.75f;
46
47         /***********************************************************************
48         
49                 generic value reaper, which does nothing
50
51         ***********************************************************************/
52        
53         static void reap(V) (V v) {}
54
55         /***********************************************************************
56         
57                 generic key/value reaper, which does nothing
58
59         ***********************************************************************/
60        
61         static void reap(K, V) (K k, V v) {}
62
63         /***********************************************************************
64
65                 generic hash function, using the default hashing. Thanks
66                 to 'mwarning' for the optimization suggestion
67
68         ***********************************************************************/
69
70         static uint hash(K) (K k, uint length)
71         {
72                 static if (is(K : int) || is(K : uint) ||
73                            is(K : long) || is(K : ulong) ||
74                            is(K : short) || is(K : ushort) ||
75                            is(K : byte) || is(K : ubyte) ||
76                            is(K : char) || is(K : wchar) || is (K : dchar))
77                            return cast(uint) (k % length);
78                 else
79                    return (typeid(K).getHash(&k) & 0x7FFFFFFF) % length;
80         }
81
82         /***********************************************************************
83         
84                 generic GC allocation manager
85                 
86         ***********************************************************************/
87        
88         struct Collect(T)
89         {
90                 /***************************************************************
91         
92                         allocate a T sized memory chunk
93                         
94                 ***************************************************************/
95        
96                 T* allocate ()
97                 {       
98                         return cast(T*) GC.calloc (T.sizeof);
99                 }
100        
101                 /***************************************************************
102         
103                         allocate an array of T sized memory chunks
104                         
105                 ***************************************************************/
106        
107                 T*[] allocate (uint count)
108                 {
109                         return new T*[count];
110                 }
111        
112                 /***************************************************************
113         
114                         Invoked when a specific T[] is discarded
115                         
116                 ***************************************************************/
117        
118                 void collect (T* p)
119                 {
120                         if (p)
121                             delete p;
122                 }
123        
124                 /***************************************************************
125         
126                         Invoked when a specific T[] is discarded
127                         
128                 ***************************************************************/
129        
130                 void collect (T*[] t)
131                 {     
132                         if (t)
133                             delete t;
134                 }
135
136                 /***************************************************************
137         
138                         Invoked when clear/reset is called on the host.
139                         This is a shortcut to clear everything allocated.
140         
141                         Should return true if supported, or false otherwise.
142                         False return will cause a series of discrete collect
143                         calls
144
145                 ***************************************************************/
146        
147                 bool collect (bool all = true)
148                 {
149                         return false;
150                 }
151         }       
152        
153                
154         /***********************************************************************
155         
156                 Malloc allocation manager.
157
158                 Note that, due to GC behaviour, you should not configure
159                 a custom allocator for containers holding anything managed
160                 by the GC. For example, you cannot use a MallocAllocator
161                 to manage a container of classes or strings where those
162                 were allocated by the GC. Once something is owned by a GC
163                 then it's lifetime must be managed by GC-managed entities
164                 (otherwise the GC may think there are no live references
165                 and prematurely collect container contents).
166         
167                 You can explicity manage the collection of keys and values
168                 yourself by providing a reaper delegate. For example, if
169                 you use a MallocAllocator to manage key/value pairs which
170                 are themselves allocated via malloc, then you should also
171                 provide a reaper delegate to collect those as required.     
172                 
173         ***********************************************************************/
174        
175         struct Malloc(T)
176         {
177                 /***************************************************************
178         
179                         allocate an array of T sized memory chunks
180                         
181                 ***************************************************************/
182        
183                 T* allocate ()
184                 {
185                         return cast(T*) calloc (1, T.sizeof);
186                 }
187        
188                 /***************************************************************
189         
190                         allocate an array of T sized memory chunks
191                         
192                 ***************************************************************/
193        
194                 T*[] allocate (uint count)
195                 {
196                         return (cast(T**) calloc(count, (T*).sizeof)) [0 .. count];
197                 }
198        
199                 /***************************************************************
200         
201                         Invoked when a specific T[] is discarded
202                         
203                 ***************************************************************/
204        
205                 void collect (T*[] t)
206                 {     
207                         if (t.length)
208                             free (t.ptr);
209                 }
210
211                 /***************************************************************
212         
213                         Invoked when a specific T[] is discarded
214                         
215                 ***************************************************************/
216        
217                 void collect (T* p)
218                 {       
219                         if (p)
220                             free (p);
221                 }
222        
223                 /***************************************************************
224         
225                         Invoked when clear/reset is called on the host.
226                         This is a shortcut to clear everything allocated.
227         
228                         Should return true if supported, or false otherwise.
229                         False return will cause a series of discrete collect
230                         calls
231                         
232                 ***************************************************************/
233        
234                 bool collect (bool all = true)
235                 {
236                         return false;
237                 }
238         }       
239        
240        
241         /***********************************************************************
242         
243                 Chunk allocator
244
245                 Can save approximately 30% memory for small elements (tested
246                 with integer elements and a chunk size of 1000), and is at
247                 least twice as fast at adding elements when compared to the
248                 default allocator (approximately 50x faster with LinkedList)
249         
250                 Note that, due to GC behaviour, you should not configure
251                 a custom allocator for containers holding anything managed
252                 by the GC. For example, you cannot use a MallocAllocator
253                 to manage a container of classes or strings where those
254                 were allocated by the GC. Once something is owned by a GC
255                 then it's lifetime must be managed by GC-managed entities
256                 (otherwise the GC may think there are no live references
257                 and prematurely collect container contents).
258         
259                 You can explicity manage the collection of keys and values
260                 yourself by providing a reaper delegate. For example, if
261                 you use a MallocAllocator to manage key/value pairs which
262                 are themselves allocated via malloc, then you should also
263                 provide a reaper delegate to collect those as required.
264         
265         ***********************************************************************/
266        
267         struct Chunk(T)
268         {
269                 private T[]     list;
270                 private T[][]   lists;
271                 private int     index;
272                 private int     freelists;
273                 private int     presize = 0;
274                 private int     chunks = 1000;
275
276                 private struct Discarded
277                 {
278                         Discarded* next;
279                 }
280                 private Discarded* discarded;
281                
282                 /***************************************************************
283         
284                         set the chunk size and preallocate lists
285                         
286                 ***************************************************************/
287        
288                 void config (int chunks, int presize)
289                 {
290                         this.chunks = chunks;
291                         this.presize = presize;
292                         lists.length = presize;
293
294                         foreach (ref list; lists)
295                                  list = block;
296                 }
297        
298                 /***************************************************************
299         
300                         allocate an array of T sized memory chunks
301                         
302                 ***************************************************************/
303
304                 T* allocate ()
305                 {
306                         if (index >= list.length)
307                             if (discarded)
308                                {   
309                                auto p = discarded;
310                                discarded = p.next;
311                                return cast(T*) p;
312                                }
313                             else
314                                newlist;
315        
316                         return (&list[index++]);
317                 }
318        
319                 /***************************************************************
320         
321                         allocate an array of T sized memory chunks
322                         
323                 ***************************************************************/
324        
325                 T*[] allocate (uint count)
326                 {
327                         return (cast(T**) calloc(count, (T*).sizeof)) [0 .. count];
328                 }
329        
330                 /***************************************************************
331         
332                         Invoked when a specific T[] is discarded
333                         
334                 ***************************************************************/
335        
336                 void collect (T*[] t)
337                 {     
338                         if (t.length)
339                             free (t.ptr);
340                 }
341
342                 /***************************************************************
343         
344                         Invoked when a specific T is discarded
345                         
346                 ***************************************************************/
347        
348                 void collect (T* p)
349                 {     
350                         if (p)
351                            {
352                            assert (T.sizeof >= (T*).sizeof);
353                            auto d = cast(Discarded*) p;
354                            d.next = discarded;
355                            discarded = d;
356                            }
357                 }
358        
359                 /***************************************************************
360         
361                         Invoked when clear/reset is called on the host.
362                         This is a shortcut to clear everything allocated.
363         
364                         Should return true if supported, or false otherwise.
365                         False return will cause a series of discrete collect
366                         calls
367                         
368                 ***************************************************************/
369        
370                 bool collect (bool all = true)
371                 {
372                         freelists = 0;
373                         newlist;
374                         if (all)
375                            {
376                            foreach (list; lists)
377                                     free (list.ptr);
378                            lists.length = 0;
379                            }
380                         return true;
381                 }
382              
383                 /***************************************************************
384         
385                         list manager
386                         
387                 ***************************************************************/
388        
389                 private void newlist ()
390                 {
391                         index = 0;
392                         if (freelists >= lists.length)
393                            {
394                            lists.length = lists.length + 1;
395                            lists[$-1] = block;
396                            }
397                         list = lists[freelists++];
398                 }
399        
400                 /***************************************************************
401         
402                         list allocator
403                         
404                 ***************************************************************/
405        
406                 private T[] block ()
407                 {
408                         return (cast(T*) calloc (chunks, T.sizeof)) [0 .. chunks];
409                 }
410         }       
411 }
Note: See TracBrowser for help on using the browser.