ConcurrentSkipList.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import sun.misc.Unsafe;
  2. import java.lang.reflect.Field;
  3. import java.util.ArrayList;
  4. import java.util.HashSet;
  5. import java.util.List;
  6. import java.util.Set;
  7. import java.util.Stack;
  8. import java.util.concurrent.*;
  9. import java.util.concurrent.atomic.AtomicInteger;
  10. import java.util.concurrent.atomic.AtomicReference;
  11. public class ConcurrentSkipList<K extends Comparable<K>, V> {
  12. private static Unsafe unsafe = getUnsafe();
  13. private static long valueOffset;
  14. private static long nextOffset;
  15. static {
  16. try {
  17. valueOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("value"));
  18. nextOffset = unsafe.objectFieldOffset(Node.class.getDeclaredField("next"));
  19. } catch (Exception e) {
  20. // Ignore
  21. }
  22. }
  23. private final ThreadLocalRandom random;
  24. private final int maxLevel;
  25. private final double p;
  26. private volatile Index<K, V> head;
  27. public ConcurrentSkipList(int maxLevel, double p) {
  28. random = ThreadLocalRandom.current();
  29. this.maxLevel = maxLevel;
  30. this.p = p;
  31. Node<K, V> node = new Node<>(null);
  32. head = new Index<>(node);
  33. }
  34. public V put(K key, V value) {
  35. Stack<Index<K, V>> update = new Stack<>();
  36. Index<K, V> curr = head;
  37. while (curr != null) {
  38. while (curr.right != null && cmp(key, curr.right.node.key) > 0) {
  39. curr = curr.right;
  40. }
  41. update.add(curr);
  42. curr = curr.down;
  43. }
  44. Node<K, V> p = update.peek().node;
  45. while (p.next != null && cmp(key, p.next.key) >= 0) {
  46. p = p.next;
  47. }
  48. if (p.key != null && cmp(key, p.key) == 0) {
  49. // update value only
  50. while (!unsafe.compareAndSwapObject(p, valueOffset, p.value, value)) {
  51. }
  52. return value;
  53. }
  54. Node<K, V> after = putAfter(p, key, value);
  55. while (!update.isEmpty()) {
  56. update.pop();
  57. }
  58. return value;
  59. }
  60. public boolean containsKey(K key) {
  61. Index curr = head;
  62. while (curr != null) {
  63. while (curr.right != null && cmp(key, curr.right.node.key) > 0) {
  64. curr = curr.right;
  65. }
  66. if (curr.down == null) {
  67. break;
  68. } else {
  69. curr = curr.down;
  70. }
  71. }
  72. Node node = curr.node;
  73. while (node.next != null && cmp(key, node.next.key) > 0) {
  74. node = node.next;
  75. }
  76. return node.next != null && cmp(key, node.next.key) == 0;
  77. }
  78. public V get(K key) {
  79. Index<K, V> curr = head;
  80. while (curr != null) {
  81. while (curr.right != null && cmp(key, curr.right.node.key) > 0) {
  82. curr = curr.right;
  83. }
  84. if (curr.down == null) {
  85. break;
  86. } else {
  87. curr = curr.down;
  88. }
  89. }
  90. Node<K, V> node = curr.node;
  91. while (node.next != null && cmp(key, node.next.key) > 0) {
  92. node = node.next;
  93. }
  94. node = node.next;
  95. if (node != null && cmp(key, node.key) == 0) {
  96. return node.value;
  97. }
  98. return null;
  99. }
  100. private static Unsafe getUnsafe() {
  101. try {
  102. Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
  103. Field field = unsafeClass.getDeclaredField("theUnsafe");
  104. field.setAccessible(true);
  105. Unsafe unsafe = (Unsafe) field.get(null);
  106. return unsafe;
  107. } catch (Exception e) {
  108. e.printStackTrace();
  109. }
  110. return null;
  111. }
  112. private Node<K, V> putAfter(Node<K, V> before, K key, V value) {
  113. Node<K, V> after = new Node<>(key, value);
  114. while (true) {
  115. Node<K, V> next = before.next;
  116. after.next = next;
  117. if (unsafe.compareAndSwapObject(before, nextOffset, next, after)) {
  118. break;
  119. }
  120. }
  121. return after;
  122. }
  123. private int cmp(Object o1, Object o2) {
  124. return ((Comparable) o1).compareTo((Comparable) o2);
  125. }
  126. public static void main(String[] args) {
  127. ConcurrentSkipList<Integer, String> skipList = new ConcurrentSkipList<>(20, 0.2);
  128. skipList.put(1, "answer");
  129. System.out.println(skipList.get(1));
  130. }
  131. private static class Node<K, V> {
  132. private K key;
  133. private V value;
  134. private Node<K, V> next;
  135. private Node(K key, V value) {
  136. this.key = key;
  137. this.value = value;
  138. }
  139. private Node(Node<K, V> next) {
  140. this.next = next;
  141. }
  142. }
  143. private static class Index<K, V> {
  144. private Node<K, V> node;
  145. private Index<K, V> down;
  146. private Index<K, V> right;
  147. private Index(Node<K, V> node) {
  148. this.node = node;
  149. }
  150. }
  151. }