aa
com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV > Class Template Reference
Collaboration diagram for com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >:
[legend]

Public Member Functions

int size ()
 
int slots ()
 

Package Functions

 CHM (ConcurrentAutoTable size)
 
boolean CAS_newkvs (Object[] newkvs)
 

Package Attributes

volatile long _copyDone = 0
 
volatile long _copyIdx = 0
 
volatile Object[] _newkvs
 
volatile long _resizers
 

Private Member Functions

final void copy_check_and_promote (NonBlockingHashMap topmap, Object[] oldkvs, int workdone)
 
boolean copy_slot (NonBlockingHashMap topmap, int idx, Object[] oldkvs, Object[] newkvs)
 
final Object[] copy_slot_and_check (NonBlockingHashMap topmap, Object[] oldkvs, int idx, Object should_help)
 
final void help_copy_impl (NonBlockingHashMap topmap, Object[] oldkvs, boolean copy_all)
 
final Object[] resize (NonBlockingHashMap topmap, Object[] kvs)
 
final boolean tableFull (int reprobe_cnt, int len)
 

Private Attributes

final AtomicReferenceFieldUpdater< CHM, Object[]> _newkvsUpdater
 
final ConcurrentAutoTable _size
 
final ConcurrentAutoTable _slots
 

Static Private Attributes

static final AtomicLongFieldUpdater< CHM_copyDoneUpdater
 
static final AtomicLongFieldUpdater< CHM_copyIdxUpdater
 
static final AtomicLongFieldUpdater< CHM_resizerUpdater
 

Detailed Description

Definition at line 802 of file NonBlockingHashMap.java.

Constructor & Destructor Documentation

◆ CHM()

com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.CHM ( ConcurrentAutoTable  size)
package

Definition at line 856 of file NonBlockingHashMap.java.

856  {
857  _size = size;
858  _slots= new ConcurrentAutoTable();
859  }

References com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._size, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._slots, and com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.size().

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.resize().

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

Member Function Documentation

◆ CAS_newkvs()

boolean com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.CAS_newkvs ( Object[]  newkvs)
package

Definition at line 831 of file NonBlockingHashMap.java.

831  {
832  while( _newkvs == null )
833  if( _newkvsUpdater.compareAndSet(this,null,newkvs) )
834  return true;
835  return false;
836  }

References com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._newkvs, and com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._newkvsUpdater.

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.resize().

Here is the caller graph for this function:

◆ copy_check_and_promote()

final void com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_check_and_promote ( NonBlockingHashMap  topmap,
Object[]  oldkvs,
int  workdone 
)
private

Definition at line 1079 of file NonBlockingHashMap.java.

1079  {
1080  assert chm(oldkvs) == this;
1081  int oldlen = len(oldkvs);
1082  // We made a slot unusable and so did some of the needed copy work
1083  long copyDone = _copyDone;
1084  assert (copyDone+workdone) <= oldlen;
1085  if( workdone > 0 ) {
1086  while( !_copyDoneUpdater.compareAndSet(this,copyDone,copyDone+workdone) ) {
1087  copyDone = _copyDone; // Reload, retry
1088  assert (copyDone+workdone) <= oldlen;
1089  }
1090  //if( (10*copyDone/oldlen) != (10*(copyDone+workdone)/oldlen) )
1091  //System.out.print(" "+(copyDone+workdone)*100/oldlen+"%"+"_"+(_copyIdx*100/oldlen)+"%");
1092  }
1093 
1094  // Check for copy being ALL done, and promote. Note that we might have
1095  // nested in-progress copies and manage to finish a nested copy before
1096  // finishing the top-level copy. We only promote top-level copies.
1097  if( copyDone+workdone == oldlen && // Ready to promote this table?
1098  topmap._kvs == oldkvs && // Looking at the top-level table?
1099  // Attempt to promote
1100  topmap.CAS_kvs(oldkvs,_newkvs) ) {
1101  topmap._last_resize_milli = System.currentTimeMillis(); // Record resize time for next check
1102  //long nano = System.nanoTime();
1103  //System.out.println(" "+nano+" Promote table to "+len(_newkvs));
1104  //if( System.out != null ) System.out.print("]");
1105  }
1106  }

References com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._copyDone, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._copyDoneUpdater, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >._kvs, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >._last_resize_milli, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._newkvs, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CAS_kvs(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.chm(), and com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.len().

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_slot_and_check(), and com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.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.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_slot ( NonBlockingHashMap  topmap,
int  idx,
Object[]  oldkvs,
Object[]  newkvs 
)
private

Definition at line 1119 of file NonBlockingHashMap.java.

1119  {
1120  // Blindly set the key slot from null to TOMBSTONE, to eagerly stop
1121  // fresh put's from inserting new values in the old table when the old
1122  // table is mid-resize. We don't need to act on the results here,
1123  // because our correctness stems from box'ing the Value field. Slamming
1124  // the Key field is a minor speed optimization.
1125  Object key;
1126  while( (key=key(oldkvs,idx)) == null )
1127  CAS_key(oldkvs,idx, null, TOMBSTONE);
1128 
1129  // ---
1130  // Prevent new values from appearing in the old table.
1131  // Box what we see in the old table, to prevent further updates.
1132  Object oldval = val(oldkvs,idx); // Read OLD table
1133  while( !(oldval instanceof Prime) ) {
1134  final Prime box = (oldval == null || oldval == TOMBSTONE) ? TOMBPRIME : new Prime(oldval);
1135  if( CAS_val(oldkvs,idx,oldval,box) ) { // CAS down a box'd version of oldval
1136  // If we made the Value slot hold a TOMBPRIME, then we both
1137  // prevented further updates here but also the (absent)
1138  // oldval is vacuously available in the new table. We
1139  // return with true here: any thread looking for a value for
1140  // this key can correctly go straight to the new table and
1141  // skip looking in the old table.
1142  if( box == TOMBPRIME )
1143  return true;
1144  // Otherwise we boxed something, but it still needs to be
1145  // copied into the new table.
1146  oldval = box; // Record updated oldval
1147  break; // Break loop; oldval is now boxed by us
1148  }
1149  oldval = val(oldkvs,idx); // Else try, try again
1150  }
1151  if( oldval == TOMBPRIME ) return false; // Copy already complete here!
1152 
1153  // ---
1154  // Copy the value into the new table, but only if we overwrite a null.
1155  // If another value is already in the new table, then somebody else
1156  // wrote something there and that write is happens-after any value that
1157  // appears in the old table. If putIfMatch does not find a null in the
1158  // new table - somebody else should have recorded the null-not_null
1159  // transition in this copy.
1160  Object old_unboxed = ((Prime)oldval)._V;
1161  assert old_unboxed != TOMBSTONE;
1162  putIfMatch(topmap, newkvs, key, old_unboxed, null);
1163 
1164  // ---
1165  // Finally, now that any old value is exposed in the new table, we can
1166  // forever hide the old-table value by slapping a TOMBPRIME down. This
1167  // will stop other threads from uselessly attempting to copy this slot
1168  // (i.e., it's a speed optimization not a correctness issue).
1169  while( oldval != TOMBPRIME && !CAS_val(oldkvs,idx,oldval,TOMBPRIME) )
1170  oldval = val(oldkvs,idx);
1171 
1172  return true;
1173  } // end copy_slot

References com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CAS_key(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CAS_val(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.key(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.putIfMatch(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.TOMBPRIME, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.TOMBSTONE, and com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.val().

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

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

◆ copy_slot_and_check()

final Object [] com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_slot_and_check ( NonBlockingHashMap  topmap,
Object[]  oldkvs,
int  idx,
Object  should_help 
)
private

Definition at line 1066 of file NonBlockingHashMap.java.

1066  {
1067  assert chm(oldkvs) == this;
1068  Object[] newkvs = _newkvs; // VOLATILE READ
1069  // We're only here because the caller saw a Prime, which implies a
1070  // table-copy is in progress.
1071  assert newkvs != null;
1072  if( copy_slot(topmap,idx,oldkvs,_newkvs) ) // Copy the desired slot
1073  copy_check_and_promote(topmap, oldkvs, 1); // Record the slot copied
1074  // Generically help along any copy (except if called recursively from a helper)
1075  return (should_help == null) ? newkvs : topmap.help_copy(newkvs);
1076  }

References com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._newkvs, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.chm(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_check_and_promote(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_slot(), and com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.help_copy().

Referenced by com.cliffc.aa.util.NonBlockingHashMap< com.cliffc.aa.type.Type.Key, com.cliffc.aa.type.Type >.get_impl(), and com.cliffc.aa.util.NonBlockingHashMap< com.cliffc.aa.type.Type.Key, com.cliffc.aa.type.Type >.putIfMatch().

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

◆ help_copy_impl()

final void com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.help_copy_impl ( NonBlockingHashMap  topmap,
Object[]  oldkvs,
boolean  copy_all 
)
private

Definition at line 1007 of file NonBlockingHashMap.java.

1007  {
1008  assert chm(oldkvs) == this;
1009  Object[] newkvs = _newkvs;
1010  assert newkvs != null; // Already checked by caller
1011  int oldlen = len(oldkvs); // Total amount to copy
1012  final int MIN_COPY_WORK = Math.min(oldlen,1024); // Limit per-thread work
1013 
1014  // ---
1015  int panic_start = -1;
1016  int copyidx=-9999; // Fool javac to think it's initialized
1017  while( _copyDone < oldlen ) { // Still needing to copy?
1018  // Carve out a chunk of work. The counter wraps around so every
1019  // thread eventually tries to copy every slot repeatedly.
1020 
1021  // We "panic" if we have tried TWICE to copy every slot - and it still
1022  // has not happened. i.e., twice some thread somewhere claimed they
1023  // would copy 'slot X' (by bumping _copyIdx) but they never claimed to
1024  // have finished (by bumping _copyDone). Our choices become limited:
1025  // we can wait for the work-claimers to finish (and become a blocking
1026  // algorithm) or do the copy work ourselves. Tiny tables with huge
1027  // thread counts trying to copy the table often 'panic'.
1028  if( panic_start == -1 ) { // No panic?
1029  copyidx = (int)_copyIdx;
1030  while( !_copyIdxUpdater.compareAndSet(this,copyidx,copyidx+MIN_COPY_WORK) )
1031  copyidx = (int)_copyIdx; // Re-read
1032  if( !(copyidx < (oldlen<<1)) ) // Panic!
1033  panic_start = copyidx; // Record where we started to panic-copy
1034  }
1035 
1036  // We now know what to copy. Try to copy.
1037  int workdone = 0;
1038  for( int i=0; i<MIN_COPY_WORK; i++ )
1039  if( copy_slot(topmap,(copyidx+i)&(oldlen-1),oldkvs,newkvs) ) // Made an oldtable slot go dead?
1040  workdone++; // Yes!
1041  if( workdone > 0 ) // Report work-done occasionally
1042  copy_check_and_promote( topmap, oldkvs, workdone );// See if we can promote
1043 
1044  copyidx += MIN_COPY_WORK;
1045  // Uncomment these next 2 lines to turn on incremental table-copy.
1046  // Otherwise this thread continues to copy until it is all done.
1047  if( !copy_all && panic_start == -1 ) // No panic?
1048  return; // Then done copying after doing MIN_COPY_WORK
1049  }
1050  // Extra promotion check, in case another thread finished all copying
1051  // then got stalled before promoting.
1052  copy_check_and_promote( topmap, oldkvs, 0 );// See if we can promote
1053  }

References com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._copyDone, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._copyIdx, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._copyIdxUpdater, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._newkvs, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.chm(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_check_and_promote(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_slot(), and com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.len().

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.SnapshotV.SnapshotV().

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

◆ resize()

final Object [] com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.resize ( NonBlockingHashMap  topmap,
Object[]  kvs 
)
private

Definition at line 885 of file NonBlockingHashMap.java.

885  {
886  assert chm(kvs) == this;
887 
888  // Check for resize already in progress, probably triggered by another thread
889  Object[] newkvs = _newkvs; // VOLATILE READ
890  if( newkvs != null ) // See if resize is already in progress
891  return newkvs; // Use the new table already
892 
893  // No copy in-progress, so start one. First up: compute new table size.
894  int oldlen = len(kvs); // Old count of K,V pairs allowed
895  int sz = size(); // Get current table count of active K,V pairs
896  int newsz = sz; // First size estimate
897 
898  // Heuristic to determine new size. We expect plenty of dead-slots-with-keys
899  // and we need some decent padding to avoid endless reprobing.
900  if( sz >= (oldlen>>2) ) { // If we are >25% full of keys then...
901  newsz = oldlen<<1; // Double size, so new table will be between 12.5% and 25% full
902  // For tables less than 1M entries, if >50% full of keys then...
903  // For tables more than 1M entries, if >75% full of keys then...
904  if( 4L*sz >= ((oldlen>>20)!=0?3L:2L)*oldlen )
905  newsz = oldlen<<2; // Double double size, so new table will be between %12.5 (18.75%) and 25% (25%)
906  }
907  // This heuristic in the next 2 lines leads to a much denser table
908  // with a higher reprobe rate
909  //if( sz >= (oldlen>>1) ) // If we are >50% full of keys then...
910  // newsz = oldlen<<1; // Double size
911 
912  // Last (re)size operation was very recent? Then double again; slows
913  // down resize operations for tables subject to a high key churn rate.
914  long tm = System.currentTimeMillis();
915  long q=0;
916  if( newsz <= oldlen && // New table would shrink or hold steady?
917  (tm <= topmap._last_resize_milli+10000 || // Recent resize (less than 10 sec ago)
918  (q=_slots.estimate_get()) >= (sz<<1)) ) // 1/2 of keys are dead?
919  newsz = oldlen<<1; // Double the existing size
920 
921  // Do not shrink, ever
922  if( newsz < oldlen ) newsz = oldlen;
923 
924  // Convert to power-of-2
925  int log2;
926  for( log2=MIN_SIZE_LOG; (1<<log2) < newsz; log2++ ) ; // Compute log2 of size
927  long len = ((1L << log2) << 1) + 2;
928  // prevent integer overflow - limit of 2^31 elements in a Java array
929  // so here, 2^30 + 2 is the largest number of elements in the hash table
930  if ((int)len!=len) {
931  log2 = 30;
932  len = (1L << log2) + 2;
933  if (sz > ((len >> 2) + (len >> 1))) throw new RuntimeException("Table is full.");
934  }
935 
936  // Now limit the number of threads actually allocating memory to a
937  // handful - lest we have 750 threads all trying to allocate a giant
938  // resized array.
939  long r = _resizers;
940  while( !_resizerUpdater.compareAndSet(this,r,r+1) )
941  r = _resizers;
942  // Size calculation: 2 words (K+V) per table entry, plus a handful. We
943  // guess at 64-bit pointers; 32-bit pointers screws up the size calc by
944  // 2x but does not screw up the heuristic very much.
945  long megs = ((((1L<<log2)<<1)+8)<<3/*word to bytes*/)>>20/*megs*/;
946  if( r >= 2 && megs > 0 ) { // Already 2 guys trying; wait and see
947  newkvs = _newkvs; // Between dorking around, another thread did it
948  if( newkvs != null ) // See if resize is already in progress
949  return newkvs; // Use the new table already
950  // TODO - use a wait with timeout, so we'll wakeup as soon as the new table
951  // is ready, or after the timeout in any case.
952  //synchronized( this ) { wait(8*megs); } // Timeout - we always wakeup
953  // For now, sleep a tad and see if the 2 guys already trying to make
954  // the table actually get around to making it happen.
955  try { Thread.sleep(megs); } catch( Exception e ) { }
956  }
957  // Last check, since the 'new' below is expensive and there is a chance
958  // that another thread slipped in a new thread while we ran the heuristic.
959  newkvs = _newkvs;
960  if( newkvs != null ) // See if resize is already in progress
961  return newkvs; // Use the new table already
962 
963  // Double size for K,V pairs, add 1 for CHM
964  newkvs = new Object[(int)len]; // This can get expensive for big arrays
965  newkvs[0] = new CHM(_size); // CHM in slot 0
966  newkvs[1] = new int[1<<log2]; // hashes in slot 1
967 
968  // Another check after the slow allocation
969  if( _newkvs != null ) // See if resize is already in progress
970  return _newkvs; // Use the new table already
971 
972  // The new table must be CAS'd in so only 1 winner amongst duplicate
973  // racing resizing threads. Extra CHM's will be GC'd.
974  if( CAS_newkvs( newkvs ) ) { // NOW a resize-is-in-progress!
975  //notifyAll(); // Wake up any sleepers
976  //long nano = System.nanoTime();
977  //System.out.println(" "+nano+" Resize from "+oldlen+" to "+(1<<log2)+" and had "+(_resizers-1)+" extras" );
978  //if( System.out != null ) System.out.print("["+log2);
979  topmap.rehash(); // Call for Hashtable's benefit
980  } else // CAS failed?
981  newkvs = _newkvs; // Reread new table
982  return newkvs;
983  }

References com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >._last_resize_milli, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._newkvs, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._resizers, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._resizerUpdater, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._size, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._slots, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.CAS_newkvs(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.chm(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.CHM(), com.cliffc.aa.util.ConcurrentAutoTable.estimate_get(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.len(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.MIN_SIZE_LOG, com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.rehash(), and com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.size().

Referenced by com.cliffc.aa.util.NonBlockingHashMap< com.cliffc.aa.type.Type.Key, com.cliffc.aa.type.Type >.putIfMatch().

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

◆ size()

int com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.size ( )

Definition at line 805 of file NonBlockingHashMap.java.

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

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

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.CHM(), com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.resize(), and com.cliffc.aa.util.NonBlockingHashMap< com.cliffc.aa.type.Type.Key, com.cliffc.aa.type.Type >.size().

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

◆ slots()

int com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.slots ( )

Definition at line 818 of file NonBlockingHashMap.java.

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

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

Here is the call graph for this function:

◆ tableFull()

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

Definition at line 870 of file NonBlockingHashMap.java.

870  {
871  return
872  // Do the cheap check first: we allow some number of reprobes always
873  reprobe_cnt >= REPROBE_LIMIT &&
874  (reprobe_cnt >= reprobe_limit(len) ||
875  // More expensive check: see if the table is > 1/2 full.
876  _slots.estimate_get() >= (len>>1));
877  }

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

Referenced by com.cliffc.aa.util.NonBlockingHashMap< com.cliffc.aa.type.Type.Key, com.cliffc.aa.type.Type >.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.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._copyDoneUpdater
staticprivate
Initial value:
=
AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyDone")

Definition at line 1000 of file NonBlockingHashMap.java.

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.copy_check_and_promote().

◆ _copyIdx

volatile long com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._copyIdx = 0
package

◆ _copyIdxUpdater

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

Definition at line 993 of file NonBlockingHashMap.java.

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.help_copy_impl().

◆ _newkvs

◆ _newkvsUpdater

final AtomicReferenceFieldUpdater<CHM,Object[]> com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._newkvsUpdater
private
Initial value:
=
AtomicReferenceFieldUpdater.newUpdater(CHM.class,Object[].class, "_newkvs")

Definition at line 828 of file NonBlockingHashMap.java.

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.CAS_newkvs().

◆ _resizers

volatile long com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >._resizers
package

◆ _resizerUpdater

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

Definition at line 851 of file NonBlockingHashMap.java.

Referenced by com.cliffc.aa.util.NonBlockingHashMap< TypeK, TypeV >.CHM< TypeK, TypeV >.resize().

◆ _size

◆ _slots


The documentation for this class was generated from the following file:
com.cliffc.aa.util.NonBlockingHashMap.val
static final Object val(Object[] kvs, int idx)
Definition: NonBlockingHashMap.java:173
com.cliffc.aa.util.NonBlockingHashMap.CHM._newkvsUpdater
final AtomicReferenceFieldUpdater< CHM, Object[]> _newkvsUpdater
Definition: NonBlockingHashMap.java:828
com.cliffc.aa.util.NonBlockingHashMap.CHM.CAS_newkvs
boolean CAS_newkvs(Object[] newkvs)
Definition: NonBlockingHashMap.java:831
com.cliffc.aa.util.NonBlockingHashMap.CHM.copy_check_and_promote
final void copy_check_and_promote(NonBlockingHashMap topmap, Object[] oldkvs, int workdone)
Definition: NonBlockingHashMap.java:1079
com.cliffc.aa.util.NonBlockingHashMap.CHM._resizerUpdater
static final AtomicLongFieldUpdater< CHM > _resizerUpdater
Definition: NonBlockingHashMap.java:851
com.cliffc.aa.util.NonBlockingHashMap.CHM.size
int size()
Definition: NonBlockingHashMap.java:805
com.cliffc.aa.util.NonBlockingHashMap.len
static final int len(Object[] kvs)
Definition: NonBlockingHashMap.java:138
com.cliffc.aa.util.NonBlockingHashMap.CHM._copyIdxUpdater
static final AtomicLongFieldUpdater< CHM > _copyIdxUpdater
Definition: NonBlockingHashMap.java:993
com.cliffc.aa.util.NonBlockingHashMap.TOMBPRIME
static final Prime TOMBPRIME
Definition: NonBlockingHashMap.java:163
com.cliffc.aa.util.NonBlockingHashMap.reprobe_limit
static final int reprobe_limit(int len)
Definition: NonBlockingHashMap.java:242
com.cliffc.aa.util.NonBlockingHashMap.CHM.CHM
CHM(ConcurrentAutoTable size)
Definition: NonBlockingHashMap.java:856
com.cliffc.aa.util.NonBlockingHashMap.key
static final Object key(Object[] kvs, int idx)
Definition: NonBlockingHashMap.java:172
com.cliffc.aa.util.NonBlockingHashMap.CHM._size
final ConcurrentAutoTable _size
Definition: NonBlockingHashMap.java:804
com.cliffc.aa.util.NonBlockingHashMap.MIN_SIZE_LOG
static final int MIN_SIZE_LOG
Definition: NonBlockingHashMap.java:146
com.cliffc.aa.util.NonBlockingHashMap.TOMBSTONE
static final Object TOMBSTONE
Definition: NonBlockingHashMap.java:158
com.cliffc.aa.util.NonBlockingHashMap.REPROBE_LIMIT
static final int REPROBE_LIMIT
Definition: NonBlockingHashMap.java:79
com.cliffc.aa.util.NonBlockingHashMap.CHM._resizers
volatile long _resizers
Definition: NonBlockingHashMap.java:850
com.cliffc.aa.util.NonBlockingHashMap.CHM.copy_slot
boolean copy_slot(NonBlockingHashMap topmap, int idx, Object[] oldkvs, Object[] newkvs)
Definition: NonBlockingHashMap.java:1119
com.cliffc.aa.util.NonBlockingHashMap.putIfMatch
final TypeV putIfMatch(Object key, Object newVal, Object oldVal)
Definition: NonBlockingHashMap.java:361
com.cliffc.aa.util.ConcurrentAutoTable.estimate_get
long estimate_get()
A cheaper get.
Definition: ConcurrentAutoTable.java:60
com.cliffc.aa.util.NonBlockingHashMap.CHM._copyDone
volatile long _copyDone
Definition: NonBlockingHashMap.java:999
com.cliffc.aa.util.NonBlockingHashMap.CHM._slots
final ConcurrentAutoTable _slots
Definition: NonBlockingHashMap.java:817
com.cliffc.aa.util.NonBlockingHashMap.CHM._copyIdx
volatile long _copyIdx
Definition: NonBlockingHashMap.java:992
com.cliffc.aa.util.NonBlockingHashMap.CHM._copyDoneUpdater
static final AtomicLongFieldUpdater< CHM > _copyDoneUpdater
Definition: NonBlockingHashMap.java:1000
com.cliffc.aa.util.NonBlockingHashMap.CAS_val
static final boolean CAS_val(Object[] kvs, int idx, Object old, Object val)
Definition: NonBlockingHashMap.java:177
com.cliffc.aa.util.NonBlockingHashMap.chm
static final CHM chm(Object[] kvs)
Definition: NonBlockingHashMap.java:135
com.cliffc.aa.util.NonBlockingHashMap.CAS_key
static final boolean CAS_key(Object[] kvs, int idx, Object old, Object key)
Definition: NonBlockingHashMap.java:174
com.cliffc.aa.util.ConcurrentAutoTable.get
long get()
Current value of the counter.
Definition: ConcurrentAutoTable.java:50
com.cliffc.aa.util.NonBlockingHashMap.CHM._newkvs
volatile Object[] _newkvs
Definition: NonBlockingHashMap.java:827