rx.internal.util.unsafe.SpscArrayQueue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rxjava-core Show documentation
Show all versions of rxjava-core Show documentation
rxjava-core developed by Netflix
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Original License: https://github.com/JCTools/JCTools/blob/master/LICENSE
* Original location: https://github.com/JCTools/JCTools/blob/master/jctools-core/src/main/java/org/jctools/queues/SpscArrayQueue.java
*/
package rx.internal.util.unsafe;
import java.util.Queue;
abstract class SpscArrayQueueL1Pad extends ConcurrentCircularArrayQueue {
long p10, p11, p12, p13, p14, p15, p16;
long p30, p31, p32, p33, p34, p35, p36, p37;
public SpscArrayQueueL1Pad(int capacity) {
super(capacity);
}
}
abstract class SpscArrayQueueTailField extends SpscArrayQueueL1Pad {
protected long tail;
protected long batchTail;
public SpscArrayQueueTailField(int capacity) {
super(capacity);
}
}
abstract class SpscArrayQueueL2Pad extends SpscArrayQueueTailField {
long p20, p21, p22, p23, p24, p25, p26;
long p30, p31, p32, p33, p34, p35, p36, p37;
public SpscArrayQueueL2Pad(int capacity) {
super(capacity);
}
}
abstract class SpscArrayQueueHeadField extends SpscArrayQueueL2Pad {
protected long head;
public SpscArrayQueueHeadField(int capacity) {
super(capacity);
}
}
abstract class SpscArrayQueueL3Pad extends SpscArrayQueueHeadField {
long p40, p41, p42, p43, p44, p45, p46;
long p30, p31, p32, p33, p34, p35, p36, p37;
public SpscArrayQueueL3Pad(int capacity) {
super(capacity);
}
}
public final class SpscArrayQueue extends SpscArrayQueueL3Pad implements Queue {
private final static long TAIL_OFFSET;
private final static long HEAD_OFFSET;
static {
try {
TAIL_OFFSET = UnsafeAccess.UNSAFE.objectFieldOffset(SpscArrayQueueTailField.class
.getDeclaredField("tail"));
HEAD_OFFSET = UnsafeAccess.UNSAFE.objectFieldOffset(SpscArrayQueueHeadField.class
.getDeclaredField("head"));
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
public SpscArrayQueue(final int capacity) {
super(capacity);
}
private long getHeadV() {
return UnsafeAccess.UNSAFE.getLongVolatile(this, HEAD_OFFSET);
}
private long getTailV() {
return UnsafeAccess.UNSAFE.getLongVolatile(this, TAIL_OFFSET);
}
@Override
public boolean offer(final E e) {
if (null == e) {
throw new NullPointerException("Null is not a valid element");
}
E[] lb = buffer;
if (tail >= batchTail) {
if (null != lvElement(lb, calcOffset(tail))) {
return false;
}
}
soElement(lb, calcOffset(tail), e);
tail++;
return true;
}
@Override
public E poll() {
final long offset = calcOffset(head);
final E[] lb = buffer;
final E e = lvElement(lb, offset);
if (null == e) {
return null;
}
soElement(lb, offset, null);
head++;
return e;
}
@Override
public E peek() {
return lvElement(calcOffset(head));
}
@Override
public int size() {
// TODO: this is ugly :( the head/tail cannot be counted on to be written out, so must take max
return (int) (Math.max(getTailV(), tail) - Math.max(getHeadV(), head));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy