Advertisement
Guest User

Untitled

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