aa
com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM Class Reference
Inheritance diagram for com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM:
[legend]
Collaboration diagram for com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM:
[legend]

Public Member Functions

int size ()
 
int slots ()
 

Package Functions

 CHM (final NonBlockingHashMapLong nbhml, ConcurrentAutoTable size, final int logsize)
 
boolean CAS_newchm (CHM newchm)
 
void clear ()
 

Package Attributes

volatile long _copyDone = 0
 
volatile long _copyIdx = 0
 
final long[] _keys
 
final NonBlockingHashMapLong _nbhml
 
volatile CHM _newchm
 
volatile long _resizers
 
final Object[] _vals
 

Private Member Functions

boolean CAS_key (int idx, long old, long key)
 
boolean CAS_val (int idx, Object old, Object val)
 
void copy_check_and_promote (int workdone)
 
boolean copy_slot (int idx)
 
CHM copy_slot_and_check (int idx, Object should_help)
 
Object get_impl (final long key)
 
void help_copy_impl (final boolean copy_all)
 
void print ()
 
void print2 ()
 
Object putIfMatch (final long key, final Object putval, final Object expVal)
 
CHM resize ()
 
boolean tableFull (int reprobe_cnt, int len)
 

Private Attributes

ConcurrentAutoTable _size
 
ConcurrentAutoTable _slots
 

Static Private Attributes

static final AtomicLongFieldUpdater< CHM_copyDoneUpdater
 
static final AtomicLongFieldUpdater< CHM_copyIdxUpdater
 
static final AtomicReferenceFieldUpdater< CHM, CHM_newchmUpdater
 
static final AtomicLongFieldUpdater< CHM_resizerUpdater
 
static volatile int DUMMY_VOLATILE
 

Detailed Description

Definition at line 426 of file NonBlockingHashMapLong.java.

Constructor & Destructor Documentation

◆ CHM()

com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CHM ( final NonBlockingHashMapLong  nbhml,
ConcurrentAutoTable  size,
final int  logsize 
)
package

Definition at line 490 of file NonBlockingHashMapLong.java.

490  {
491  _nbhml = nbhml;
492  _size = size;
493  _slots= new ConcurrentAutoTable();
494  _keys = new long [1<<logsize];
495  _vals = new Object[1<<logsize];
496  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._nbhml, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._size, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._slots, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._vals, and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.size().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.resize().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Function Documentation

◆ CAS_key()

boolean com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_key ( int  idx,
long  old,
long  key 
)
private

Definition at line 479 of file NonBlockingHashMapLong.java.

479  {
480  return UNSAFE.compareAndSwapLong ( _keys, rawIndex(_keys, idx), old, key );
481  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.rawIndex().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ CAS_newchm()

boolean com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_newchm ( CHM  newchm)
package

Definition at line 458 of file NonBlockingHashMapLong.java.

458  {
459  return _newchmUpdater.compareAndSet(this,null,newchm);
460  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchmUpdater.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.resize().

Here is the caller graph for this function:

◆ CAS_val()

boolean com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_val ( int  idx,
Object  old,
Object  val 
)
private

Definition at line 482 of file NonBlockingHashMapLong.java.

482  {
483  return UNSAFE.compareAndSwapObject( _vals, rawIndex(_vals, idx), old, val );
484  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._vals, and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.rawIndex().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ clear()

void com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.clear ( )
package

Definition at line 498 of file NonBlockingHashMapLong.java.

498  {
499  _size = new ConcurrentAutoTable();
500  _slots= new ConcurrentAutoTable();
501  Arrays.fill(_keys,0);
502  Arrays.fill(_vals,null);
503  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._size, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._slots, and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._vals.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeStruct >.clear().

Here is the caller graph for this function:

◆ copy_check_and_promote()

void com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_check_and_promote ( int  workdone)
private

Definition at line 936 of file NonBlockingHashMapLong.java.

936  {
937  int oldlen = _keys.length;
938  // We made a slot unusable and so did some of the needed copy work
939  long copyDone = _copyDone;
940  long nowDone = copyDone+workdone;
941  assert nowDone <= oldlen;
942  if( workdone > 0 ) {
943  while( !_copyDoneUpdater.compareAndSet(this,copyDone,nowDone) ) {
944  copyDone = _copyDone; // Reload, retry
945  nowDone = copyDone+workdone;
946  assert nowDone <= oldlen;
947  }
948  }
949 
950  // Check for copy being ALL done, and promote. Note that we might have
951  // nested in-progress copies and manage to finish a nested copy before
952  // finishing the top-level copy. We only promote top-level copies.
953  if( nowDone == oldlen && // Ready to promote this table?
954  _nbhml._chm == this && // Looking at the top-level table?
955  // Attempt to promote
956  _nbhml.CAS(_chm_offset,this,_newchm) ) {
957  _nbhml._last_resize_milli = System.currentTimeMillis(); // Record resize time for next check
958  }
959  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >._chm, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >._chm_offset, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._copyDone, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._copyDoneUpdater, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >._last_resize_milli, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._nbhml, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchm, and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CAS().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot_and_check(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.help_copy_impl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy_slot()

boolean com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot ( int  idx)
private

Definition at line 971 of file NonBlockingHashMapLong.java.

971  {
972  // Blindly set the key slot from NO_KEY to some key which hashes here,
973  // to eagerly stop fresh put's from inserting new values in the old
974  // table when the old table is mid-resize. We don't need to act on the
975  // results here, because our correctness stems from box'ing the Value
976  // field. Slamming the Key field is a minor speed optimization.
977  long key;
978  while( (key=_keys[idx]) == NO_KEY )
979  CAS_key(idx, NO_KEY, (idx+_keys.length)/*a non-zero key which hashes here*/);
980 
981  // ---
982  // Prevent new values from appearing in the old table.
983  // Box what we see in the old table, to prevent further updates.
984  Object oldval = _vals[idx]; // Read OLD table
985  while( !(oldval instanceof Prime) ) {
986  final Prime box = (oldval == null || oldval == TOMBSTONE) ? TOMBPRIME : new Prime(oldval);
987  if( CAS_val(idx,oldval,box) ) { // CAS down a box'd version of oldval
988  // If we made the Value slot hold a TOMBPRIME, then we both
989  // prevented further updates here but also the (absent) oldval is
990  // vaccuously available in the new table. We return with true here:
991  // any thread looking for a value for this key can correctly go
992  // straight to the new table and skip looking in the old table.
993  if( box == TOMBPRIME )
994  return true;
995  // Otherwise we boxed something, but it still needs to be
996  // copied into the new table.
997  oldval = box; // Record updated oldval
998  break; // Break loop; oldval is now boxed by us
999  }
1000  oldval = _vals[idx]; // Else try, try again
1001  }
1002  if( oldval == TOMBPRIME ) return false; // Copy already complete here!
1003 
1004  // ---
1005  // Copy the value into the new table, but only if we overwrite a null.
1006  // If another value is already in the new table, then somebody else
1007  // wrote something there and that write is happens-after any value that
1008  // appears in the old table.
1009  Object old_unboxed = ((Prime)oldval)._V;
1010  assert old_unboxed != TOMBSTONE;
1011  boolean copied_into_new = (_newchm.putIfMatch(key, old_unboxed, null) == null);
1012 
1013  // ---
1014  // Finally, now that any old value is exposed in the new table, we can
1015  // forever hide the old-table value by slapping a TOMBPRIME down. This
1016  // will stop other threads from uselessly attempting to copy this slot
1017  // (i.e., it's a speed optimization not a correctness issue).
1018  while( oldval != TOMBPRIME && !CAS_val(idx,oldval,TOMBPRIME) )
1019  oldval = _vals[idx];
1020 
1021  return copied_into_new;
1022  } // end copy_slot

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchm, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._vals, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_key(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_val(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.NO_KEY, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.TOMBPRIME, and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.TOMBSTONE.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot_and_check(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.help_copy_impl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ copy_slot_and_check()

CHM com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot_and_check ( int  idx,
Object  should_help 
)
private

Definition at line 924 of file NonBlockingHashMapLong.java.

924  {
925  // We're only here because the caller saw a Prime, which implies a
926  // table-copy is in progress.
927  assert _newchm != null;
928  if( copy_slot(idx) ) // Copy the desired slot
929  copy_check_and_promote(1); // Record the slot copied
930  // Generically help along any copy (except if called recursively from a helper)
931  if( should_help != null ) _nbhml.help_copy();
932  return _newchm;
933  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._nbhml, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchm, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_check_and_promote(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.help_copy().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.get_impl(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_impl()

Object com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.get_impl ( final long  key)
private

Definition at line 535 of file NonBlockingHashMapLong.java.

535  {
536  final int hash = hash(key);
537  final int len = _keys.length;
538  int idx = (hash & (len-1)); // First key hash
539 
540  // Main spin/reprobe loop, looking for a Key hit
541  int reprobe_cnt=0;
542  while( true ) {
543  final long K = _keys[idx]; // Get key before volatile read, could be NO_KEY
544  final Object V = _vals[idx]; // Get value before volatile read, could be null or Tombstone or Prime
545  if( K == NO_KEY ) return null; // A clear miss
546 
547  // Key-compare
548  if( key == K ) {
549  // Key hit! Check for no table-copy-in-progress
550  if( !(V instanceof Prime) ) { // No copy?
551  if( V == TOMBSTONE) return null;
552  // We need a volatile-read between reading a newly inserted Value
553  // and returning the Value (so the user might end up reading the
554  // stale Value contents).
555  @SuppressWarnings("unused") final CHM newchm = _newchm; // VOLATILE READ before returning V
556  return V;
557  }
558  // Key hit - but slot is (possibly partially) copied to the new table.
559  // Finish the copy & retry in the new table.
560  return copy_slot_and_check(idx,key).get_impl(key); // Retry in the new table
561  }
562  // get and put must have the same key lookup logic! But only 'put'
563  // needs to force a table-resize for a too-long key-reprobe sequence.
564  // Check for too-many-reprobes on get.
565  if( ++reprobe_cnt >= reprobe_limit(len) ) // too many probes
566  return _newchm == null // Table copy in progress?
567  ? null // Nope! A clear miss
568  : copy_slot_and_check(idx,key).get_impl(key); // Retry in the new table
569 
570  idx = (idx+1)&(len-1); // Reprobe by 1! (could now prefetch)
571  }
572  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchm, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._vals, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot_and_check(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.get_impl(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.hash(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.NO_KEY, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.reprobe_limit(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.TOMBSTONE.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeStruct >.get(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.get_impl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ help_copy_impl()

void com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.help_copy_impl ( final boolean  copy_all)
private

Definition at line 861 of file NonBlockingHashMapLong.java.

861  {
862  final CHM newchm = _newchm;
863  assert newchm != null; // Already checked by caller
864  int oldlen = _keys.length; // Total amount to copy
865  final int MIN_COPY_WORK = Math.min(oldlen,1024); // Limit per-thread work
866 
867  // ---
868  int panic_start = -1;
869  int copyidx=-9999; // Fool javac to think it's initialized
870  while( _copyDone < oldlen ) { // Still needing to copy?
871  // Carve out a chunk of work. The counter wraps around so every
872  // thread eventually tries to copy every slot repeatedly.
873 
874  // We "panic" if we have tried TWICE to copy every slot - and it still
875  // has not happened. i.e., twice some thread somewhere claimed they
876  // would copy 'slot X' (by bumping _copyIdx) but they never claimed to
877  // have finished (by bumping _copyDone). Our choices become limited:
878  // we can wait for the work-claimers to finish (and become a blocking
879  // algorithm) or do the copy work ourselves. Tiny tables with huge
880  // thread counts trying to copy the table often 'panic'.
881  if( panic_start == -1 ) { // No panic?
882  copyidx = (int)_copyIdx;
883  while( copyidx < (oldlen<<1) && // 'panic' check
884  !_copyIdxUpdater.compareAndSet(this,copyidx,copyidx+MIN_COPY_WORK) )
885  copyidx = (int)_copyIdx; // Re-read
886  if( !(copyidx < (oldlen<<1)) ) // Panic!
887  panic_start = copyidx; // Record where we started to panic-copy
888  }
889 
890  // We now know what to copy. Try to copy.
891  int workdone = 0;
892  for( int i=0; i<MIN_COPY_WORK; i++ )
893  if( copy_slot((copyidx+i)&(oldlen-1)) ) // Made an oldtable slot go dead?
894  workdone++; // Yes!
895  if( workdone > 0 ) // Report work-done occasionally
896  copy_check_and_promote( workdone );// See if we can promote
897  //for( int i=0; i<MIN_COPY_WORK; i++ )
898  // if( copy_slot((copyidx+i)&(oldlen-1)) ) // Made an oldtable slot go dead?
899  // copy_check_and_promote( 1 );// See if we can promote
900 
901  copyidx += MIN_COPY_WORK;
902  // Uncomment these next 2 lines to turn on incremental table-copy.
903  // Otherwise this thread continues to copy until it is all done.
904  if( !copy_all && panic_start == -1 ) // No panic?
905  return; // Then done copying after doing MIN_COPY_WORK
906  }
907  // Extra promotion check, in case another thread finished all copying
908  // then got stalled before promoting.
909  copy_check_and_promote( 0 ); // See if we can promote
910  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._copyDone, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._copyIdx, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._copyIdxUpdater, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchm, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_check_and_promote(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeStruct >.help_copy(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.SnapshotV.SnapshotV().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print()

void com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.print ( )
private

Definition at line 506 of file NonBlockingHashMapLong.java.

506  {
507  for( int i=0; i<_keys.length; i++ ) {
508  long K = _keys[i];
509  if( K != NO_KEY )
510  print_impl(i,K,_vals[i]);
511  }
512  CHM newchm = _newchm; // New table, if any
513  if( newchm != null ) {
514  System.out.println("----");
515  newchm.print();
516  }
517  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchm, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._vals, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.NO_KEY, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.print(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.print_impl().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeStruct >.print(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.print(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeStruct >.print2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ print2()

void com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.print2 ( )
private

Definition at line 520 of file NonBlockingHashMapLong.java.

520  {
521  for( int i=0; i<_keys.length; i++ ) {
522  long K = _keys[i];
523  if( K != NO_KEY ) // key is sane
524  print2_impl(i,K,_vals[i]);
525  }
526  CHM newchm = _newchm; // New table, if any
527  if( newchm != null ) {
528  System.out.println("----");
529  newchm.print2();
530  }
531  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchm, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._vals, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.NO_KEY, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.print2(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.print2_impl().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.print2().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ putIfMatch()

Object com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch ( final long  key,
final Object  putval,
final Object  expVal 
)
private

Definition at line 581 of file NonBlockingHashMapLong.java.

581  {
582  final int hash = hash(key);
583  assert putval != null;
584  assert !(putval instanceof Prime);
585  assert !(expVal instanceof Prime);
586  final int len = _keys.length;
587  int idx = (hash & (len-1)); // The first key
588 
589  // ---
590  // Key-Claim stanza: spin till we can claim a Key (or force a resizing).
591  int reprobe_cnt=0;
592  long K;
593  Object V;
594  while( true ) { // Spin till we get a Key slot
595  V = _vals[idx]; // Get old value
596  K = _keys[idx]; // Get current key
597  if( K == NO_KEY ) { // Slot is free?
598  // Found an empty Key slot - which means this Key has never been in
599  // this table. No need to put a Tombstone - the Key is not here!
600  if( putval == TOMBSTONE ) return TOMBSTONE; // Not-now & never-been in this table
601  if( expVal == MATCH_ANY ) return TOMBSTONE; // Will not match, even after K inserts
602  // Claim the zero key-slot
603  if( CAS_key(idx, NO_KEY, key) ) { // Claim slot for Key
604  _slots.add(1); // Raise key-slots-used count
605  break; // Got it!
606  }
607  // CAS to claim the key-slot failed.
608  //
609  // This re-read of the Key points out an annoying short-coming of Java
610  // CAS. Most hardware CAS's report back the existing value - so that
611  // if you fail you have a *witness* - the value which caused the CAS
612  // to fail. The Java API turns this into a boolean destroying the
613  // witness. Re-reading does not recover the witness because another
614  // thread can write over the memory after the CAS. Hence we can be in
615  // the unfortunate situation of having a CAS fail *for cause* but
616  // having that cause removed by a later store. This turns a
617  // non-spurious-failure CAS (such as Azul has) into one that can
618  // apparently spuriously fail - and we avoid apparent spurious failure
619  // by not allowing Keys to ever change.
620  K = _keys[idx]; // CAS failed, get updated value
621  assert K != NO_KEY ; // If keys[idx] is NO_KEY, CAS shoulda worked
622  }
623  // Key slot was not null, there exists a Key here
624  if( K == key )
625  break; // Got it!
626 
627  // get and put must have the same key lookup logic! Lest 'get' give
628  // up looking too soon.
629  //topmap._reprobes.add(1);
630  if( ++reprobe_cnt >= reprobe_limit(len) ) {
631  // We simply must have a new table to do a 'put'. At this point a
632  // 'get' will also go to the new table (if any). We do not need
633  // to claim a key slot (indeed, we cannot find a free one to claim!).
634  final CHM newchm = resize();
635  if( expVal != null ) _nbhml.help_copy(); // help along an existing copy
636  return newchm.putIfMatch(key,putval,expVal);
637  }
638 
639  idx = (idx+1)&(len-1); // Reprobe!
640  } // End of spinning till we get a Key slot
641 
642  while ( true ) { // Spin till we insert a value
643  // ---
644  // Found the proper Key slot, now update the matching Value slot. We
645  // never put a null, so Value slots monotonically move from null to
646  // not-null (deleted Values use Tombstone). Thus if 'V' is null we
647  // fail this fast cutout and fall into the check for table-full.
648  if( putval == V ) return V; // Fast cutout for no-change
649 
650  // See if we want to move to a new table (to avoid high average re-probe
651  // counts). We only check on the initial set of a Value from null to
652  // not-null (i.e., once per key-insert).
653  if( (V == null && tableFull(reprobe_cnt,len)) ||
654  // Or we found a Prime: resize is already in progress. The resize
655  // call below will do a CAS on _newchm forcing the read.
656  V instanceof Prime) {
657  resize(); // Force the new table copy to start
658  return copy_slot_and_check(idx,expVal).putIfMatch(key,putval,expVal);
659  }
660 
661  // ---
662  // We are finally prepared to update the existing table
663  //assert !(V instanceof Prime); // always true, so IDE warnings if uncommented
664 
665  // Must match old, and we do not? Then bail out now. Note that either V
666  // or expVal might be TOMBSTONE. Also V can be null, if we've never
667  // inserted a value before. expVal can be null if we are called from
668  // copy_slot.
669 
670  if( expVal != NO_MATCH_OLD && // Do we care about expected-Value at all?
671  V != expVal && // No instant match already?
672  (expVal != MATCH_ANY || V == TOMBSTONE || V == null) &&
673  !(V==null && expVal == TOMBSTONE) && // Match on null/TOMBSTONE combo
674  (expVal == null || !expVal.equals(V)) ) // Expensive equals check at the last
675  return (V==null) ? TOMBSTONE : V; // Do not update!
676 
677  // Actually change the Value in the Key,Value pair
678  if( CAS_val(idx, V, putval ) ) break;
679 
680  // CAS failed
681  // Because we have no witness, we do not know why it failed.
682  // Indeed, by the time we look again the value under test might have flipped
683  // a thousand times and now be the expected value (despite the CAS failing).
684  // Check for the never-succeed condition of a Prime value and jump to any
685  // nested table, or else just re-run.
686 
687  // We would not need this load at all if CAS returned the value on which
688  // the CAS failed (AKA witness). The new CAS semantics are supported via
689  // VarHandle in JDK9.
690  V = _vals[idx]; // Get new value
691 
692  // If a Prime'd value got installed, we need to re-run the put on the
693  // new table. Otherwise we lost the CAS to another racing put.
694  // Simply retry from the start.
695  if( V instanceof Prime )
696  return copy_slot_and_check(idx,expVal).putIfMatch(key,putval,expVal);
697 
698  // Simply retry from the start.
699  // NOTE: need the fence, since otherwise '_vals[idx]' load could be hoisted
700  // out of loop.
701  int dummy = DUMMY_VOLATILE;
702  }
703 
704  // CAS succeeded - we did the update!
705  // Both normal put's and table-copy calls putIfMatch, but table-copy
706  // does not (effectively) increase the number of live k/v pairs.
707  if( expVal != null ) {
708  // Adjust sizes - a striped counter
709  if( (V == null || V == TOMBSTONE) && putval != TOMBSTONE ) _size.add( 1);
710  if( !(V == null || V == TOMBSTONE) && putval == TOMBSTONE ) _size.add(-1);
711  }
712 
713  // We won; we know the update happened as expected.
714  return (V==null && expVal!=null) ? TOMBSTONE : V;
715  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._nbhml, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._size, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._slots, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._vals, com.cliffc.aa.util.ConcurrentAutoTable.add(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_key(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_val(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot_and_check(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.DUMMY_VOLATILE, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.hash(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.help_copy(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.MATCH_ANY, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.NO_KEY, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.NO_MATCH_OLD, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.reprobe_limit(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.resize(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.tableFull(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.TOMBSTONE.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_slot(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeStruct >.putIfMatch(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ resize()

CHM com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.resize ( )
private

Definition at line 741 of file NonBlockingHashMapLong.java.

741  {
742  // Check for resize already in progress, probably triggered by another thread
743  CHM newchm = _newchm; // VOLATILE READ
744  if( newchm != null ) // See if resize is already in progress
745  return newchm; // Use the new table already
746 
747  // No copy in-progress, so start one. First up: compute new table size.
748  int oldlen = _keys.length; // Old count of K,V pairs allowed
749  int sz = size(); // Get current table count of active K,V pairs
750  int newsz = sz; // First size estimate
751 
752  // Heuristic to determine new size. We expect plenty of dead-slots-with-keys
753  // and we need some decent padding to avoid endless reprobing.
754  if( _nbhml._opt_for_space ) {
755  // This heuristic leads to a much denser table with a higher reprobe rate
756  if( sz >= (oldlen>>1) ) // If we are >50% full of keys then...
757  newsz = oldlen<<1; // Double size
758  } else {
759  if( sz >= (oldlen>>2) ) { // If we are >25% full of keys then...
760  newsz = oldlen<<1; // Double size
761  if( sz >= (oldlen>>1) ) // If we are >50% full of keys then...
762  newsz = oldlen<<2; // Double double size
763  }
764  }
765 
766  // Last (re)size operation was very recent? Then double again
767  // despite having few live keys; slows down resize operations
768  // for tables subject to a high key churn rate - but do not
769  // forever grow the table. If there is a high key churn rate
770  // the table needs a steady state of rare same-size resize
771  // operations to clean out the dead keys.
772  long tm = System.currentTimeMillis();
773  if( newsz <= oldlen && // New table would shrink or hold steady?
774  tm <= _nbhml._last_resize_milli+10000) // Recent resize (less than 10 sec ago)
775  newsz = oldlen<<1; // Double the existing size
776 
777  // Do not shrink, ever. If we hit this size once, assume we
778  // will again.
779  if( newsz < oldlen ) newsz = oldlen;
780 
781  // Convert to power-of-2
782  int log2;
783  for( log2=MIN_SIZE_LOG; (1<<log2) < newsz; log2++ ) ; // Compute log2 of size
784  long len = ((1L << log2) << 1) + 2;
785  // prevent integer overflow - limit of 2^31 elements in a Java array
786  // so here, 2^30 + 2 is the largest number of elements in the hash table
787  if ((int)len!=len) {
788  log2 = 30;
789  len = (1L << log2) + 2;
790  if (sz > ((len >> 2) + (len >> 1))) throw new RuntimeException("Table is full.");
791  }
792 
793  // Now limit the number of threads actually allocating memory to a
794  // handful - lest we have 750 threads all trying to allocate a giant
795  // resized array.
796  long r = _resizers;
797  while( !_resizerUpdater.compareAndSet(this,r,r+1) )
798  r = _resizers;
799  // Size calculation: 2 words (K+V) per table entry, plus a handful. We
800  // guess at 64-bit pointers; 32-bit pointers screws up the size calc by
801  // 2x but does not screw up the heuristic very much.
802  long megs = ((((1L<<log2)<<1)+8)<<3/*word to bytes*/)>>20/*megs*/;
803  if( r >= 2 && megs > 0 ) { // Already 2 guys trying; wait and see
804  newchm = _newchm; // Between dorking around, another thread did it
805  if( newchm != null ) // See if resize is already in progress
806  return newchm; // Use the new table already
807  // We could use a wait with timeout, so we'll wakeup as soon as the new table
808  // is ready, or after the timeout in any case.
809  //synchronized( this ) { wait(8*megs); } // Timeout - we always wakeup
810  // For now, sleep a tad and see if the 2 guys already trying to make
811  // the table actually get around to making it happen.
812  try { Thread.sleep(megs); } catch( Exception e ) { /*empty*/}
813  }
814  // Last check, since the 'new' below is expensive and there is a chance
815  // that another thread slipped in a new thread while we ran the heuristic.
816  newchm = _newchm;
817  if( newchm != null ) // See if resize is already in progress
818  return newchm; // Use the new table already
819 
820  // New CHM - actually allocate the big arrays
821  newchm = new CHM(_nbhml,_size,log2);
822 
823  // Another check after the slow allocation
824  if( _newchm != null ) // See if resize is already in progress
825  return _newchm; // Use the new table already
826 
827  // The new table must be CAS'd in so only 1 winner amongst duplicate
828  // racing resizing threads. Extra CHM's will be GC'd.
829  if( CAS_newchm( newchm ) ) { // NOW a resize-is-in-progress!
830  //notifyAll(); // Wake up any sleepers
831  //long nano = System.nanoTime();
832  //System.out.println(" "+nano+" Resize from "+oldlen+" to "+(1<<log2)+" and had "+(_resizers-1)+" extras" );
833  //System.out.print("["+log2);
834  } else // CAS failed?
835  newchm = _newchm; // Reread new table
836  return newchm;
837  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._keys, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >._last_resize_milli, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._nbhml, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchm, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >._opt_for_space, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._resizers, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._resizerUpdater, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._size, com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_newchm(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CHM(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.MIN_SIZE_LOG, and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.size().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ size()

int com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.size ( )

Definition at line 432 of file NonBlockingHashMapLong.java.

432 { return (int)_size.get(); }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._size, and com.cliffc.aa.util.ConcurrentAutoTable.get().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CHM(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.resize(), and com.cliffc.aa.util.NonBlockingHashMapLong< TypeStruct >.size().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ slots()

int com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.slots ( )

Definition at line 445 of file NonBlockingHashMapLong.java.

445 { return (int)_slots.get(); }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._slots, and com.cliffc.aa.util.ConcurrentAutoTable.get().

Here is the call graph for this function:

◆ tableFull()

boolean com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.tableFull ( int  reprobe_cnt,
int  len 
)
private

Definition at line 726 of file NonBlockingHashMapLong.java.

726  {
727  return
728  // Do the cheap check first: we allow some number of reprobes always
729  reprobe_cnt >= REPROBE_LIMIT &&
730  (reprobe_cnt >= reprobe_limit(len) ||
731  // More expensive check: see if the table is > 1/2 full.
732  _slots.estimate_get() >= (len>>1));
733  }

References com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._slots, com.cliffc.aa.util.ConcurrentAutoTable.estimate_get(), com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.REPROBE_LIMIT, and com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.reprobe_limit().

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.putIfMatch().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ _copyDone

◆ _copyDoneUpdater

final AtomicLongFieldUpdater<CHM> com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._copyDoneUpdater
staticprivate
Initial value:
=
AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyDone")

Definition at line 854 of file NonBlockingHashMapLong.java.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.copy_check_and_promote().

◆ _copyIdx

volatile long com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._copyIdx = 0
package

◆ _copyIdxUpdater

final AtomicLongFieldUpdater<CHM> com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._copyIdxUpdater
staticprivate
Initial value:
=
AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyIdx")

Definition at line 847 of file NonBlockingHashMapLong.java.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.help_copy_impl().

◆ _keys

◆ _nbhml

◆ _newchm

◆ _newchmUpdater

final AtomicReferenceFieldUpdater<CHM,CHM> com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._newchmUpdater
staticprivate
Initial value:
=
AtomicReferenceFieldUpdater.newUpdater(CHM.class,CHM.class, "_newchm")

Definition at line 455 of file NonBlockingHashMapLong.java.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.CAS_newchm().

◆ _resizers

volatile long com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._resizers
package

◆ _resizerUpdater

final AtomicLongFieldUpdater<CHM> com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM._resizerUpdater
staticprivate
Initial value:
=
AtomicLongFieldUpdater.newUpdater(CHM.class, "_resizers")

Definition at line 474 of file NonBlockingHashMapLong.java.

Referenced by com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.resize().

◆ _size

◆ _slots

◆ _vals

◆ DUMMY_VOLATILE

volatile int com.cliffc.aa.util.NonBlockingHashMapLong< TypeV >.CHM.DUMMY_VOLATILE
staticprivate

The documentation for this class was generated from the following file:
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._slots
ConcurrentAutoTable _slots
Definition: NonBlockingHashMapLong.java:444
com.cliffc.aa.util.NonBlockingHashMapLong._chm
transient CHM _chm
Definition: NonBlockingHashMapLong.java:131
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.copy_slot_and_check
CHM copy_slot_and_check(int idx, Object should_help)
Definition: NonBlockingHashMapLong.java:924
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.size
int size()
Definition: NonBlockingHashMapLong.java:432
com.cliffc.aa.util.NonBlockingHashMapLong.REPROBE_LIMIT
static final int REPROBE_LIMIT
Definition: NonBlockingHashMapLong.java:95
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._size
ConcurrentAutoTable _size
Definition: NonBlockingHashMapLong.java:431
com.cliffc.aa.util.NonBlockingHashMapLong.MIN_SIZE_LOG
static final int MIN_SIZE_LOG
Definition: NonBlockingHashMapLong.java:145
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._vals
final Object[] _vals
Definition: NonBlockingHashMapLong.java:487
com.cliffc.aa.util.NonBlockingHashMapLong.reprobe_limit
static int reprobe_limit(int len)
Definition: NonBlockingHashMapLong.java:210
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._copyIdxUpdater
static final AtomicLongFieldUpdater< CHM > _copyIdxUpdater
Definition: NonBlockingHashMapLong.java:847
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._nbhml
final NonBlockingHashMapLong _nbhml
Definition: NonBlockingHashMapLong.java:428
com.cliffc.aa.util.ConcurrentAutoTable.add
void add(long x)
Add the given value to current counter value.
Definition: ConcurrentAutoTable.java:30
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.CAS_newchm
boolean CAS_newchm(CHM newchm)
Definition: NonBlockingHashMapLong.java:458
com.cliffc.aa.util.NonBlockingHashMapLong.MATCH_ANY
static final Object MATCH_ANY
Definition: NonBlockingHashMapLong.java:154
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._copyIdx
volatile long _copyIdx
Definition: NonBlockingHashMapLong.java:846
com.cliffc.aa.util.NonBlockingHashMapLong._chm_offset
static final long _chm_offset
Definition: NonBlockingHashMapLong.java:116
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.get_impl
Object get_impl(final long key)
Definition: NonBlockingHashMapLong.java:535
com.cliffc.aa.util.NonBlockingHashMapLong.print_impl
static void print_impl(final int i, final long K, final Object V)
Definition: NonBlockingHashMapLong.java:177
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.putIfMatch
Object putIfMatch(final long key, final Object putval, final Object expVal)
Definition: NonBlockingHashMapLong.java:581
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._copyDone
volatile long _copyDone
Definition: NonBlockingHashMapLong.java:853
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.CAS_key
boolean CAS_key(int idx, long old, long key)
Definition: NonBlockingHashMapLong.java:479
com.cliffc.aa.util.NonBlockingHashMapLong.NO_KEY
static final long NO_KEY
Definition: NonBlockingHashMapLong.java:167
com.cliffc.aa.util.NonBlockingHashMapLong.help_copy
void help_copy()
Definition: NonBlockingHashMapLong.java:403
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._copyDoneUpdater
static final AtomicLongFieldUpdater< CHM > _copyDoneUpdater
Definition: NonBlockingHashMapLong.java:854
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._newchm
volatile CHM _newchm
Definition: NonBlockingHashMapLong.java:454
com.cliffc.aa.util.NonBlockingHashMapLong._opt_for_space
final boolean _opt_for_space
Definition: NonBlockingHashMapLong.java:140
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.resize
CHM resize()
Definition: NonBlockingHashMapLong.java:741
com.cliffc.aa.util.NonBlockingHashMapLong.hash
static final int hash(long h)
Definition: NonBlockingHashMapLong.java:416
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.copy_slot
boolean copy_slot(int idx)
Definition: NonBlockingHashMapLong.java:971
com.cliffc.aa.util.NonBlockingHashMapLong.rawIndex
static long rawIndex(final Object[] ary, final int idx)
Definition: NonBlockingHashMapLong.java:100
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.CHM
CHM(final NonBlockingHashMapLong nbhml, ConcurrentAutoTable size, final int logsize)
Definition: NonBlockingHashMapLong.java:490
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.print2
void print2()
Definition: NonBlockingHashMapLong.java:520
com.cliffc.aa.util.NonBlockingHashMapLong._last_resize_milli
transient long _last_resize_milli
Definition: NonBlockingHashMapLong.java:137
com.cliffc.aa.util.ConcurrentAutoTable.estimate_get
long estimate_get()
A cheaper get.
Definition: ConcurrentAutoTable.java:60
com.cliffc.aa.util.NonBlockingHashMapLong.TOMBSTONE
static final Object TOMBSTONE
Definition: NonBlockingHashMapLong.java:157
com.cliffc.aa.util.NonBlockingHashMapLong.print2_impl
static void print2_impl(final int i, final long K, final Object V)
Definition: NonBlockingHashMapLong.java:190
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._keys
final long[] _keys
Definition: NonBlockingHashMapLong.java:486
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._resizerUpdater
static final AtomicLongFieldUpdater< CHM > _resizerUpdater
Definition: NonBlockingHashMapLong.java:474
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.DUMMY_VOLATILE
static volatile int DUMMY_VOLATILE
Definition: NonBlockingHashMapLong.java:580
com.cliffc.aa.util.NonBlockingHashMapLong.NO_MATCH_OLD
static final Object NO_MATCH_OLD
Definition: NonBlockingHashMapLong.java:151
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._newchmUpdater
static final AtomicReferenceFieldUpdater< CHM, CHM > _newchmUpdater
Definition: NonBlockingHashMapLong.java:455
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.tableFull
boolean tableFull(int reprobe_cnt, int len)
Definition: NonBlockingHashMapLong.java:726
com.cliffc.aa.util.NonBlockingHashMapLong.CHM._resizers
volatile long _resizers
Definition: NonBlockingHashMapLong.java:473
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.copy_check_and_promote
void copy_check_and_promote(int workdone)
Definition: NonBlockingHashMapLong.java:936
com.cliffc.aa.util.ConcurrentAutoTable.get
long get()
Current value of the counter.
Definition: ConcurrentAutoTable.java:50
com.cliffc.aa.util.NonBlockingHashMapLong.TOMBPRIME
static final Prime TOMBPRIME
Definition: NonBlockingHashMapLong.java:162
com.cliffc.aa.util.NonBlockingHashMapLong.CAS
final boolean CAS(final long offset, final Object old, final Object nnn)
Definition: NonBlockingHashMapLong.java:119
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.CAS_val
boolean CAS_val(int idx, Object old, Object val)
Definition: NonBlockingHashMapLong.java:482
com.cliffc.aa.util.NonBlockingHashMapLong.CHM.print
void print()
Definition: NonBlockingHashMapLong.java:506