Optimize AtomicStampedReference in ByteBufConcurrentStack
package io.datakernel.bytebuf;
-import java.util.concurrent.atomic.AtomicStampedReference;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Simple lock-free concurrent stack implementation for the {@link ByteBuf ByteBufs} that is used in {@link ByteBufPool}
*/
final class ByteBufConcurrentStack {
- private final AtomicStampedReference<ByteBuf> head = new AtomicStampedReference<>(null, 0);
+ private static final class ByteBufRef {
+ ByteBuf buf;
+ }
+
+ private final AtomicReference<ByteBufRef> head = new AtomicReference<>(new ByteBufRef());
public void push(ByteBuf newHead) {
- ByteBuf oldHead;
- int oldStamp;
+ ByteBufRef oldHeadRef;
+ ByteBufRef newHeadRef = new ByteBufRef();
+ newHeadRef.buf = newHead;
do {
- int[] oldStampRef = new int[1];
- oldHead = head.get(oldStampRef);
- oldStamp = oldStampRef[0];
- newHead.next = oldHead;
- } while (!head.compareAndSet(oldHead, newHead, oldStamp, oldStamp + 1));
+ oldHeadRef = head.get();
+ newHead.next = oldHeadRef.buf;
+ } while (!head.compareAndSet(oldHeadRef, newHeadRef));
}
public ByteBuf pop() {
+ ByteBufRef oldHeadRef;
+ ByteBufRef newHeadRef = new ByteBufRef();
ByteBuf oldHead;
- ByteBuf newHead;
- int oldStamp;
do {
- int[] oldStampRef = new int[1];
- oldHead = head.get(oldStampRef);
- oldStamp = oldStampRef[0];
+ oldHeadRef = head.get();
+ oldHead = oldHeadRef.buf;
if (oldHead == null) {
return null;
}
- newHead = oldHead.next;
- } while (!head.compareAndSet(oldHead, newHead, oldStamp, oldStamp + 1));
+ newHeadRef.buf = oldHead.next;
+ } while (!head.compareAndSet(oldHeadRef, newHeadRef));
return oldHead;
}
public ByteBuf peek() {
- return head.getReference();
+ return head.get().buf;
}
public void clear() {
- head.set(null, 0);
+ head.set(new ByteBufRef());
}
public boolean isEmpty() {
- return head.getReference() == null;
+ return head.get().buf == null;
}
public int size() {
int result = 0;
- ByteBuf node = head.getReference();
+ ByteBuf node = head.get().buf;
while (node != null) {
node = node.next;
result++;
