src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java

Print this page
rev 12972 : 8140606: Update library code to use internal Unsafe
Reviewed-by: duke


 517                 return null;
 518             @SuppressWarnings("unchecked") V vv = (V)v;
 519             return vv;
 520         }
 521 
 522         /**
 523          * Creates and returns a new SimpleImmutableEntry holding current
 524          * mapping if this node holds a valid value, else null.
 525          * @return new entry or null
 526          */
 527         AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() {
 528             Object v = value;
 529             if (v == null || v == this || v == BASE_HEADER)
 530                 return null;
 531             @SuppressWarnings("unchecked") V vv = (V)v;
 532             return new AbstractMap.SimpleImmutableEntry<K,V>(key, vv);
 533         }
 534 
 535         // Unsafe mechanics
 536 
 537         private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
 538         private static final long VALUE;
 539         private static final long NEXT;
 540 
 541         static {
 542             try {
 543                 VALUE = U.objectFieldOffset
 544                     (Node.class.getDeclaredField("value"));
 545                 NEXT = U.objectFieldOffset
 546                     (Node.class.getDeclaredField("next"));
 547             } catch (ReflectiveOperationException e) {
 548                 throw new Error(e);
 549             }
 550         }
 551     }
 552 
 553     /* ---------------- Indexing -------------- */
 554 
 555     /**
 556      * Index nodes represent the levels of the skip list.  Note that
 557      * even though both Nodes and Indexes have forward-pointing


 597          * @return true if successful
 598          */
 599         final boolean link(Index<K,V> succ, Index<K,V> newSucc) {
 600             Node<K,V> n = node;
 601             newSucc.right = succ;
 602             return n.value != null && casRight(succ, newSucc);
 603         }
 604 
 605         /**
 606          * Tries to CAS right field to skip over apparent successor
 607          * succ.  Fails (forcing a retraversal by caller) if this node
 608          * is known to be deleted.
 609          * @param succ the expected current successor
 610          * @return true if successful
 611          */
 612         final boolean unlink(Index<K,V> succ) {
 613             return node.value != null && casRight(succ, succ.right);
 614         }
 615 
 616         // Unsafe mechanics
 617         private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
 618         private static final long RIGHT;
 619         static {
 620             try {
 621                 RIGHT = U.objectFieldOffset
 622                     (Index.class.getDeclaredField("right"));
 623             } catch (ReflectiveOperationException e) {
 624                 throw new Error(e);
 625             }
 626         }
 627     }
 628 
 629     /* ---------------- Head nodes -------------- */
 630 
 631     /**
 632      * Nodes heading each level keep track of their level.
 633      */
 634     static final class HeadIndex<K,V> extends Index<K,V> {
 635         final int level;
 636         HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
 637             super(node, down, right);


3579                     return k1.compareTo(e2.getKey());
3580                 };
3581             }
3582         }
3583     }
3584 
3585     // Almost the same as keySpliterator()
3586     final EntrySpliterator<K,V> entrySpliterator() {
3587         Comparator<? super K> cmp = comparator;
3588         for (;;) { // almost same as key version
3589             HeadIndex<K,V> h; Node<K,V> p;
3590             Node<K,V> b = (h = head).node;
3591             if ((p = b.next) == null || p.value != null)
3592                 return new EntrySpliterator<K,V>(cmp, h, p, null, (p == null) ?
3593                                                  0 : Integer.MAX_VALUE);
3594             p.helpDelete(b, p.next);
3595         }
3596     }
3597 
3598     // Unsafe mechanics
3599     private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
3600     private static final long HEAD;
3601     static {
3602         try {
3603             HEAD = U.objectFieldOffset
3604                 (ConcurrentSkipListMap.class.getDeclaredField("head"));
3605         } catch (ReflectiveOperationException e) {
3606             throw new Error(e);
3607         }
3608     }
3609 }


 517                 return null;
 518             @SuppressWarnings("unchecked") V vv = (V)v;
 519             return vv;
 520         }
 521 
 522         /**
 523          * Creates and returns a new SimpleImmutableEntry holding current
 524          * mapping if this node holds a valid value, else null.
 525          * @return new entry or null
 526          */
 527         AbstractMap.SimpleImmutableEntry<K,V> createSnapshot() {
 528             Object v = value;
 529             if (v == null || v == this || v == BASE_HEADER)
 530                 return null;
 531             @SuppressWarnings("unchecked") V vv = (V)v;
 532             return new AbstractMap.SimpleImmutableEntry<K,V>(key, vv);
 533         }
 534 
 535         // Unsafe mechanics
 536 
 537         private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
 538         private static final long VALUE;
 539         private static final long NEXT;
 540 
 541         static {
 542             try {
 543                 VALUE = U.objectFieldOffset
 544                     (Node.class.getDeclaredField("value"));
 545                 NEXT = U.objectFieldOffset
 546                     (Node.class.getDeclaredField("next"));
 547             } catch (ReflectiveOperationException e) {
 548                 throw new Error(e);
 549             }
 550         }
 551     }
 552 
 553     /* ---------------- Indexing -------------- */
 554 
 555     /**
 556      * Index nodes represent the levels of the skip list.  Note that
 557      * even though both Nodes and Indexes have forward-pointing


 597          * @return true if successful
 598          */
 599         final boolean link(Index<K,V> succ, Index<K,V> newSucc) {
 600             Node<K,V> n = node;
 601             newSucc.right = succ;
 602             return n.value != null && casRight(succ, newSucc);
 603         }
 604 
 605         /**
 606          * Tries to CAS right field to skip over apparent successor
 607          * succ.  Fails (forcing a retraversal by caller) if this node
 608          * is known to be deleted.
 609          * @param succ the expected current successor
 610          * @return true if successful
 611          */
 612         final boolean unlink(Index<K,V> succ) {
 613             return node.value != null && casRight(succ, succ.right);
 614         }
 615 
 616         // Unsafe mechanics
 617         private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
 618         private static final long RIGHT;
 619         static {
 620             try {
 621                 RIGHT = U.objectFieldOffset
 622                     (Index.class.getDeclaredField("right"));
 623             } catch (ReflectiveOperationException e) {
 624                 throw new Error(e);
 625             }
 626         }
 627     }
 628 
 629     /* ---------------- Head nodes -------------- */
 630 
 631     /**
 632      * Nodes heading each level keep track of their level.
 633      */
 634     static final class HeadIndex<K,V> extends Index<K,V> {
 635         final int level;
 636         HeadIndex(Node<K,V> node, Index<K,V> down, Index<K,V> right, int level) {
 637             super(node, down, right);


3579                     return k1.compareTo(e2.getKey());
3580                 };
3581             }
3582         }
3583     }
3584 
3585     // Almost the same as keySpliterator()
3586     final EntrySpliterator<K,V> entrySpliterator() {
3587         Comparator<? super K> cmp = comparator;
3588         for (;;) { // almost same as key version
3589             HeadIndex<K,V> h; Node<K,V> p;
3590             Node<K,V> b = (h = head).node;
3591             if ((p = b.next) == null || p.value != null)
3592                 return new EntrySpliterator<K,V>(cmp, h, p, null, (p == null) ?
3593                                                  0 : Integer.MAX_VALUE);
3594             p.helpDelete(b, p.next);
3595         }
3596     }
3597 
3598     // Unsafe mechanics
3599     private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
3600     private static final long HEAD;
3601     static {
3602         try {
3603             HEAD = U.objectFieldOffset
3604                 (ConcurrentSkipListMap.class.getDeclaredField("head"));
3605         } catch (ReflectiveOperationException e) {
3606             throw new Error(e);
3607         }
3608     }
3609 }