1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 module hunt.pool.KeyedObjectPool;
18 
19 import hunt.util.Common;
20 import hunt.Exceptions;
21 
22 /**
23  * A "keyed" pooling interface.
24  * <p>
25  * A keyed pool maintains a pool of instances for each key value.
26  * </p>
27  * <p>
28  * Example of use:
29  * </p>
30  * <pre style="border:solid thin; padding: 1ex;"
31  * > Object obj = <code style="color:#00C">null</code>;
32  * Object key = <code style="color:#C00">"Key"</code>;
33  *
34  * <code style="color:#00C">try</code> {
35  *     obj = pool.borrowObject(key);
36  *     <code style="color:#0C0">//...use the object...</code>
37  * } <code style="color:#00C">catch</code>(Exception e) {
38  *     <code style="color:#0C0">// invalidate the object</code>
39  *     pool.invalidateObject(key, obj);
40  *     <code style="color:#0C0">// do not return the object to the pool twice</code>
41  *     obj = <code style="color:#00C">null</code>;
42  * } <code style="color:#00C">finally</code> {
43  *     <code style="color:#0C0">// make sure the object is returned to the pool</code>
44  *     <code style="color:#00C">if</code>(<code style="color:#00C">null</code> != obj) {
45  *         pool.returnObject(key, obj);
46  *     }
47  * }</pre>
48  * <p>
49  * {@link KeyedObjectPool} implementations <i>may</i> choose to store at most
50  * one instance per key value, or may choose to maintain a pool of instances
51  * for each key (essentially creating a {@link java.util.Map Map} of
52  * {@link ObjectPool pools}).
53  * </p>
54  * <p>
55  * See {@link hunt.pool.impl.GenericKeyedObjectPool
56  * GenericKeyedObjectPool} for an implementation.
57  * </p>
58  *
59  * @param <K> The type of keys maintained by this pool.
60  * @param <V> Type of element pooled in this pool.
61  *
62  * @see KeyedPooledObjectFactory
63  * @see ObjectPool
64  * @see hunt.pool.impl.GenericKeyedObjectPool GenericKeyedObjectPool
65  *
66  */
67 interface KeyedObjectPool(K, V) : Closeable {
68     /**
69      * Obtains an instance from this pool for the specified <code>key</code>.
70      * <p>
71      * Instances returned from this method will have been either newly created
72      * with {@link KeyedPooledObjectFactory#makeObject makeObject} or will be
73      * a previously idle object and have been activated with
74      * {@link KeyedPooledObjectFactory#activateObject activateObject} and then
75      * (optionally) validated with
76      * {@link KeyedPooledObjectFactory#validateObject validateObject}.
77      * </p>
78      * <p>
79      * By contract, clients <strong>must</strong> return the borrowed object
80      * using {@link #returnObject returnObject},
81      * {@link #invalidateObject invalidateObject}, or a related method as
82      * defined in an implementation or sub-interface, using a <code>key</code>
83      * that is {@link Object#equals equivalent} to the one used to borrow the
84      * instance in the first place.
85      * </p>
86      * <p>
87      * The behaviour of this method when the pool has been exhausted is not
88      * strictly specified (although it may be specified by implementations).
89      * </p>
90      *
91      * @param key the key used to obtain the object
92      *
93      * @return an instance from this pool.
94      *
95      * @throws IllegalStateException
96      *              after {@link #close close} has been called on this pool
97      * @throws Exception
98      *              when {@link KeyedPooledObjectFactory#makeObject
99      *              makeObject}exception
100      * @throws NoSuchElementException
101      *              when the pool is exhausted and cannot or will not return
102      *              another instance
103      */
104     V borrowObject(K key);
105 
106     /**
107      * Return an instance to the pool. By contract, <code>obj</code>
108      * <strong>must</strong> have been obtained using
109      * {@link #borrowObject borrowObject} or a related method as defined in an
110      * implementation or sub-interface using a <code>key</code> that is
111      * equivalent to the one used to borrow the instance in the first place.
112      *
113      * @param key the key used to obtain the object
114      * @param obj a {@link #borrowObject borrowed} instance to be returned.
115      *
116      * @throws IllegalStateException
117      *              if an attempt is made to return an object to the pool that
118      *              is in any state other than allocated (i.e. borrowed).
119      *              Attempting to return an object more than once or attempting
120      *              to return an object that was never borrowed from the pool
121      *              will trigger this exception.
122      *
123      * @throws Exception if an instance cannot be returned to the pool
124      */
125     void returnObject(K key, V obj);
126 
127     /**
128      * Invalidates an object from the pool.
129      * <p>
130      * By contract, <code>obj</code> <strong>must</strong> have been obtained
131      * using {@link #borrowObject borrowObject} or a related method as defined
132      * in an implementation or sub-interface using a <code>key</code> that is
133      * equivalent to the one used to borrow the <code>Object</code> in the first
134      * place.
135      * </p>
136      * <p>
137      * This method should be used when an object that has been borrowed is
138      * determined (due to an exception or other problem) to be invalid.
139      * </p>
140      *
141      * @param key the key used to obtain the object
142      * @param obj a {@link #borrowObject borrowed} instance to be returned.
143      *
144      * @throws Exception if the instance cannot be invalidated
145      */
146     void invalidateObject(K key, V obj);
147 
148     /**
149      * Create an object using the {@link KeyedPooledObjectFactory factory} or
150      * other implementation dependent mechanism, passivate it, and then place it
151      * in the idle object pool. <code>addObject</code> is useful for
152      * "pre-loading" a pool with idle objects (Optional operation).
153      *
154      * @param key the key a new instance should be added to
155      *
156      * @throws Exception
157      *              when {@link KeyedPooledObjectFactory#makeObject} fails.
158      * @throws IllegalStateException
159      *              after {@link #close} has been called on this pool.
160      * @throws UnsupportedOperationException
161      *              when this pool cannot add new idle objects.
162      */
163     void addObject(K key);
164 
165     /**
166      * Returns the number of instances corresponding to the given
167      * <code>key</code> currently idle in this pool. Returns a negative value if
168      * this information is not available.
169      *
170      * @param key the key to query
171      * @return the number of instances corresponding to the given
172      * <code>key</code> currently idle in this pool.
173      */
174     int getNumIdle(K key);
175 
176     /**
177      * Returns the number of instances currently borrowed from but not yet
178      * returned to the pool corresponding to the given <code>key</code>.
179      * Returns a negative value if this information is not available.
180      *
181      * @param key the key to query
182      * @return the number of instances currently borrowed from but not yet
183      * returned to the pool corresponding to the given <code>key</code>.
184      */
185     int getNumActive(K key);
186 
187     /**
188      * Returns the total number of instances currently idle in this pool.
189      * Returns a negative value if this information is not available.
190      * @return the total number of instances currently idle in this pool.
191      */
192     int getNumIdle();
193 
194     /**
195      * Returns the total number of instances currently borrowed from this pool but
196      * not yet returned. Returns a negative value if this information is not
197      * available.
198      * @return the total number of instances currently borrowed from this pool but
199      * not yet returned.
200      */
201     int getNumActive();
202 
203     /**
204      * Clears the pool, removing all pooled instances (optional operation).
205      *
206      * @throws UnsupportedOperationException when this implementation doesn't
207      *                                       support the operation
208      *
209      * @throws Exception if the pool cannot be cleared
210      */
211     void clear();
212 
213     /**
214      * Clears the specified pool, removing all pooled instances corresponding to
215      * the given <code>key</code> (optional operation).
216      *
217      * @param key the key to clear
218      *
219      * @throws UnsupportedOperationException when this implementation doesn't
220      *                                       support the operation
221      *
222      * @throws Exception if the key cannot be cleared
223      */
224     void clear(K key);
225 
226     /**
227      * Close this pool, and free any resources associated with it.
228      * <p>
229      * Calling {@link #addObject addObject} or
230      * {@link #borrowObject borrowObject} after invoking this method on a pool
231      * will cause them to throw an {@link IllegalStateException}.
232      * </p>
233      * <p>
234      * Implementations should silently fail if not all resources can be freed.
235      * </p>
236      */
237     override
238     void close();
239 }