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

io.legaldocml.pool.UnsafePool Maven / Gradle / Ivy

The newest version!
package io.legaldocml.pool;


import io.legaldocml.unsafe.UnsafeHelper;

import java.io.Closeable;

/**
 * @author Jacques Militello
 */
final class UnsafePool implements Pool>, Closeable{

    private final long adr;

    private static final sun.misc.Unsafe UNSAFE = UnsafeHelper.getUnsafe();

    private final UnsafeHolder[] holders;

    private final int size;

    private final PoolableObject poolableObject;

    private int index;

    private boolean isClosed;

    @SuppressWarnings("unchecked")
    UnsafePool(int size, PoolableObject poolableObject) {
        this.poolableObject = poolableObject;
        this.adr = UNSAFE.allocateMemory((long)size * 8);
        this.holders = new UnsafeHolder[size];
        for (int i = 0; i < size; i++) {
            holders[i] = new UnsafeHolder(poolableObject.newInstance());
        }
        this.size = size;
        this.isClosed = false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public UnsafeHolder checkOut() {

        int size = this.size;
        int index = this.index;
        UnsafeHolder[] holders = this.holders;
        for (int i = index; i < size; i++) {
            if (UNSAFE.compareAndSwapInt(holders[i], UnsafeHolder.FIELD_OFFSET, UnsafeHolder.FREE, UnsafeHolder.USED)) {
                // it's free => return;
                this.index = i;
                return holders[i];
            }
        }
        for (int i = 0; i < index; i++) {
            if (UNSAFE.compareAndSwapInt(holders[i], UnsafeHolder.FIELD_OFFSET, UnsafeHolder.FREE, UnsafeHolder.USED)) {
                this.index = i;
                // it's free => return;
                return holders[i];
            }
        }
        // all are used => retry
        return checkOut(0, size, holders);
    }

    @SuppressWarnings("unchecked")
    private UnsafeHolder checkOut(int count, int size, UnsafeHolder[] holders) {

        if (count == 100) {
            return new UnsafeHolder<>(poolableObject.newInstance(), UnsafeHolder.SINGLE);
        }

        Thread.yield();

        for (int i = 0; i < size; i++) {
            if (UNSAFE.compareAndSwapInt(holders[i], UnsafeHolder.FIELD_OFFSET, UnsafeHolder.FREE, UnsafeHolder.USED)) {
                return holders[i];
            }
        }

        return checkOut(count + 1, size, holders);

    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void checkIn(PoolHolder holder) {


        // single instance => not a member of the pool ==> skip
        if (UnsafeHolder.SINGLE == holder.getState()) {
            return;
        }

        holder.setState(UnsafeHolder.FREE);

        this.poolableObject.passivate(holder.get());

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void close() {
        if (!this.isClosed) {
            UNSAFE.freeMemory(this.adr);
            this.isClosed = true;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void finalize() throws Throwable {
        close();
        super.finalize();
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy