Advertisement
Guest User

Untitled

a guest
Nov 14th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 2.51 KB | None | 0 0
  1. package faaqueue;
  2.  
  3. import kotlinx.atomicfu.*;
  4.  
  5. import static faaqueue.FAAQueue.Node.NODE_SIZE;
  6.  
  7.  
  8. public class FAAQueue<T> implements Queue<T> {
  9.     private static final Object DONE = new Object(); // Marker for the "DONE" slot state; to avoid memory leaks
  10.  
  11.     private AtomicRef<Node> head; // Head pointer, similarly to the Michael-Scott queue (but the first node is _not_ sentinel)
  12.     private AtomicRef<Node> tail; // Tail pointer, similarly to the Michael-Scott queue
  13.  
  14.     public FAAQueue() {
  15.         Node firstNode = new Node();
  16.         head = new AtomicRef<>(firstNode);
  17.         tail = new AtomicRef<>(firstNode);
  18.     }
  19.  
  20.     @Override
  21.     public void enqueue(T x) {
  22.         while (true) {
  23.             Node oldTail = tail.getValue();
  24.             int enqIdx = oldTail.enqIdx.getAndAdd(1);
  25.             if (enqIdx >= NODE_SIZE) {
  26.                 Node newTail = new Node(x);
  27.                 this.tail.getValue().next = newTail;
  28.                 this.tail.setValue(newTail);
  29.                 return;
  30.             } else {
  31.                 System.
  32.                 if (oldTail.data[enqIdx].compareAndSet(null, x)) {
  33.                     return;
  34.                 }
  35.             }
  36.         }
  37.     }
  38.  
  39.     @Override
  40.     public T dequeue() {
  41.         while (true) {
  42.             Node oldHead = this.head.getValue();
  43.             if (oldHead.isEmpty()) {
  44.                 Object headNext = oldHead.next;
  45.                 if (headNext == null) return null;
  46.                 this.head.compareAndSet(oldHead, (Node) headNext);
  47.             } else {
  48.                 int deqIdx = oldHead.deqIdx.getAndAdd(1);
  49.                 if (deqIdx >= NODE_SIZE) continue;
  50.                 Object res = oldHead.data[deqIdx].getAndSet(DONE);
  51.                 if (res == null) continue;
  52.                 return (T) res;
  53.             }
  54.         }
  55.     }
  56.  
  57.     static class Node {
  58.         static final int NODE_SIZE = 2; // CHANGE ME FOR BENCHMARKING ONLY
  59.  
  60.         private Node next = null;
  61.         private AtomicInt enqIdx = new AtomicInt(0); // index for the next enqueue operation
  62.         private AtomicInt deqIdx = new AtomicInt(0); // index for the next dequeue operation
  63.         private final AtomicRef[] data = new AtomicRef[NODE_SIZE];
  64.  
  65.         Node() {}
  66.  
  67.         Node(Object x) {
  68.             this.enqIdx = new AtomicInt(1);
  69.             this.data[0] = new AtomicRef<>(x);
  70.         }
  71.  
  72.         private boolean isEmpty() {
  73.             return this.deqIdx.getValue() >= this.enqIdx.getValue() || this.deqIdx.getValue() >= NODE_SIZE;
  74.         }
  75.     }
  76. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement