Advertisement
Guest User

Untitled

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