public int drain(final Consumer<E> elementConsumer, final int limit) { int count = 0; E e; while (count < limit && null != (e = poll())) { elementConsumer.accept(e); ++count; } return count; }
@SuppressWarnings("unchecked") public E poll() { final long[] sequences = this.sequences; final long mask = this.capacity - 1; while (true) { final long currentHead = head; final long sequenceOffset = sequenceArrayOffset(currentHead, mask); final long sequence = UNSAFE.getLongVolatile(sequences, sequenceOffset); final long attemptedHead = currentHead + 1L; if (sequence < attemptedHead) { return null; } if (UNSAFE.compareAndSwapLong(this, HEAD_OFFSET, currentHead, attemptedHead)) { final long elementOffset = sequenceToBufferOffset(currentHead, mask); final Object e = UNSAFE.getObject(buffer, elementOffset); UNSAFE.putObject(buffer, elementOffset, null); UNSAFE.putOrderedLong(sequences, sequenceOffset, attemptedHead + mask); return (E)e; } } }
static <T> ReactiveSeq<T> reactiveBufferBlock(int buffer, Consumer<? super Subscriber<T>> onNext){ return Spouts.reactiveStream(new BufferingSinkOperator<T>(new ManyToManyConcurrentArrayQueue<T>(buffer), onNext,BufferOverflowPolicy.BLOCK)); } static <T> ReactiveSeq<T> reactiveBuffer(Queue<T> buffer,BufferOverflowPolicy policy, Consumer<? super Subscriber<T>> onNext){
public ObjectPool(int capacity, Function<ObjectPool<T>, T> objectFactory) { this.queue = new ManyToManyConcurrentArrayQueue<>(capacity); for (int i = 0; i < capacity; i++) { this.queue.add(objectFactory.apply(this)); } }
/** * Create a new queue with a bounded capacity. The requested capacity will be rounded up to the next positive * power of two in size. That is if you request a capacity of 1000 then you will get 1024. If you request 1024 * then that is what you will get. * * @param requestedCapacity of the queue which must be >= 2. * @throws IllegalArgumentException if the requestedCapacity < 2. */ public ManyToManyConcurrentArrayQueue(final int requestedCapacity) { super(requestedCapacity); if (requestedCapacity < 2) { throw new IllegalArgumentException( "requestedCapacity must be >= 2: requestedCapacity=" + requestedCapacity); } final long[] sequences = new long[capacity]; for (int i = 0; i < capacity; i++) { sequences[i] = i; } UNSAFE.putLongVolatile(sequences, sequenceArrayOffset(0, sequences.length - 1), 0); this.sequences = sequences; }
private void doWork() { submittedCallbacks.drain(this); if (clock.update()) { timerJobQueue.processExpiredTimers(clock); } currentTask = taskScheduler.getNextTask(clock); if (currentTask != null) { try { executeCurrentTask(); } finally { taskScheduler.onTaskReleased(currentTask); } } else { idleStrategy.onIdle(); } }
static <T> ReactiveSeq<T> asyncBufferBlock(int buffer, Consumer<? super PushSubscriber<T>> onNext){ return Spouts.asyncStream(new BufferingSinkOperator<T>(new ManyToManyConcurrentArrayQueue<T>(buffer), c-> onNext.accept(PushSubscriber.of(c)), BufferOverflowPolicy.BLOCK)); } static <T> ReactiveSeq<T> asyncBuffer(Queue<T> buffer,BufferOverflowPolicy policy, Consumer<? super PushSubscriber<T>> onNext){
public ObjectPool(int capacity, Function<ObjectPool<T>, T> objectFactory) { this.queue = new ManyToManyConcurrentArrayQueue<>(capacity); for (int i = 0; i < capacity; i++) { this.queue.add(objectFactory.apply(this)); } }
/** * Create a new queue with a bounded capacity. The requested capacity will be rounded up to the next positive * power of two in size. That is if you request a capacity of 1000 then you will get 1024. If you request 1024 * then that is what you will get. * * @param requestedCapacity of the queue which must be >= 2. * @throws IllegalArgumentException if the requestedCapacity < 2. */ public ManyToManyConcurrentArrayQueue(final int requestedCapacity) { super(requestedCapacity); if (requestedCapacity < 2) { throw new IllegalArgumentException("requestCapacity must be >= 2: requestedCapacity=" + requestedCapacity); } final long[] sequences = new long[capacity]; for (int i = 0, size = capacity; i < size; i++) { final long sequenceOffset = sequenceArrayOffset(i, capacity - 1); UNSAFE.putOrderedLong(sequences, sequenceOffset, i); } this.sequences = sequences; }
private void doWork() { submittedCallbacks.drain(this); if (clock.update()) { timerJobQueue.processExpiredTimers(clock); } currentTask = taskScheduler.getNextTask(clock); if (currentTask != null) { try { executeCurrentTask(); } finally { taskScheduler.onTaskReleased(currentTask); } } else { idleStrategy.onIdle(); } }
static <T> ReactiveSeq<T> asyncBuffer(int buffer, Consumer<? super PushSubscriber<T>> onNext){ return Spouts.asyncStream(new BufferingSinkOperator<T>(new ManyToManyConcurrentArrayQueue<T>(buffer),c-> onNext.accept(PushSubscriber.of(c)), BufferOverflowPolicy.DROP)); } static <T> ReactiveSeq<T> asyncBufferBlock(int buffer, Consumer<? super PushSubscriber<T>> onNext){
public boolean offer(final E e) { if (null == e) { throw new NullPointerException("element cannot be null"); } final long mask = this.capacity - 1; final long[] sequences = this.sequences; while (true) { final long currentTail = tail; final long sequenceOffset = sequenceArrayOffset(currentTail, mask); final long sequence = UNSAFE.getLongVolatile(sequences, sequenceOffset); if (sequence < currentTail) { return false; } if (UNSAFE.compareAndSwapLong(this, TAIL_OFFSET, currentTail, currentTail + 1L)) { UNSAFE.putObject(buffer, sequenceToBufferOffset(currentTail, mask), e); UNSAFE.putOrderedLong(sequences, sequenceOffset, currentTail + 1L); return true; } } }
public int drainTo(final Collection<? super E> target, final int limit) { int count = 0; while (count < limit) { final E e = poll(); if (null == e) { break; } target.add(e); ++count; } return count; }
/** * Create a new queue with a bounded capacity. The requested capacity will be rounded up to the next positive * power of two in size. That is if you request a capacity of 1000 then you will get 1024. If you request 1024 * then that is what you will get. * * @param requestedCapacity of the queue which must be >= 2. * @throws IllegalArgumentException if the requestedCapacity < 2. */ public ManyToManyConcurrentArrayQueue(final int requestedCapacity) { super(requestedCapacity); if (requestedCapacity < 2) { throw new IllegalArgumentException( "requestedCapacity must be >= 2: requestedCapacity=" + requestedCapacity); } final long[] sequences = new long[capacity]; for (int i = 0; i < capacity; i++) { sequences[i] = i; } UNSAFE.putLongVolatile(sequences, sequenceArrayOffset(0, sequences.length - 1), 0); this.sequences = sequences; }
return Spouts.reactiveStream(new BufferingSinkOperator<T>(new ManyToManyConcurrentArrayQueue<T>(buffer), onNext, BufferOverflowPolicy.DROP));
public boolean offer(final E e) { if (null == e) { throw new NullPointerException("element cannot be null"); } final long mask = this.capacity - 1; final long[] sequences = this.sequences; while (true) { final long currentTail = tail; final long sequenceOffset = sequenceArrayOffset(currentTail, mask); final long sequence = UNSAFE.getLongVolatile(sequences, sequenceOffset); if (sequence < currentTail) { return false; } if (UNSAFE.compareAndSwapLong(this, TAIL_OFFSET, currentTail, currentTail + 1L)) { UNSAFE.putObject(buffer, sequenceToBufferOffset(currentTail, mask), e); UNSAFE.putOrderedLong(sequences, sequenceOffset, currentTail + 1L); return true; } } }
public T request() { return this.queue.poll(); } }