package io.datakernel.bytebuf;

import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * 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);

	public void push(ByteBuf newHead) {
		ByteBuf oldHead;
		int oldStamp;
		do {
			int[] oldStampRef = new int[1];
			oldHead = head.get(oldStampRef);
			oldStamp = oldStampRef[0];
			newHead.next = oldHead;
		} while (!head.compareAndSet(oldHead, newHead, oldStamp, oldStamp + 1));
	}

	public ByteBuf pop() {
		ByteBuf oldHead;
		ByteBuf newHead;
		int oldStamp;
		do {
			int[] oldStampRef = new int[1];
			oldHead = head.get(oldStampRef);
			oldStamp = oldStampRef[0];
			if (oldHead == null) {
				return null;
			}
			newHead = oldHead.next;
		} while (!head.compareAndSet(oldHead, newHead, oldStamp, oldStamp + 1));
		return oldHead;
	}

	public ByteBuf peek() {
		return head.getReference();
	}

	public void clear() {
		head.set(null, 0);
	}

	public boolean isEmpty() {
		return head.getReference() == null;
	}

	public int size() {
		int result = 0;
		ByteBuf node = head.getReference();
		while (node != null) {
			node = node.next;
			result++;
		}
		return result;
	}
}

@@ -62,31 +62,24 @@
 tomic.Atomic
-Stamped
 Reference;%0A%0A
@@ -244,16 +244,76 @@
 Stack %7B%0A
+%09private static final class ByteBufRef %7B%0A%09%09ByteBuf buf;%0A%09%7D%0A%0A
 %09private
@@ -321,31 +321,24 @@
 final Atomic
-Stamped
 Reference%3CBy
@@ -342,16 +342,19 @@
 %3CByteBuf
+Ref
 %3E head =
@@ -368,15 +368,8 @@
 omic
-Stamped
 Refe
@@ -377,22 +377,31 @@
 ence%3C%3E(n
-ull, 0
+ew ByteBufRef()
 );%0A%0A%09pub
@@ -438,32 +438,35 @@
  %7B%0A%09%09ByteBuf
+Ref
  oldHead
 ;%0A%09%09int oldS
@@ -457,78 +457,105 @@
 Head
+Ref
 ;%0A%09%09
-int oldStamp;%0A%09%09do %7B%0A%09%09%09int%5B%5D oldStampRef = new int%5B1%5D;%0A%09
+ByteBufRef newHeadRef = new ByteBufRef();%0A%09%09newHeadRef.buf = newHead;%0A%09%09do %7B%0A
 %09%09
+%09
 oldHead
+Ref
  = h
@@ -566,50 +566,9 @@
 get(
-oldStampRef);%0A%09%09%09oldStamp = oldStampRef%5B0%5D
+)
 ;%0A%09%09
@@ -586,24 +586,31 @@
 xt = oldHead
+Ref.buf
 ;%0A%09%09%7D while 
@@ -629,32 +629,35 @@
 reAndSet(oldHead
+Ref
 , newHead, oldSt
@@ -653,32 +653,11 @@
 Head
-, oldStamp, oldStamp + 1
+Ref
 ));%0A
@@ -693,24 +693,27 @@
 %09ByteBuf
+Ref
  oldHead
 ;%0A%09%09Byte
@@ -700,24 +700,27 @@
 fRef oldHead
+Ref
 ;%0A%09%09ByteBuf 
@@ -718,24 +718,27 @@
 %09ByteBuf
+Ref
  newHead
 ;%0A%09%09int 
@@ -733,67 +733,57 @@
 Head
-;%0A%09%09int oldStamp;%0A%09%09do %7B%0A%09%09%09int%5B%5D oldStampRef = new int%5B1%5D;
+Ref = new ByteBufRef();%0A%09%09ByteBuf oldHead;%0A%09%09do %7B
 %0A%09%09%09
@@ -789,16 +789,19 @@
 %09oldHead
+Ref
  = head.
@@ -804,27 +804,16 @@
 ead.get(
-oldStampRef
 );%0A%09%09%09ol
@@ -817,30 +817,29 @@
 %09old
-Stamp
+Head
  = old
-StampRef%5B0%5D
+HeadRef.buf
 ;%0A%09%09
@@ -890,24 +890,31 @@
 %7D%0A%09%09%09newHead
+Ref.buf
  = oldHead.n
@@ -956,16 +956,19 @@
 (oldHead
+Ref
 , newHea
@@ -972,32 +972,11 @@
 Head
-, oldStamp, oldStamp + 1
+Ref
 ));%0A
@@ -1039,27 +1039,22 @@
 head.get
-Reference()
+().buf
 ;%0A%09%7D%0A%0A%09p
@@ -1090,14 +1090,23 @@
 et(n
-ull, 0
+ew ByteBufRef()
 );%0A%09
@@ -1153,27 +1153,22 @@
 head.get
-Reference()
+().buf
  == null
@@ -1241,19 +1241,14 @@
 .get
-Reference()
+().buf
 ;%0A%09%09

Optimize AtomicStampedReference in ByteBufConcurrentStack