package org.infinispan.persistence.sifs; import java.util.AbstractQueue; import java.util.Collection; import java.util.Iterator; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import org.infinispan.commons.equivalence.Equivalence; /** * Splits the requests into several subqueues according to request.key.hashCode(). If the request has no key, * inserts countdown into the request and puts it into all subqueues - the thread that retrieves such element * should call countDown() and upon true handle the request (this preserves the FIFO ordering). * * @author Radim Vansa <rvansa@redhat.coPausem> */ public class IndexQueue extends AbstractQueue<IndexRequest> implements BlockingQueue<IndexRequest> { private final ArrayBlockingQueue[] queues; private final Equivalence<Object> keyEquivalence; public IndexQueue(int segments, int capacity, Equivalence<Object> keyEquivalence) { queues = new ArrayBlockingQueue[segments]; for (int i = 0; i < segments; ++i) { queues[i] = new ArrayBlockingQueue(capacity); } this.keyEquivalence = keyEquivalence; } @Override public Iterator<IndexRequest> iterator() { throw new UnsupportedOperationException(); } @Override public int size() { throw new UnsupportedOperationException(); } @Override public void put(IndexRequest indexRequest) throws InterruptedException { if (indexRequest.getKey() != null) { queues[Math.abs(keyEquivalence.hashCode(indexRequest.getKey())) % queues.length].put(indexRequest); } else { indexRequest.setCountDown(queues.length); for (int i = 0; i < queues.length; ++i) { queues[i].put(indexRequest); } } } @Override public boolean offer(IndexRequest indexRequest, long timeout, TimeUnit unit) throws InterruptedException { if (indexRequest.getKey() != null) { return queues[Math.abs(keyEquivalence.hashCode(indexRequest.getKey())) % queues.length].offer(indexRequest, timeout, unit); } else { throw new UnsupportedOperationException(); } } @Override public IndexRequest take() throws InterruptedException { throw new UnsupportedOperationException(); } @Override public IndexRequest poll(long timeout, TimeUnit unit) throws InterruptedException { throw new UnsupportedOperationException(); } @Override public int remainingCapacity() { throw new UnsupportedOperationException(); } @Override public int drainTo(Collection<? super IndexRequest> c) { throw new UnsupportedOperationException(); } @Override public int drainTo(Collection<? super IndexRequest> c, int maxElements) { throw new UnsupportedOperationException(); } @Override public boolean offer(IndexRequest indexRequest) { return queues[Math.abs(keyEquivalence.hashCode(indexRequest.getKey())) % queues.length].offer(indexRequest); } @Override public IndexRequest poll() { throw new UnsupportedOperationException(); } @Override public IndexRequest peek() { throw new UnsupportedOperationException(); } public BlockingQueue<IndexRequest> subQueue(int id) { return queues[id]; } }