Advertisement
Guest User

Untitled

a guest
Nov 16th, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.01 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 curTail = tail.getValue();
  24.             int enqIdx = tail.getValue().enqIdx.getAndAdd(1);
  25.             if (enqIdx >= NODE_SIZE) {
  26.                 Node newTail = new Node(x);
  27.                 if (curTail.next.compareAndSet(null, newTail)) {
  28.                     if (tail.compareAndSet(curTail, newTail)) {
  29.                         //
  30.                         //System.out.println(333);
  31.                         return;
  32.                     }
  33.                     //return;
  34.                 }
  35. //                Node newTail = new Node(x);
  36. //                this.tail.getValue().next.setValue(newTail);
  37. //                this.tail.setValue(newTail);
  38. //                return;
  39.             } else {
  40.                 //if (tail.getValue().data.get(enqIdx).compareAndSet(null, x)) {
  41.                 if (curTail.data.get(enqIdx).compareAndSet(null, x)) {
  42.                     return;
  43.                 }
  44.             }
  45.         }
  46. //        int enqIdx = tail.getValue().enqIdx++;
  47. //        if (enqIdx >= NODE_SIZE) {
  48. //            Node newTail = new Node(x);
  49. //            this.tail.getValue().next = newTail;
  50. //            this.tail.setValue(newTail);
  51. //            return;
  52. //        }
  53. //        this.tail.getValue().data[enqIdx] = x;
  54.     }
  55.  
  56.     @Override
  57.     public T dequeue() {
  58.         while (true) {
  59.             Node curHead = head.getValue();
  60.             if (curHead.isEmpty()) {
  61.                 Node curHeadNext = curHead.next.getValue();
  62.                 if (curHeadNext == null) {
  63.                     return null;
  64.                 }
  65.                 if (head.compareAndSet(curHead, curHeadNext)) {
  66.                     //System.out.println(222);
  67.                 }
  68.             } else {
  69.                 int deqIdx = head.getValue().deqIdx.getAndAdd(1);
  70.                 if (deqIdx >= NODE_SIZE) {
  71.                     continue;
  72.                 }
  73.                 Object res = head.getValue().data.get(deqIdx).getAndSet(DONE);
  74.                 if (res == null) {
  75.                     continue;
  76.                 }
  77.                 return (T) res;
  78.             }
  79.         }
  80. //        while (true) {
  81. //            if (this.head.getValue().isEmpty()) {
  82. //                if (this.head.getValue().next == null) return null;
  83. //                this.head.setValue(this.head.getValue().next);
  84. //                continue;
  85. //            }
  86. //            int deqIdx = this.head.getValue().deqIdx++;
  87. //            Object res = head.getValue().data[deqIdx];
  88. //            head.getValue().data[deqIdx] = DONE;
  89. //            return (T) res;
  90. //        }
  91.     }
  92.  
  93.     static class Node {
  94.         static final int NODE_SIZE = 2; // CHANGE ME FOR BENCHMARKING ONLY
  95.  
  96.         private AtomicRef<Node> next = new AtomicRef<>(null);
  97.         private AtomicInt enqIdx = new AtomicInt(0); // index for the next enqueue operation
  98.         private AtomicInt deqIdx = new AtomicInt(0); // index for the next dequeue operation
  99.         private final AtomicArray<Object> data = new AtomicArray<>(NODE_SIZE);
  100.  
  101.         Node() {
  102.         }
  103.  
  104.         Node(Object x) {
  105.             enqIdx.setValue(1);
  106.             data.get(0).setValue(x);
  107.         }
  108.  
  109.         private boolean isEmpty() {
  110.             int deq = deqIdx.getValue();
  111.             int enq = enqIdx.getValue();
  112.             return deq >= enq ||
  113.                     deq >= NODE_SIZE;
  114.         }
  115.     }
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement