//
//  ========================================================================
//  Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.util.compression;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicInteger;

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

public abstract class CompressionPool<T> extends AbstractLifeCycle
{
    public static final int INFINITE_CAPACITY = -1;

    private final Queue<T> _pool;
    private final AtomicInteger _numObjects = new AtomicInteger(0);
    private final int _capacity;

    
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; _pool = (_capacity == 0) ? null : new ConcurrentLinkedQueue<>(); } protected abstract T newObject(); 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 T acquire() { T object; if (_capacity == 0) object = newObject(); else { object = _pool.poll(); if (object == null) object = newObject(); else if (_capacity > 0) _numObjects.decrementAndGet(); } return object; }
Params:
  • object – returns this Object to the pool or calls end(Object) if the pool is full.
/** * @param object returns this Object to the pool or calls {@link #end(Object)} if the pool is full. */
public void release(T object) { if (object == null) return; if (_capacity == 0 || !isRunning()) { end(object); return; } else if (_capacity < 0) { reset(object); _pool.add(object); } else { while (true) { int d = _numObjects.get(); if (d >= _capacity) { end(object); break; } if (_numObjects.compareAndSet(d, d + 1)) { reset(object); _pool.add(object); break; } } } } @Override public void doStop() { T t = _pool.poll(); while (t != null) { end(t); t = _pool.poll(); } _numObjects.set(0); } }