All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.esotericsoftware.kryo.util.Pool Maven / Gradle / Ivy

Go to download

Easy Redis Java client and Real-Time Data Platform. Valkey compatible. Sync/Async/RxJava3/Reactive API. Client side caching. Over 50 Redis based Java objects and services: JCache API, Apache Tomcat, Hibernate, Spring, Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Scheduler, RPC

There is a newer version: 3.40.2
Show newest version
/* Copyright (c) 2008-2023, Nathan Sweet
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
 * conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided with the distribution.
 * - Neither the name of Esoteric Software nor the names of its contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */

package com.esotericsoftware.kryo.util;

import java.lang.ref.SoftReference;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

/** A pool of objects that can be reused to avoid allocations. The pool is optionally thread safe and can be configured to use
 * soft references.
 * @author Nathan Sweet
 * @author Martin Grotzke */
public abstract class Pool {
	private final Queue freeObjects;
	private int peak;

	/** Creates a pool with no maximum. */
	public Pool (boolean threadSafe, boolean softReferences) {
		this(threadSafe, softReferences, Integer.MAX_VALUE);
	}

	/** @param maximumCapacity The maximum number of free objects to store in this pool. Objects are not created until
	 *           {@link #obtain()} is called and no free objects are available. */
	public Pool (boolean threadSafe, boolean softReferences, final int maximumCapacity) {
		Queue queue;
		if (threadSafe)
			queue = new LinkedBlockingQueue(maximumCapacity) {
				@Override
				public boolean add (T o) {
					return super.offer(o);
				}
			};
		else if (softReferences) {
			queue = new LinkedList() { // More efficient clean() than ArrayDeque.
				public boolean add (T object) {
					if (size() >= maximumCapacity) return false;
					super.add(object);
					return true;
				}
			};
		} else {
			queue = new ArrayDeque() {
				public boolean offer (T object) {
					if (size() >= maximumCapacity) return false;
					super.offer(object);
					return true;
				}
			};
		}
		freeObjects = softReferences ? new SoftReferenceQueue<>(((Queue>)queue)) : queue;
	}

	protected abstract T create ();

	/** Returns an object from this pool. The object may be new (from {@link #create()}) or reused (previously {@link #free(Object)
	 * freed}). */
	public T obtain () {
		T object = freeObjects.poll();
		return object != null ? object : create();
	}

	/** Puts the specified object in the pool, making it eligible to be returned by {@link #obtain()}. If the pool already contains
	 * the maximum number of free objects, the specified object is reset but not added to the pool.
	 * 

* If using soft references and the pool contains the maximum number of free objects, the first soft reference whose object has * been garbage collected is discarded to make room. */ public void free (T object) { if (object == null) throw new IllegalArgumentException("object cannot be null."); reset(object); if (!freeObjects.offer(object) && freeObjects instanceof SoftReferenceQueue) { ((SoftReferenceQueue)freeObjects).cleanOne(); freeObjects.offer(object); } peak = Math.max(peak, freeObjects.size()); } /** Called when an object is freed to clear the state of the object for possible later reuse. The default implementation calls * {@link Poolable#reset()} if the object is {@link Poolable}. */ protected void reset (T object) { if (object instanceof Poolable) ((Poolable)object).reset(); } /** Removes all free objects from this pool. */ public void clear () { freeObjects.clear(); } /** If using soft references, all soft references whose objects have been garbage collected are removed from the pool. This can * be useful to reduce the number of objects in the pool before calling {@link #getFree()} or when the pool has no maximum * capacity. It is not necessary to call {@link #clean()} before calling {@link #free(Object)}, which will try to remove an * empty reference if the maximum capacity has been reached. */ public void clean () { if (freeObjects instanceof SoftReferenceQueue) ((SoftReferenceQueue)freeObjects).clean(); } /** The number of objects available to be obtained. *

* If using soft references, this number may include objects that have been garbage collected. {@link #clean()} may be used * first to remove empty soft references. */ public int getFree () { return freeObjects.size(); } /** The all-time highest number of free objects. This can help determine if a pool's maximum capacity is set appropriately. It * can be reset any time with {@link #resetPeak()}. *

* If using soft references, this number may include objects that have been garbage collected. */ public int getPeak () { return peak; } public void resetPeak () { peak = 0; } /** Objects implementing this interface will have {@link #reset()} called when passed to {@link Pool#free(Object)}. */ public static interface Poolable { /** Resets the object for reuse. Object references should be nulled and fields may be set to default values. */ public void reset (); } /** Wraps queue values with {@link SoftReference} for {@link Pool}. * @author Martin Grotzke */ static class SoftReferenceQueue implements Queue { private final Queue> delegate; public SoftReferenceQueue (Queue> delegate) { this.delegate = delegate; } public T poll () { while (true) { SoftReference reference = delegate.poll(); if (reference == null) return null; T object = reference.get(); if (object != null) return object; } } public boolean offer (T e) { return delegate.add(new SoftReference<>(e)); } public int size () { return delegate.size(); } public void clear () { delegate.clear(); } void cleanOne () { for (Iterator> iter = delegate.iterator(); iter.hasNext();) { if (iter.next().get() == null) { iter.remove(); break; } } } void clean () { delegate.removeIf(o -> o.get() == null); } public boolean add (T e) { return false; } public boolean isEmpty () { return false; } public boolean contains (Object o) { return false; } public Iterator iterator () { return null; } public T remove () { return null; } public Object[] toArray () { return null; } public T element () { return null; } public T peek () { return null; } public E[] toArray (E[] a) { return null; } public boolean remove (Object o) { return false; } public boolean containsAll (Collection c) { return false; } public boolean addAll (Collection c) { return false; } public boolean removeAll (Collection c) { return false; } public boolean retainAll (Collection c) { return false; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy