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

shz.core.queue.p.ConcurrentPQueue Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
package shz.core.queue.p;

import shz.core.NullHelp;
import shz.core.lock.ReadWriteLockHolder;

import java.io.*;
import java.util.Arrays;
import java.util.Comparator;

@SuppressWarnings("unchecked")
public final class ConcurrentPQueue extends ReadWriteLockHolder implements Serializable {
    private static final long serialVersionUID = -4626363787236007870L;
    final int capacity;
    transient E[] queue;
    transient int size;
    final Comparator comparator;

    public ConcurrentPQueue(int capacity, Comparator comparator) {
        NullHelp.requireNon(capacity < 1);
        NullHelp.requireNonNull(comparator);
        this.capacity = capacity;
        this.comparator = comparator;
        queue = (E[]) new Object[capacity];
    }

    public ConcurrentPQueue(Comparator comparator) {
        this(16, comparator);
    }

    public static  ConcurrentPQueue of(int capacity, Comparator comparator) {
        return new ConcurrentPQueue<>(capacity, comparator);
    }

    public static  ConcurrentPQueue of(Comparator comparator) {
        return new ConcurrentPQueue<>(comparator);
    }

    public int size() {
        readLock.lock();
        try {
            return size;
        } finally {
            readLock.unlock();
        }
    }

    public boolean isEmpty() {
        readLock.lock();
        try {
            return size == 0;
        } finally {
            readLock.unlock();
        }
    }

    public void offer(E e) {
        writeLock.lock();
        try {
            int i = size;
            if (i >= queue.length) grow(i + 1);
            size = i + 1;
            if (i == 0) queue[0] = e;
            else siftUp(i, e);
        } finally {
            writeLock.unlock();
        }
    }

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    private void grow(int minCapacity) {
        int oldCapacity = queue.length;
        int newCapacity = oldCapacity + (oldCapacity < 64 ? oldCapacity + 2 : oldCapacity >> 1);
        if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity);
        queue = Arrays.copyOf(queue, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) throw new OutOfMemoryError();
        return minCapacity > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }

    private void siftUp(int k, E x) {
        while (k > 0) {
            int parent = (k - 1) >>> 1;
            E e = queue[parent];
            if (comparator.compare(x, e) > 0) break;
            queue[k] = e;
            k = parent;
        }
        queue[k] = x;
    }

    public E poll() {
        writeLock.lock();
        try {
            if (size == 0) return null;
            int s = --size;
            E result = queue[0];
            E x = queue[s];
            queue[s] = null;
            if (s != 0) siftDown(0, x);
            return result;
        } finally {
            writeLock.unlock();
        }
    }

    private void siftDown(int k, E x) {
        int half = size >>> 1;
        while (k < half) {
            int child = (k << 1) + 1;
            E c = queue[child];
            int right = child + 1;
            if (right < size && comparator.compare(c, queue[right]) > 0) c = queue[child = right];
            if (comparator.compare(x, c) < 0) break;
            queue[k] = c;
            k = child;
        }
        queue[k] = x;
    }

    public E peek() {
        readLock.lock();
        try {
            return size == 0 ? null : queue[0];
        } finally {
            readLock.unlock();
        }
    }

    private void writeObject(ObjectOutputStream oos) throws IOException {
        oos.defaultWriteObject();
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        ois.defaultReadObject();
        queue = (E[]) new Object[capacity];
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy