//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.util.compression;

import java.io.Closeable;

import org.eclipse.jetty.util.Pool;
import org.eclipse.jetty.util.component.AbstractLifeCycle;

public abstract class CompressionPool<T> extends AbstractLifeCycle
{
    public static final int DEFAULT_CAPACITY = 1024;

    private int _capacity;
    private Pool<Entry> _pool;

    
Create a Pool of T instances. If given a capacity equal to zero the Objects will not be pooled and will be created on acquire and ended on release. If given a negative capacity equal to zero there will be no size restrictions on the Pool
Params:
  • capacity – maximum number of Objects which can be contained in the pool
/** * Create a Pool of {@link T} instances. * * If given a capacity equal to zero the Objects will not be pooled * and will be created on acquire and ended on release. * If given a negative capacity equal to zero there will be no size restrictions on the Pool * * @param capacity maximum number of Objects which can be contained in the pool */
public CompressionPool(int capacity) { _capacity = capacity; } public int getCapacity() { return _capacity; } public void setCapacity(int capacity) { if (isStarted()) throw new IllegalStateException("Already Started"); _capacity = capacity; } protected abstract T newPooled(); protected abstract void end(T object); protected abstract void reset(T object);
Returns:Object taken from the pool if it is not empty or a newly created Object
/** * @return Object taken from the pool if it is not empty or a newly created Object */
public Entry acquire() { Entry entry = null; if (_pool != null) { Pool<Entry>.Entry acquiredEntry = _pool.acquire(e -> new Entry(newPooled(), e)); if (acquiredEntry != null) entry = acquiredEntry.getPooled(); } return (entry == null) ? new Entry(newPooled()) : entry; }
Params:
  • entry – returns this Object to the pool or calls end(Object) if the pool is full.
/** * @param entry returns this Object to the pool or calls {@link #end(Object)} if the pool is full. */
public void release(Entry entry) { entry.release(); } @Override protected void doStart() throws Exception { if (_capacity > 0) _pool = new Pool<>(Pool.StrategyType.RANDOM, _capacity, true); super.doStart(); } @Override public void doStop() throws Exception { if (_pool != null) { _pool.close(); _pool = null; } super.doStop(); } public class Entry implements Closeable { private final T _value; private final Pool<Entry>.Entry _entry; Entry(T value) { this(value, null); } Entry(T value, Pool<Entry>.Entry entry) { _value = value; _entry = entry; } public T get() { return _value; } public void release() { // Reset the value for the next usage. reset(_value); if (_entry != null) { // If release return false, the entry should be removed and the object should be disposed. if (!_pool.release(_entry)) { if (_pool.remove(_entry)) close(); } } else { close(); } } @Override public void close() { end(_value); } } @Override public String toString() { return String.format("%s@%x{%s,size=%d,capacity=%s}", getClass().getSimpleName(), hashCode(), getState(), (_pool == null) ? -1 : _pool.size(), _capacity); } }