gogoWebsite

ConcurrentHashMap: spread, tabAt, casTabAt, setTabAt, resizeStamp, tableSizeFor

Updated to 17 days ago

5.1——Spread(hash) Source code analysis

    / 
	* 1100 0011 1010 0101 0001 1100 0001 1110
     * 0000 0000 0000 0000 1100 0011 1010 0101
     * 1100 0011 1010 0101 1101 1111 1011 1011
     * ---------------------------------------
     * 1100 0011 1010 0101 1101 1111 1011 1011
     * 0111 1111 1111 1111 1111 1111 1111 1111  ==HASH_BITS
     * 0100 0011 1010 0101 1101 1111 1011 1011
     *
     *The current hash is moved right16bit or original hash&HASH_BITS Get the hash value of a positive number*Let high16bits are also involved in the operation*/
    static final int spread(int h) {
        return (h ^ (h >>> 16)) & HASH_BITS;
    }

5.2——tabAt(tab, index) source code analysis

    //Get the element of the specified subscript position in the array
    @SuppressWarnings("unchecked")
    static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
        return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
    }

5.3———casTabAt(tab, index, c, v) source code analysis

    //Use cas to set the value of the specified position of the table, and return true after successful setting.
    static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
                                        Node<K,V> c, Node<K,V> v) {
        return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
    }

5.4——setTabAt(tab, index, v) source code analysis

    //Specify the location setting value
    static final <K,V> void setTabAt(Node<K,V>[] tab, int i, Node<K,V> v) {
        U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v);
    }

5.5——ResizeStamp(int n) Source code analysis

    /**
      * Returns the stamp bits for resizing a table of size n.
      * Must be negative when shifted left by RESIZE_STAMP_SHIFT.
      * The capacity expansion mark can only be consistent before it can participate in the capacity expansion
      * 16 -> 32
      * numberOfLeadingZeros(16) => 1 0000 =>27 =>0000 0000 0001 1011
      * | 16-1
      * (1 << (RESIZE_STAMP_BITS - 1)) => 1000 0000 0000 0000 => 32768
      * ---------------------------------------------------------------
      * 0000 0000 0001 1011
      * 1000 0000 0000 0000
      * 1000 0000 0001 1011
      */
    static final int resizeStamp(int n) {
        return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1));
    }

5.6——tableSizeFor(int c) source code analysis

    /**
      * Returns a power of two table size for the given desired capacity.
      * See Hackers Delight, sec 3.2
      * Returns the minimum power of 2 of >=c
      * c=28
      * n=27 => 0b 11011
      * 11011 | 01101 => 11111
      * 11111 | 00111 => 11111
      * ....
      * => 11111 + 1 =100000 = 32
      */
    private static final int tableSizeFor(int c) {
        int n = c - 1;
        n |= n >>> 1;
        n |= n >>> 2;
        n |= n >>> 4;
        n |= n >>> 8;
        n |= n >>> 16;
        return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
    }