1 /*******************************************************************************
2 
3     Elastic binary tree node pool
4 
5     Simple struct pool for node struct instances
6 
7     Copyright:
8         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
9         All rights reserved.
10 
11     License:
12         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
13         Alternatively, this file may be distributed under the terms of the Tango
14         3-Clause BSD License (see LICENSE_BSD.txt for details).
15 
16 *******************************************************************************/
17 
18 module ocean.util.container.ebtree.nodepool.NodePool;
19 
20 import ocean.meta.types.Qualifiers;
21 
22 /*******************************************************************************
23 
24     Node pool interface
25 
26 *******************************************************************************/
27 
28 interface INodePool ( Node )
29 {
30     Node* get ( );
31 
32     void recycle ( Node* );
33 }
34 
35 /*******************************************************************************
36 
37     Default node pool implementation
38 
39 *******************************************************************************/
40 
41 class NodePool ( Node ) : INodePool!(Node)
42 {
43     static assert (is (Node == struct));
44 
45     /***************************************************************************
46 
47         List of free nodes. When a node is removed it is added to this list, so
48         that it can be re-used when a new node is added.
49 
50     ***************************************************************************/
51 
52     private Node*[] free_nodes;
53 
54     /***************************************************************************
55 
56         Obtains a Node instance. If there are currently free nodes, one of these
57         is used, otherwise a new Node instance is created.
58 
59         Returns:
60             Node instance
61 
62     ***************************************************************************/
63 
64     public Node* get ( )
65     {
66         if ( this.free_nodes.length )
67         {
68             scope (success)
69             {
70                 this.free_nodes.length = this.free_nodes.length - 1;
71                 assumeSafeAppend(this.free_nodes);
72             }
73 
74             return this.free_nodes[$ - 1];
75         }
76         else
77         {
78             return this.newNode();
79         }
80     }
81 
82     /***************************************************************************
83 
84         Adds node to the list of free nodes.
85 
86         Params:
87             node = free node instance
88 
89     ***************************************************************************/
90 
91     public void recycle ( Node* node )
92     {
93         this.free_nodes.length = this.free_nodes.length + 1;
94         assumeSafeAppend(this.free_nodes);
95         this.free_nodes[$ - 1] = node;
96     }
97 
98     /***************************************************************************
99 
100         Creates a new node.
101         May be overridden by a subclass to use a different allocation method.
102 
103         Returns:
104             a newly created node.
105 
106         Out:
107             The returned node pointer is an integer multiple of 16 as required
108             by the libebtree.
109 
110     ***************************************************************************/
111 
112     protected Node* newNode ( )
113     out (node)
114     {
115         assert((cast(size_t)node) % 16 == 0,
116                "the node pointer must be an integer multiple of 16");
117     }
118     do
119     {
120         return new Node;
121     }
122 
123     /***************************************************************************
124 
125         Resets the maintained list of free nodes so that the pool becomes empty.
126 
127         All nodes in the pool will be lost. You should call this method if and
128         only if you otherwise delete the free nodes.
129 
130     ***************************************************************************/
131 
132     protected void resetFreeList ()
133     {
134         this.free_nodes.length = 0;
135         assumeSafeAppend(this.free_nodes);
136     }
137 }