/** Get and clear the current count of reprobes. Reprobes happen on key * collisions, and a high reprobe rate may indicate a poor hash function or * weaknesses in the table resizing function. * @return the count of reprobes since the last call to {@link #reprobes} * or since the table was created. */ public long reprobes() { long r = _reprobes.get(); _reprobes = new ConcurrentAutoTable(); return r; }
/** * Add the given value to current counter value. Concurrent updates will * not be lost, but addAndGet or getAndAdd are not implemented because the * total counter value (i.e., {@link #get}) is not atomically updated. * Updates are striped across an array of counters to avoid cache contention * and has been tested with performance scaling linearly up to 768 CPUs. */ public void add( long x ) { add_if_mask( x,0); } /** {@link #add} with -1 */
private final boolean tableFull( int reprobe_cnt, int len ) { return // Do the cheap check first: we allow some number of reprobes always reprobe_cnt >= REPROBE_LIMIT && // More expensive check: see if the table is > 1/4 full. _slots.estimate_get() >= reprobe_limit(len); }
CHM( ConcurrentAutoTable size ) { _size = size; _slots= new ConcurrentAutoTable(); }
public int size() { return (int)_size.get(); }
/** Atomically set the sum of the striped counters to specified value. * Rather more expensive than a simple store, in order to remain atomic. */ public void set( long x ) { CAT newcat = new CAT(null,4,x); // Spin until CAS works while( !CAS_cat(_cat,newcat) ); }
private long add_if_mask( long x, long mask ) { return _cat.add_if_mask(x,mask,hash(),this); }
CHM( ConcurrentAutoTable size ) { _size = size; _slots= new ConcurrentAutoTable(); }
public int size () { return (int)_size.get(); }
/** Get and clear the current count of reprobes. Reprobes happen on key * collisions, and a high reprobe rate may indicate a poor hash function or * weaknesses in the table resizing function. * @return the count of reprobes since the last call to {@link #reprobes} * or since the table was created. */ public long reprobes() { long r = _reprobes.get(); _reprobes = new ConcurrentAutoTable(); return r; }
/** Create a new empty bit-vector */ public NonBlockingSetInt( ) { _nbsi = new NBSI(63, new ConcurrentAutoTable(), this); // The initial 1-word set }
public int slots() { return (int)_slots.get(); }
private final boolean tableFull( int reprobe_cnt, int len ) { return // Do the cheap check first: we allow some number of reprobes always reprobe_cnt >= REPROBE_LIMIT && // More expensive check: see if the table is > 1/2 full. _slots.estimate_get() >= reprobe_limit(len)*2; }
public boolean remove( final int i ) { if( (i>>6) >= _bits.length ) // Out of bounds? Not in this array! return _new==null ? false : help_copy().remove(i); // Handle every 64th bit via using a nested array NBSI nbsi = this; // The bit array being added into int j = i; // The bit index being added while( (j&63) == 63 ) { // Bit 64? (low 6 bits are all set) nbsi = nbsi._nbsi64; // Recurse j = j>>6; // Strip off low 6 bits (all set) } final long mask = mask(j); long old; do { old = nbsi._bits[j>>6]; // Read old bits if( old < 0 ) // Not mutable? // Not mutable: finish copy of word, and retry on copied word return help_copy_impl(i).help_copy().remove(i); if( (old & mask) == 0 ) return false; // Bit is already clear? } while( !nbsi.CAS( j>>6, old, old & ~mask ) ); _size.add(-1); return true; }
/** {@link #add} with -1 */ public void decrement() { add_if_mask(-1L,0); } /** {@link #add} with +1 */
/** Get and clear the current count of reprobes. Reprobes happen on key * collisions, and a high reprobe rate may indicate a poor hash function or * weaknesses in the table resizing function. * @return the count of reprobes since the last call to {@link #reprobes} * or since the table was created. */ public long reprobes() { long r = _reprobes.get(); _reprobes = new ConcurrentAutoTable(); return r; }
private final void initialize( int initial_sz ) { if( initial_sz < 0 ) throw new IllegalArgumentException(); int i; // Convert to next largest power-of-2 if( initial_sz > 1024*1024 ) initial_sz = 1024*1024; for( i=MIN_SIZE_LOG; (1<<i) < (initial_sz<<2); i++ ) ; // Double size for K,V pairs, add 1 for CHM and 1 for hashes _kvs = new Object[((1<<i)<<1)+2]; _kvs[0] = new CHM(new ConcurrentAutoTable()); // CHM in slot 0 _kvs[1] = new int[1<<i]; // Matching hash entries _last_resize_milli = System.currentTimeMillis(); } // Version for subclassed readObject calls, to be called after the defaultReadObject
public int slots() { return (int)_slots.get(); }