/* * Copyright (C) 2011-2014 Chris Vest (mr.chrisvest@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package stormpot; /** * Reallocators are a special kind of {@link Allocator} that can reallocate * {@link Poolable}s that have expired. This is useful since the {@link Pool} * will typically keep the Poolables around for a relatively long time, with * respect to garbage collection. Because of this, there is a high chance that * the Poolables tenure to the old generation during their life time. This * way, pools often cause a slow, but steady accretion of old generation * garbage, ultimately helping to increase the frequency of expensive full * collections. * * The accretion of old generation garbage is inevitable, but the rate can be * slowed by reusing as much as possible of the Poolable instances, when they * are to be reallocated. This interface is only here to enable this * optimisation, and implementing it is completely optional. * * @author Chris Vest <mr.chrisvest@gmail.com> * * @param <T> any type that implements Poolable. * @since 2.2 */ public interface Reallocator<T extends Poolable> extends Allocator<T> { /** * Possibly reallocate the given instance of T for the given slot, and * return it if the reallocation was successful, or a fresh replacement if * the instance could not be reallocated. * * This method is effectively equivalent to the following: * * [source,java] * -- * deallocate(poolable); * return allocate(slot); * -- * * With the only difference that it may, if possible, reuse the given * expired Poolable, either wholly or in part. * * The state stored in the {@link stormpot.SlotInfo} for the object is reset * upon reallocation, just like it would be in the case of a normal * deallocation-allocation cycle. * * Exceptions thrown by this method may propagate out through the * {@link Pool#claim(Timeout) claim} method of a pool, in the form of being * wrapped inside a {@link PoolException}. Pools must be able to handle these * exceptions in a sane manner, and are guaranteed to return to a working * state if a Reallocator stops throwing exceptions from its reallocate * method. * * Be aware that if the reallocation of an object fails with an exception, * then no attempts will be made to explicitly deallocate that object. This * way, a failed reallocation is implicitly understood to effectively be a * successful deallocation. * @param slot The slot the pool wish to allocate an object for. * Implementers do not need to concern themselves with the details of a * pools slot objects. They just have to call release on them as the * protocol demands. * @param poolable The non-null Poolable instance to be reallocated. * @return A fresh or rejuvenated instance of T. Never `null`. * @throws Exception If the allocation fails. * @see #allocate(Slot) * @see #deallocate(Poolable) */ T reallocate(Slot slot, T poolable) throws Exception; }