Pad all groups with empty maps, to ensure it's the same size as
timestamps list.

We want to keep all the Group instances to have the same number of
maps as the timestamps list, so we can zip the two together.
975431
private void fixBacklog() throws IOException {
            try {
                writers.values().parallelStream()
                        .forEach(groupWriter -> {
                            try {
                                groupWriter.fixBacklog(timestamps.size());
                            } catch (IOException ex) {
                                throw new RuntimeIOException(ex);
                            }
                        });
            } catch (RuntimeIOException ex) {
                throw ex.getEx();
            }
        }
281852
public void setGroups(java.util.Collection<Group> groups) {
        if (groups == null) {
            this.groups = null;
            return;
        }

        this.groups = new java.util.ArrayList<Group>(groups);
    }
1090335
@Override
  public void putAll(Map<? extends TypeK, ? extends TypeV> m) {
    for (Map.Entry<? extends TypeK, ? extends TypeV> e : m.entrySet())
      put(e.getKey(), e.getValue());
  }

  /** Removes all of the mappings from this map. */
  @Override
  public void clear() {         // Smack a new empty table down
    Object[] newkvs = new NonBlockingIdentityHashMap(MIN_SIZE)._kvs;
    while( !CAS_kvs(_kvs,newkvs) ) // Spin until the clear works
      ;
  }

  /** Returns <tt>true</tt> if this Map maps one or more keys to the specified
   *  value.  <em>Note</em>: This method requires a full internal traversal of the
   *  hash table and is much slower than {@link #containsKey}.
   *  @param val value whose presence in this map is to be tested
   *  @return <tt>true</tt> if this map maps one or more keys to the specified value
   *  @throws NullPointerException if the specified value is null */
  @Override
  public boolean containsValue( final Object val ) {
    if( val == null ) throw new NullPointerException();
    for( TypeV V : values() )
      if( V == val || V.equals(val) )
        return true;
    return false;
  }

  // This function is supposed to do something for Hashtable, and the JCK
  // tests hang until it gets called... by somebody ... for some reason,
  // any reason....
  protected void rehash() {
  }

  /**
   * Creates a shallow copy of this hashtable. All the structure of the
   * hashtable itself is copied, but the keys and values are not cloned.
   * This is a relatively expensive operation.
   *
   * @return  a clone of the hashtable.
   */
  @Override
  public Object clone() {
    try {
      // Must clone, to get the class right; NBHM might have been
      // extended so it would be wrong to just make a new NBHM.
      NonBlockingIdentityHashMap<TypeK,TypeV> t = (NonBlockingIdentityHashMap<TypeK,TypeV>) super.clone();
      // But I don't have an atomic clone operation - the underlying _kvs
      // structure is undergoing rapid change.  If I just clone the _kvs
      // field, the CHM in _kvs[0] won't be in sync.
      //
      // Wipe out the cloned array (it was shallow anyways).
      t.clear();
      // Now copy sanely
      for( TypeK K : keySet() ) {
        final TypeV V = get(K);  // Do an official 'get'
        t.put(K,V);
      }
      return t;
    } catch (CloneNotSupportedException e) {
      // this shouldn't happen, since we are Cloneable
      throw new InternalError();
    }
  }

  /**
   * Returns a string representation of this map.  The string representation
   * consists of a list of key-value mappings in the order returned by the
   * map's <tt>entrySet</tt> view's iterator, enclosed in braces
   * (<tt>"{}"</tt>).  Adjacent mappings are separated by the characters
   * <tt>", "</tt> (comma and space).  Each key-value mapping is rendered as
   * the key followed by an equals sign (<tt>"="</tt>) followed by the
   * associated value.  Keys and values are converted to strings as by
   * {@link String#valueOf(Object)}.
   *
   * @return a string representation of this map
   */
  @Override
  public String toString() {
    Iterator<Entry<TypeK,TypeV>> i = entrySet().iterator();
    if( !i.hasNext())
      return "{}";

    StringBuilder sb = new StringBuilder();
    sb.append('{');
    for (;;) {
      Entry<TypeK,TypeV> e = i.next();
      TypeK key = e.getKey();
      TypeV value = e.getValue();
      sb.append(key   == this ? "(this Map)" : key);
      sb.append('=');
      sb.append(value == this ? "(this Map)" : value);
      if( !i.hasNext())
        return sb.append('}').toString();
      sb.append(", ");
    }
  }

  // --- get -----------------------------------------------------------------
  /** Returns the value to which the specified key is mapped, or {@code null}
   *  if this map contains no mapping for the key.
   *  <p>More formally, if this map contains a mapping from a key {@code k} to
   *  a value {@code v} such that {@code key.equals(k)}, then this method
   *  returns {@code v}; otherwise it returns {@code null}.  (There can be at
   *  most one such mapping.)
   * @throws NullPointerException if the specified key is null */
  // Never returns a Prime nor a Tombstone.
  @Override
  public TypeV get( Object key ) {
    final Object V = get_impl(this,_kvs,key);
    assert !(V instanceof Prime); // Never return a Prime
    return (TypeV)V;
  }

  private static final Object get_impl( final NonBlockingIdentityHashMap topmap, final Object[] kvs, final Object key ) {
    final int fullhash= hash (key); // throws NullPointerException if key is null
    final int len     = len  (kvs); // Count of key/value pairs, reads kvs.length
    final CHM chm     = chm  (kvs); // The CHM, for a volatile read below; reads slot 0 of kvs

    int idx = fullhash & (len-1); // First key hash

    // Main spin/reprobe loop, looking for a Key hit
    int reprobe_cnt=0;
    while( true ) {
      // Probe table.  Each read of 'val' probably misses in cache in a big
      // table; hopefully the read of 'key' then hits in cache.
      final Object K = key(kvs,idx); // Get key   before volatile read, could be null
      final Object V = val(kvs,idx); // Get value before volatile read, could be null or Tombstone or Prime
      if( K == null ) return null;   // A clear miss

      // We need a volatile-read here to preserve happens-before semantics on
      // newly inserted Keys.  If the Key body was written just before inserting
      // into the table a Key-compare here might read the uninitalized Key body.
      // Annoyingly this means we have to volatile-read before EACH key compare.
      // .
      // We also need a volatile-read between reading a newly inserted Value
      // and returning the Value (so the user might end up reading the stale
      // Value contents).  Same problem as with keys - and the one volatile
      // read covers both.
      final Object[] newkvs = chm._newkvs; // VOLATILE READ before key compare

      // Key-compare
      if( K == key ) {
        // Key hit!  Check for no table-copy-in-progress
        if( !(V instanceof Prime) ) // No copy?
          return (V == TOMBSTONE) ? null : V; // Return the value
        // Key hit - but slot is (possibly partially) copied to the new table.
        // Finish the copy & retry in the new table.
        return get_impl(topmap,chm.copy_slot_and_check(topmap,kvs,idx,key),key); // Retry in the new table
      }
      // get and put must have the same key lookup logic!  But only 'put'
      // needs to force a table-resize for a too-long key-reprobe sequence.
      // Check for too-many-reprobes on get - and flip to the new table.
      if( ++reprobe_cnt >= reprobe_limit(len) || // too many probes
          key == TOMBSTONE ) // found a TOMBSTONE key, means no more keys in this table
        return newkvs == null ? null : get_impl(topmap,topmap.help_copy(newkvs),key); // Retry in the new table

      idx = (idx+1)&(len-1);    // Reprobe by 1!  (could now prefetch)
    }
  }

  // --- putIfMatch ---------------------------------------------------------
  // Put, Remove, PutIfAbsent, etc.  Return the old value.  If the returned
  // value is equal to expVal (or expVal is NO_MATCH_OLD) then the put can be
  // assumed to work (although might have been immediately overwritten).  Only
  // the path through copy_slot passes in an expected value of null, and
  // putIfMatch only returns a null if passed in an expected null.
  private static final Object putIfMatch( final NonBlockingIdentityHashMap topmap, final Object[] kvs, final Object key, final Object putval, final Object expVal ) {
    assert putval != null;
    assert !(putval instanceof Prime);
    assert !(expVal instanceof Prime);
    final int fullhash = hash  (key); // throws NullPointerException if key null
    final int len      = len   (kvs); // Count of key/value pairs, reads kvs.length
    final CHM chm      = chm   (kvs); // Reads kvs[0]
    int idx = fullhash & (len-1);

    // ---
    // Key-Claim stanza: spin till we can claim a Key (or force a resizing).
    int reprobe_cnt=0;
    Object K=null, V=null;
    Object[] newkvs=null;
    while( true ) {             // Spin till we get a Key slot
      V = val(kvs,idx);         // Get old value (before volatile read below!)
      K = key(kvs,idx);         // Get current key
      if( K == null ) {         // Slot is free?
        // Found an empty Key slot - which means this Key has never been in
        // this table.  No need to put a Tombstone - the Key is not here!
        if( putval == TOMBSTONE ) return putval; // Not-now & never-been in this table
        // Claim the null key-slot
        if( CAS_key(kvs,idx, null, key ) ) { // Claim slot for Key
          chm._slots.add(1);      // Raise key-slots-used count
          break;                  // Got it!
        }
        // CAS to claim the key-slot failed.
        //
        // This re-read of the Key points out an annoying short-coming of Java
        // CAS.  Most hardware CAS's report back the existing value - so that
        // if you fail you have a *witness* - the value which caused the CAS
        // to fail.  The Java API turns this into a boolean destroying the
        // witness.  Re-reading does not recover the witness because another
        // thread can write over the memory after the CAS.  Hence we can be in
        // the unfortunate situation of having a CAS fail *for cause* but
        // having that cause removed by a later store.  This turns a
        // non-spurious-failure CAS (such as Azul has) into one that can
        // apparently spuriously fail - and we avoid apparent spurious failure
        // by not allowing Keys to ever change.
        K = key(kvs,idx);       // CAS failed, get updated value
        assert K != null;       // If keys[idx] is null, CAS shoulda worked
      }
      // Key slot was not null, there exists a Key here

      // We need a volatile-read here to preserve happens-before semantics on
      // newly inserted Keys.  If the Key body was written just before inserting
      // into the table a Key-compare here might read the uninitalized Key body.
      // Annoyingly this means we have to volatile-read before EACH key compare.
      newkvs = chm._newkvs;     // VOLATILE READ before key compare

      if( K == key )
        break;                  // Got it!

      // get and put must have the same key lookup logic!  Lest 'get' give
      // up looking too soon.
      //topmap._reprobes.add(1);
      if( ++reprobe_cnt >= reprobe_limit(len) || // too many probes or
          key == TOMBSTONE ) { // found a TOMBSTONE key, means no more keys
        // We simply must have a new table to do a 'put'.  At this point a
        // 'get' will also go to the new table (if any).  We do not need
        // to claim a key slot (indeed, we cannot find a free one to claim!).
        newkvs = chm.resize(topmap,kvs);
        if( expVal != null ) topmap.help_copy(newkvs); // help along an existing copy
        return putIfMatch(topmap,newkvs,key,putval,expVal);
      }

      idx = (idx+1)&(len-1); // Reprobe!
    } // End of spinning till we get a Key slot

    // ---
    // Found the proper Key slot, now update the matching Value slot.  We
    // never put a null, so Value slots monotonically move from null to
    // not-null (deleted Values use Tombstone).  Thus if 'V' is null we
    // fail this fast cutout and fall into the check for table-full.
    if( putval == V ) return V; // Fast cutout for no-change

    // See if we want to move to a new table (to avoid high average re-probe
    // counts).  We only check on the initial set of a Value from null to
    // not-null (i.e., once per key-insert).  Of course we got a 'free' check
    // of newkvs once per key-compare (not really free, but paid-for by the
    // time we get here).
    if( newkvs == null &&       // New table-copy already spotted?
        // Once per fresh key-insert check the hard way
        ((V == null && chm.tableFull(reprobe_cnt,len)) ||
         // Or we found a Prime, but the JMM allowed reordering such that we
         // did not spot the new table (very rare race here: the writing
         // thread did a CAS of _newkvs then a store of a Prime.  This thread
         // reads the Prime, then reads _newkvs - but the read of Prime was so
         // delayed (or the read of _newkvs was so accelerated) that they
         // swapped and we still read a null _newkvs.  The resize call below
         // will do a CAS on _newkvs forcing the read.
         V instanceof Prime) )
      newkvs = chm.resize(topmap,kvs); // Force the new table copy to start
    // See if we are moving to a new table.
    // If so, copy our slot and retry in the new table.
    if( newkvs != null )
      return putIfMatch(topmap,chm.copy_slot_and_check(topmap,kvs,idx,expVal),key,putval,expVal);

    // ---
    // We are finally prepared to update the existing table
    assert !(V instanceof Prime);

    // Must match old, and we do not?  Then bail out now.  Note that either V
    // or expVal might be TOMBSTONE.  Also V can be null, if we've never
    // inserted a value before.  expVal can be null if we are called from
    // copy_slot.

    if( expVal != NO_MATCH_OLD && // Do we care about expected-Value at all?
        V != expVal &&            // No instant match already?
        (expVal != MATCH_ANY || V == TOMBSTONE || V == null) &&
        !(V==null && expVal == TOMBSTONE) &&    // Match on null/TOMBSTONE combo
        (expVal == null || !expVal.equals(V)) ) // Expensive equals check at the last
      return V;                                 // Do not update!

    // Actually change the Value in the Key,Value pair
    if( CAS_val(kvs, idx, V, putval ) ) {
      // CAS succeeded - we did the update!
      // Both normal put's and table-copy calls putIfMatch, but table-copy
      // does not (effectively) increase the number of live k/v pairs.
      if( expVal != null ) {
        // Adjust sizes - a striped counter
        if(  (V == null || V == TOMBSTONE) && putval != TOMBSTONE ) chm._size.add( 1);
        if( !(V == null || V == TOMBSTONE) && putval == TOMBSTONE ) chm._size.add(-1);
      }
    } else {                    // Else CAS failed
      V = val(kvs,idx);         // Get new value
      // If a Prime'd value got installed, we need to re-run the put on the
      // new table.  Otherwise we lost the CAS to another racing put.
      // Simply retry from the start.
      if( V instanceof Prime )
        return putIfMatch(topmap,chm.copy_slot_and_check(topmap,kvs,idx,expVal),key,putval,expVal);
    }
    // Win or lose the CAS, we are done.  If we won then we know the update
    // happened as expected.  If we lost, it means "we won but another thread
    // immediately stomped our update with no chance of a reader reading".
    return (V==null && expVal!=null) ? TOMBSTONE : V;
  }

  // --- help_copy ---------------------------------------------------------
  // Help along an existing resize operation.  This is just a fast cut-out
  // wrapper, to encourage inlining for the fast no-copy-in-progress case.  We
  // always help the top-most table copy, even if there are nested table
  // copies in progress.
  private final Object[] help_copy( Object[] helper ) {
    // Read the top-level KVS only once.  We'll try to help this copy along,
    // even if it gets promoted out from under us (i.e., the copy completes
    // and another KVS becomes the top-level copy).
    Object[] topkvs = _kvs;
    CHM topchm = chm(topkvs);
    if( topchm._newkvs == null ) return helper; // No copy in-progress
    topchm.help_copy_impl(this,topkvs,false);
    return helper;
  }


  // --- CHM -----------------------------------------------------------------
  // The control structure for the NonBlockingIdentityHashMap
  private static final class CHM<TypeK,TypeV> {
    // Size in active K,V pairs
    private final ConcurrentAutoTable _size;
    public int size () { return (int)_size.get(); }

    // ---
    // These next 2 fields are used in the resizing heuristics, to judge when
    // it is time to resize or copy the table.  Slots is a count of used-up
    // key slots, and when it nears a large fraction of the table we probably
    // end up reprobing too much.  Last-resize-milli is the time since the
    // last resize; if we are running back-to-back resizes without growing
    // (because there are only a few live keys but many slots full of dead
    // keys) then we need a larger table to cut down on the churn.

    // Count of used slots, to tell when table is full of dead unusable slots
    private final ConcurrentAutoTable _slots;
    public int slots() { return (int)_slots.get(); }

    // ---
    // New mappings, used during resizing.
    // The 'new KVs' array - created during a resize operation.  This
    // represents the new table being copied from the old one.  It's the
    // volatile variable that is read as we cross from one table to the next,
    // to get the required memory orderings.  It monotonically transits from
    // null to set (once).
    volatile Object[] _newkvs;
    private final AtomicReferenceFieldUpdater<CHM,Object[]> _newkvsUpdater =
      AtomicReferenceFieldUpdater.newUpdater(CHM.class,Object[].class, "_newkvs");
    // Set the _next field if we can.
    boolean CAS_newkvs( Object[] newkvs ) {
      while( _newkvs == null )
        if( _newkvsUpdater.compareAndSet(this,null,newkvs) )
          return true;
      return false;
    }
    // Sometimes many threads race to create a new very large table.  Only 1
    // wins the race, but the losers all allocate a junk large table with
    // hefty allocation costs.  Attempt to control the overkill here by
    // throttling attempts to create a new table.  I cannot really block here
    // (lest I lose the non-blocking property) but late-arriving threads can
    // give the initial resizing thread a little time to allocate the initial
    // new table.  The Right Long Term Fix here is to use array-lets and
    // incrementally create the new very large array.  In C I'd make the array
    // with malloc (which would mmap under the hood) which would only eat
    // virtual-address and not real memory - and after Somebody wins then we
    // could in parallel initialize the array.  Java does not allow
    // un-initialized array creation (especially of ref arrays!).
    volatile long _resizers; // count of threads attempting an initial resize
    private static final AtomicLongFieldUpdater<CHM> _resizerUpdater =
      AtomicLongFieldUpdater.newUpdater(CHM.class, "_resizers");

    // ---
    // Simple constructor
    CHM( ConcurrentAutoTable size ) {
      _size = size;
      _slots= new ConcurrentAutoTable();
    }

    // --- tableFull ---------------------------------------------------------
    // Heuristic to decide if this table is too full, and we should start a
    // new table.  Note that if a 'get' call has reprobed too many times and
    // decided the table must be full, then always the estimate_sum must be
    // high and we must report the table is full.  If we do not, then we might
    // end up deciding that the table is not full and inserting into the
    // current table, while a 'get' has decided the same key cannot be in this
    // table because of too many reprobes.  The invariant is:
    //   slots.estimate_sum >= max_reprobe_cnt >= reprobe_limit(len)
    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);
    }

    // --- resize ------------------------------------------------------------
    // Resizing after too many probes.  "How Big???" heuristics are here.
    // Callers will (not this routine) will 'help_copy' any in-progress copy.
    // Since this routine has a fast cutout for copy-already-started, callers
    // MUST 'help_copy' lest we have a path which forever runs through
    // 'resize' only to discover a copy-in-progress which never progresses.
    private final Object[] resize( NonBlockingIdentityHashMap topmap, Object[] kvs) {
      assert chm(kvs) == this;

      // Check for resize already in progress, probably triggered by another thread
      Object[] newkvs = _newkvs; // VOLATILE READ
      if( newkvs != null )       // See if resize is already in progress
        return newkvs;           // Use the new table already

      // No copy in-progress, so start one.  First up: compute new table size.
      int oldlen = len(kvs);    // Old count of K,V pairs allowed
      int sz = size();          // Get current table count of active K,V pairs
      int newsz = sz;           // First size estimate

      // Heuristic to determine new size.  We expect plenty of dead-slots-with-keys
      // and we need some decent padding to avoid endless reprobing.
      if( sz >= (oldlen>>2) ) { // If we are >25% full of keys then...
        newsz = oldlen<<1;      // Double size
        if( sz >= (oldlen>>1) ) // If we are >50% full of keys then...
          newsz = oldlen<<2;    // Double double size
      }
      // This heuristic in the next 2 lines leads to a much denser table
      // with a higher reprobe rate
      //if( sz >= (oldlen>>1) ) // If we are >50% full of keys then...
      //  newsz = oldlen<<1;    // Double size

      // Last (re)size operation was very recent?  Then double again; slows
      // down resize operations for tables subject to a high key churn rate.
      long tm = System.currentTimeMillis();
      long q=0;
      if( newsz <= oldlen && // New table would shrink or hold steady?
          tm <= topmap._last_resize_milli+10000 && // Recent resize (less than 1 sec ago)
          (q=_slots.estimate_get()) >= (sz<<1) ) // 1/2 of keys are dead?
        newsz = oldlen<<1;      // Double the existing size

      // Do not shrink, ever
      if( newsz < oldlen ) newsz = oldlen;

      // Convert to power-of-2
      int log2;
      for( log2=MIN_SIZE_LOG; (1<<log2) < newsz; log2++ ) ; // Compute log2 of size

      // Now limit the number of threads actually allocating memory to a
      // handful - lest we have 750 threads all trying to allocate a giant
      // resized array.
      long r = _resizers;
      while( !_resizerUpdater.compareAndSet(this,r,r+1) )
        r = _resizers;
      // Size calculation: 2 words (K+V) per table entry, plus a handful.  We
      // guess at 32-bit pointers; 64-bit pointers screws up the size calc by
      // 2x but does not screw up the heuristic very much.
      int megs = ((((1<<log2)<<1)+4)<<3/*word to bytes*/)>>20/*megs*/;
      if( r >= 2 && megs > 0 ) { // Already 2 guys trying; wait and see
        newkvs = _newkvs;        // Between dorking around, another thread did it
        if( newkvs != null )     // See if resize is already in progress
          return newkvs;         // Use the new table already
        // TODO - use a wait with timeout, so we'll wakeup as soon as the new table
        // is ready, or after the timeout in any case.
        //synchronized( this ) { wait(8*megs); }         // Timeout - we always wakeup
        // For now, sleep a tad and see if the 2 guys already trying to make
        // the table actually get around to making it happen.
        try { Thread.sleep(8*megs); } catch( Exception e ) { }
      }
      // Last check, since the 'new' below is expensive and there is a chance
      // that another thread slipped in a new thread while we ran the heuristic.
      newkvs = _newkvs;
      if( newkvs != null )      // See if resize is already in progress
        return newkvs;          // Use the new table already

      // Double size for K,V pairs, add 1 for CHM
      newkvs = new Object[((1<<log2)<<1)+2]; // This can get expensive for big arrays
      newkvs[0] = new CHM(_size); // CHM in slot 0
      newkvs[1] = new int[1<<log2]; // hashes in slot 1

      // Another check after the slow allocation
      if( _newkvs != null )     // See if resize is already in progress
        return _newkvs;         // Use the new table already

      // The new table must be CAS'd in so only 1 winner amongst duplicate
      // racing resizing threads.  Extra CHM's will be GC'd.
      if( CAS_newkvs( newkvs ) ) { // NOW a resize-is-in-progress!
        //notifyAll();            // Wake up any sleepers
        //long nano = System.nanoTime();
        //System.out.println(" "+nano+" Resize from "+oldlen+" to "+(1<<log2)+" and had "+(_resizers-1)+" extras" );
        //if( System.out != null ) System.out.print("["+log2);
        topmap.rehash();        // Call for Hashtable's benefit
      } else                    // CAS failed?
        newkvs = _newkvs;       // Reread new table
      return newkvs;
    }


    // The next part of the table to copy.  It monotonically transits from zero
    // to _kvs.length.  Visitors to the table can claim 'work chunks' by
    // CAS'ing this field up, then copying the indicated indices from the old
    // table to the new table.  Workers are not required to finish any chunk;
    // the counter simply wraps and work is copied duplicately until somebody
    // somewhere completes the count.
    volatile long _copyIdx = 0;
    static private final AtomicLongFieldUpdater<CHM> _copyIdxUpdater =
      AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyIdx");

    // Work-done reporting.  Used to efficiently signal when we can move to
    // the new table.  From 0 to len(oldkvs) refers to copying from the old
    // table to the new.
    volatile long _copyDone= 0;
    static private final AtomicLongFieldUpdater<CHM> _copyDoneUpdater =
      AtomicLongFieldUpdater.newUpdater(CHM.class, "_copyDone");

    // --- help_copy_impl ----------------------------------------------------
    // Help along an existing resize operation.  We hope its the top-level
    // copy (it was when we started) but this CHM might have been promoted out
    // of the top position.
    private final void help_copy_impl( NonBlockingIdentityHashMap topmap, Object[] oldkvs, boolean copy_all ) {
      assert chm(oldkvs) == this;
      Object[] newkvs = _newkvs;
      assert newkvs != null;    // Already checked by caller
      int oldlen = len(oldkvs); // Total amount to copy
      final int MIN_COPY_WORK = Math.min(oldlen,1024); // Limit per-thread work

      // ---
      int panic_start = -1;
      int copyidx=-9999;            // Fool javac to think it's initialized
      while( _copyDone < oldlen ) { // Still needing to copy?
        // Carve out a chunk of work.  The counter wraps around so every
        // thread eventually tries to copy every slot repeatedly.

        // We "panic" if we have tried TWICE to copy every slot - and it still
        // has not happened.  i.e., twice some thread somewhere claimed they
        // would copy 'slot X' (by bumping _copyIdx) but they never claimed to
        // have finished (by bumping _copyDone).  Our choices become limited:
        // we can wait for the work-claimers to finish (and become a blocking
        // algorithm) or do the copy work ourselves.  Tiny tables with huge
        // thread counts trying to copy the table often 'panic'.
        if( panic_start == -1 ) { // No panic?
          copyidx = (int)_copyIdx;
          while( copyidx < (oldlen<<1) && // 'panic' check
                 !_copyIdxUpdater.compareAndSet(this,copyidx,copyidx+MIN_COPY_WORK) )
            copyidx = (int)_copyIdx;      // Re-read
          if( !(copyidx < (oldlen<<1)) )  // Panic!
            panic_start = copyidx;        // Record where we started to panic-copy
        }

        // We now know what to copy.  Try to copy.
        int workdone = 0;
        for( int i=0; i<MIN_COPY_WORK; i++ )
          if( copy_slot(topmap,(copyidx+i)&(oldlen-1),oldkvs,newkvs) ) // Made an oldtable slot go dead?
            workdone++;         // Yes!
        if( workdone > 0 )      // Report work-done occasionally
          copy_check_and_promote( topmap, oldkvs, workdone );// See if we can promote
        //for( int i=0; i<MIN_COPY_WORK; i++ )
        //  if( copy_slot(topmap,(copyidx+i)&(oldlen-1),oldkvs,newkvs) ) // Made an oldtable slot go dead?
        //    copy_check_and_promote( topmap, oldkvs, 1 );// See if we can promote

        copyidx += MIN_COPY_WORK;
        // Uncomment these next 2 lines to turn on incremental table-copy.
        // Otherwise this thread continues to copy until it is all done.
        if( !copy_all && panic_start == -1 ) // No panic?
          return;       // Then done copying after doing MIN_COPY_WORK
      }
      // Extra promotion check, in case another thread finished all copying
      // then got stalled before promoting.
      copy_check_and_promote( topmap, oldkvs, 0 );// See if we can promote
    }


    // --- copy_slot_and_check -----------------------------------------------
    // Copy slot 'idx' from the old table to the new table.  If this thread
    // confirmed the copy, update the counters and check for promotion.
    //
    // Returns the result of reading the volatile _newkvs, mostly as a
    // convenience to callers.  We come here with 1-shot copy requests
    // typically because the caller has found a Prime, and has not yet read
    // the _newkvs volatile - which must have changed from null-to-not-null
    // before any Prime appears.  So the caller needs to read the _newkvs
    // field to retry his operation in the new table, but probably has not
    // read it yet.
    private final Object[] copy_slot_and_check( NonBlockingIdentityHashMap topmap, Object[] oldkvs, int idx, Object should_help ) {
      assert chm(oldkvs) == this;
      Object[] newkvs = _newkvs; // VOLATILE READ
      // We're only here because the caller saw a Prime, which implies a
      // table-copy is in progress.
      assert newkvs != null;
      if( copy_slot(topmap,idx,oldkvs,_newkvs) )   // Copy the desired slot
        copy_check_and_promote(topmap, oldkvs, 1); // Record the slot copied
      // Generically help along any copy (except if called recursively from a helper)
      return (should_help == null) ? newkvs : topmap.help_copy(newkvs);
    }

    // --- copy_check_and_promote --------------------------------------------
    private final void copy_check_and_promote( NonBlockingIdentityHashMap topmap, Object[] oldkvs, int workdone ) {
      assert chm(oldkvs) == this;
      int oldlen = len(oldkvs);
      // We made a slot unusable and so did some of the needed copy work
      long copyDone = _copyDone;
      assert (copyDone+workdone) <= oldlen;
      if( workdone > 0 ) {
        while( !_copyDoneUpdater.compareAndSet(this,copyDone,copyDone+workdone) ) {
          copyDone = _copyDone; // Reload, retry
          assert (copyDone+workdone) <= oldlen;
        }
        //if( (10*copyDone/oldlen) != (10*(copyDone+workdone)/oldlen) )
        //System.out.print(" "+(copyDone+workdone)*100/oldlen+"%"+"_"+(_copyIdx*100/oldlen)+"%");
      }

      // Check for copy being ALL done, and promote.  Note that we might have
      // nested in-progress copies and manage to finish a nested copy before
      // finishing the top-level copy.  We only promote top-level copies.
      if( copyDone+workdone == oldlen && // Ready to promote this table?
          topmap._kvs == oldkvs && // Looking at the top-level table?
          // Attempt to promote
          topmap.CAS_kvs(oldkvs,_newkvs) ) {
        topmap._last_resize_milli = System.currentTimeMillis(); // Record resize time for next check
        //long nano = System.nanoTime();
        //System.out.println(" "+nano+" Promote table to "+len(_newkvs));
        //if( System.out != null ) System.out.print("]");
      }
    }

    // --- copy_slot ---------------------------------------------------------
    // Copy one K/V pair from oldkvs[i] to newkvs.  Returns true if we can
    // confirm that the new table guaranteed has a value for this old-table
    // slot.  We need an accurate confirmed-copy count so that we know when we
    // can promote (if we promote the new table too soon, other threads may
    // 'miss' on values not-yet-copied from the old table).  We don't allow
    // any direct updates on the new table, unless they first happened to the
    // old table - so that any transition in the new table from null to
    // not-null must have been from a copy_slot (or other old-table overwrite)
    // and not from a thread directly writing in the new table.  Thus we can
    // count null-to-not-null transitions in the new table.
    private boolean copy_slot( NonBlockingIdentityHashMap topmap, int idx, Object[] oldkvs, Object[] newkvs ) {
      // Blindly set the key slot from null to TOMBSTONE, to eagerly stop
      // fresh put's from inserting new values in the old table when the old
      // table is mid-resize.  We don't need to act on the results here,
      // because our correctness stems from box'ing the Value field.  Slamming
      // the Key field is a minor speed optimization.
      Object key;
      while( (key=key(oldkvs,idx)) == null )
        CAS_key(oldkvs,idx, null, TOMBSTONE);

      // ---
      // Prevent new values from appearing in the old table.
      // Box what we see in the old table, to prevent further updates.
      Object oldval = val(oldkvs,idx); // Read OLD table
      while( !(oldval instanceof Prime) ) {
        final Prime box = (oldval == null || oldval == TOMBSTONE) ? TOMBPRIME : new Prime(oldval);
        if( CAS_val(oldkvs,idx,oldval,box) ) { // CAS down a box'd version of oldval
          // If we made the Value slot hold a TOMBPRIME, then we both
          // prevented further updates here but also the (absent)
          // oldval is vaccuously available in the new table.  We
          // return with true here: any thread looking for a value for
          // this key can correctly go straight to the new table and
          // skip looking in the old table.
          if( box == TOMBPRIME )
            return true;
          // Otherwise we boxed something, but it still needs to be
          // copied into the new table.
          oldval = box;         // Record updated oldval
          break;                // Break loop; oldval is now boxed by us
        }
        oldval = val(oldkvs,idx); // Else try, try again
      }
      if( oldval == TOMBPRIME ) return false; // Copy already complete here!

      // ---
      // Copy the value into the new table, but only if we overwrite a null.
      // If another value is already in the new table, then somebody else
      // wrote something there and that write is happens-after any value that
      // appears in the old table.  If putIfMatch does not find a null in the
      // new table - somebody else should have recorded the null-not_null
      // transition in this copy.
      Object old_unboxed = ((Prime)oldval)._V;
      assert old_unboxed != TOMBSTONE;
      boolean copied_into_new = (putIfMatch(topmap, newkvs, key, old_unboxed, null) == null);

      // ---
      // Finally, now that any old value is exposed in the new table, we can
      // forever hide the old-table value by slapping a TOMBPRIME down.  This
      // will stop other threads from uselessly attempting to copy this slot
      // (i.e., it's a speed optimization not a correctness issue).
      while( !CAS_val(oldkvs,idx,oldval,TOMBPRIME) )
        oldval = val(oldkvs,idx);

      return copied_into_new;
    } // end copy_slot
  } // End of CHM


  // --- Snapshot ------------------------------------------------------------
  // The main class for iterating over the NBHM.  It "snapshots" a clean
  // view of the K/V array.
  private class SnapshotV implements Iterator<TypeV>, Enumeration<TypeV> {
    final Object[] _sskvs;
    public SnapshotV() {
      while( true ) {           // Verify no table-copy-in-progress
        Object[] topkvs = _kvs;
        CHM topchm = chm(topkvs);
        if( topchm._newkvs == null ) { // No table-copy-in-progress
          // The "linearization point" for the iteration.  Every key in this
          // table will be visited, but keys added later might be skipped or
          // even be added to a following table (also not iterated over).
          _sskvs = topkvs;
          break;
        }
        // Table copy in-progress - so we cannot get a clean iteration.  We
        // must help finish the table copy before we can start iterating.
        topchm.help_copy_impl(NonBlockingIdentityHashMap.this,topkvs,true);
      }
      // Warm-up the iterator
      next();
    }
    int length() { return len(_sskvs); }
    Object key(int idx) { return NonBlockingIdentityHashMap.key(_sskvs,idx); }
    private int _idx;              // Varies from 0-keys.length
    private Object _nextK, _prevK; // Last 2 keys found
    private TypeV  _nextV, _prevV; // Last 2 values found
    public boolean hasNext() { return _nextV != null; }
    public TypeV next() {
      // 'next' actually knows what the next value will be - it had to
      // figure that out last go-around lest 'hasNext' report true and
      // some other thread deleted the last value.  Instead, 'next'
      // spends all its effort finding the key that comes after the
      // 'next' key.
      if( _idx != 0 && _nextV == null ) throw new NoSuchElementException();
      _prevK = _nextK;          // This will become the previous key
      _prevV = _nextV;          // This will become the previous value
      _nextV = null;            // We have no more next-key
      // Attempt to set <_nextK,_nextV> to the next K,V pair.
      // _nextV is the trigger: stop searching when it is != null
      while( _idx<length() ) {  // Scan array
        _nextK = key(_idx++); // Get a key that definitely is in the set (for the moment!)
        if( _nextK != null && // Found something?
            _nextK != TOMBSTONE &&
            (_nextV=get(_nextK)) != null )
          break;                // Got it!  _nextK is a valid Key
      }                         // Else keep scanning
      return _prevV;            // Return current value.
    }
    public void remove() {
      if( _prevV == null ) throw new IllegalStateException();
      putIfMatch( NonBlockingIdentityHashMap.this, _sskvs, _prevK, TOMBSTONE, _prevV );
      _prevV = null;
    }

    public TypeV nextElement() { return next(); }
    public boolean hasMoreElements() { return hasNext(); }
  }

  /** Returns an enumeration of the values in this table.
   *  @return an enumeration of the values in this table
   *  @see #values()  */
  public Enumeration<TypeV> elements() { return new SnapshotV(); }

  // --- values --------------------------------------------------------------
  /** Returns a {@link Collection} view of the values contained in this map.
   *  The collection is backed by the map, so changes to the map are reflected
   *  in the collection, and vice-versa.  The collection supports element
   *  removal, which removes the corresponding mapping from this map, via the
   *  <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
   *  <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
   *  It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
   *
   *  <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator that
   *  will never throw {@link ConcurrentModificationException}, and guarantees
   *  to traverse elements as they existed upon construction of the iterator,
   *  and may (but is not guaranteed to) reflect any modifications subsequent
   *  to construction. */
  @Override
  public Collection<TypeV> values() {
    return new AbstractCollection<TypeV>() {
      @Override public void    clear   (          ) {        NonBlockingIdentityHashMap.this.clear        ( ); }
      @Override public int     size    (          ) { return NonBlockingIdentityHashMap.this.size         ( ); }
      @Override public boolean contains( Object v ) { return NonBlockingIdentityHashMap.this.containsValue(v); }
      @Override public Iterator<TypeV> iterator()   { return new SnapshotV(); }
    };
  }

  // --- keySet --------------------------------------------------------------
  private class SnapshotK implements Iterator<TypeK>, Enumeration<TypeK> {
    final SnapshotV _ss;
    public SnapshotK() { _ss = new SnapshotV(); }
    public void remove() { _ss.remove(); }
    public TypeK next() { _ss.next(); return (TypeK)_ss._prevK; }
    public boolean hasNext() { return _ss.hasNext(); }
    public TypeK nextElement() { return next(); }
    public boolean hasMoreElements() { return hasNext(); }
  }

  /** Returns an enumeration of the keys in this table.
   *  @return an enumeration of the keys in this table
   *  @see #keySet()  */
  public Enumeration<TypeK> keys() { return new SnapshotK(); }

  /** Returns a {@link Set} view of the keys contained in this map.  The set
   *  is backed by the map, so changes to the map are reflected in the set,
   *  and vice-versa.  The set supports element removal, which removes the
   *  corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
   *  <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
   *  <tt>clear</tt> operations.  It does not support the <tt>add</tt> or
   *  <tt>addAll</tt> operations.
   *
   *  <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator that
   *  will never throw {@link ConcurrentModificationException}, and guarantees
   *  to traverse elements as they existed upon construction of the iterator,
   *  and may (but is not guaranteed to) reflect any modifications subsequent
   *  to construction.  */
  @Override
  public Set<TypeK> keySet() {
    return new AbstractSet<TypeK> () {
      @Override public void    clear   (          ) {        NonBlockingIdentityHashMap.this.clear   ( ); }
      @Override public int     size    (          ) { return NonBlockingIdentityHashMap.this.size    ( ); }
      @Override public boolean contains( Object k ) { return NonBlockingIdentityHashMap.this.containsKey(k); }
      @Override public boolean remove  ( Object k ) { return NonBlockingIdentityHashMap.this.remove  (k) != null; }
      @Override public Iterator<TypeK> iterator()   { return new SnapshotK(); }
    };
  }


  // --- entrySet ------------------------------------------------------------
  // Warning: Each call to 'next' in this iterator constructs a new NBHMEntry.
  private class NBHMEntry extends AbstractEntry<TypeK,TypeV> {
    NBHMEntry( final TypeK k, final TypeV v ) { super(k,v); }
    public TypeV setValue(final TypeV val) {
      if( val == null ) throw new NullPointerException();
      _val = val;
      return put(_key, val);
    }
  }

  private class SnapshotE implements Iterator<Map.Entry<TypeK,TypeV>> {
    final SnapshotV _ss;
    public SnapshotE() { _ss = new SnapshotV(); }
    public void remove() { _ss.remove(); }
    public Map.Entry<TypeK,TypeV> next() { _ss.next(); return new NBHMEntry((TypeK)_ss._prevK,_ss._prevV); }
    public boolean hasNext() { return _ss.hasNext(); }
  }

  /** Returns a {@link Set} view of the mappings contained in this map.  The
   *  set is backed by the map, so changes to the map are reflected in the
   *  set, and vice-versa.  The set supports element removal, which removes
   *  the corresponding mapping from the map, via the
   *  <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>,
   *  <tt>retainAll</tt>, and <tt>clear</tt> operations.  It does not support
   *  the <tt>add</tt> or <tt>addAll</tt> operations.
   *
   *  <p>The view's <tt>iterator</tt> is a "weakly consistent" iterator
   *  that will never throw {@link ConcurrentModificationException},
   *  and guarantees to traverse elements as they existed upon
   *  construction of the iterator, and may (but is not guaranteed to)
   *  reflect any modifications subsequent to construction.
   *
   *  <p><strong>Warning:</strong> the iterator associated with this Set
   *  requires the creation of {@link java.util.Map.Entry} objects with each
   *  iteration.  The {@link NonBlockingIdentityHashMap} does not normally create or
   *  using {@link java.util.Map.Entry} objects so they will be created soley
   *  to support this iteration.  Iterating using {@link #keySet} or {@link
   *  #values} will be more efficient.
   */
  @Override
  public Set<Map.Entry<TypeK,TypeV>> entrySet() {
    return new AbstractSet<Map.Entry<TypeK,TypeV>>() {
      @Override public void    clear   (          ) {        NonBlockingIdentityHashMap.this.clear( ); }
      @Override public int     size    (          ) { return NonBlockingIdentityHashMap.this.size ( ); }
      @Override public boolean remove( final Object o ) {
        if( !(o instanceof Map.Entry)) return false;
        final Map.Entry<?,?> e = (Map.Entry<?,?>)o;
        return NonBlockingIdentityHashMap.this.remove(e.getKey(), e.getValue());
      }
      @Override public boolean contains(final Object o) {
        if( !(o instanceof Map.Entry)) return false;
        final Map.Entry<?,?> e = (Map.Entry<?,?>)o;
        TypeV v = get(e.getKey());
        return v.equals(e.getValue());
      }
      @Override public Iterator<Map.Entry<TypeK,TypeV>> iterator() { return new SnapshotE(); }
    };
  }

  // --- writeObject -------------------------------------------------------
  // Write a NBHM to a stream
  private void writeObject(java.io.ObjectOutputStream s) throws IOException  {
    s.defaultWriteObject();     // Nothing to write
    for( Object K : keySet() ) {
      final Object V = get(K);  // Do an official 'get'
      s.writeObject(K);         // Write the <TypeK,TypeV> pair
      s.writeObject(V);
    }
    s.writeObject(null);        // Sentinel to indicate end-of-data
    s.writeObject(null);
  }

  // --- readObject --------------------------------------------------------
  // Read a CHM from a stream
  private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
    s.defaultReadObject();      // Read nothing
    initialize(MIN_SIZE);
    for(;;) {
      final TypeK K = (TypeK) s.readObject();
      final TypeV V = (TypeV) s.readObject();
      if( K == null ) break;
      put(K,V);                 // Insert with an offical put
    }
  }

}
1354633
private static Map<String, String> generateMapChangeIds(List<String> newIDs) {
    Map<String, String> mapIds = new HashMap<String, String>();
    List<String> oldIds = HELM2NotationUtils.helm2notation.getPolymerAndGroupingIDs();

    Map<String, String> mapOldIds = new HashMap<String, String>();
    for (String oldID : oldIds) {
      mapOldIds.put(oldID, "");
    }
    for (String newId : newIDs) {
      if (mapOldIds.containsKey(newId)) {
        int i = 1;
        String type = newId.split("\\d")[0];

        while (mapOldIds.containsKey(type + i)) {
          i++;
        }
        mapIds.put(newId, type + i);
      }
    }

    return mapIds;

  }
314709
private Map<String, Set<String>> toExpandMap(String[] expands) {
    if (expands != null) {
      Map<String, Set<String>> expandMap = new HashMap<>();
      for (String expand : expands) {
        // validate
        Matcher matcher = PATTERN_EXPANDS.matcher(expand);
        if (!matcher.matches()) throw new MolgenisDataException("invalid expand value: " + expand);

        // for partial expands, create set
        expand = matcher.group(1);
        String attrsStr = matcher.group(2);
        Set<String> attrSet;
        if (attrsStr != null && !attrsStr.isEmpty()) {
          attrSet = new HashSet<>();
          for (String attr : attrsStr.split(";")) {
            attrSet.add(attr.toLowerCase());
          }
        } else attrSet = null;

        expandMap.put(expand.toLowerCase(), attrSet);
      }
      return expandMap;
    }
    return null;
  }
757230
def put_all(indexables)
      documents = indexables.map do |indexable|
        generate_document(indexable)
      end
      documents.reject!(&:empty?)

      publish_all(documents) unless documents.empty?
    end
500005
private static <K, N, S> int countMappingsInKeyGroup(final Map<N, Map<K, S>> keyGroupMap) {
		int count = 0;
		for (Map<K, S> namespaceMap : keyGroupMap.values()) {
			count += namespaceMap.size();
		}

		return count;
	}
1161536
public void setGroups(java.util.Collection<GroupSummary> groups) {
        if (groups == null) {
            this.groups = null;
            return;
        }

        this.groups = new java.util.ArrayList<GroupSummary>(groups);
    }
687409
def timestamps(self):
        ''''''
        timestamps = set()
        for series in self.groups.itervalues():
            timestamps |= set(series.timestamps)
        return sorted(list(timestamps))
484414
public void appendBatchWith(List<Card> groups) {
        if (mGroupBasicAdapter != null) {
            insertBatchWith(mGroupBasicAdapter.getGroups().size(), groups);
        }
    }
177207
@Override
  public void putAll(Map<? extends TypeK, ? extends TypeV> m) {
    for (Map.Entry<? extends TypeK, ? extends TypeV> e : m.entrySet())
      put(e.getKey(), e.getValue());
  }

  /** Removes all of the mappings from this map. */
  @Override
  public void clear() {         // Smack a new empty table down
    Object[] newkvs = new NonBlockingHashMap(MIN_SIZE)._kvs;
    while( !CAS_kvs(_kvs,newkvs) ) // Spin until the clear works
      ;
  }

  /** Returns <tt>true</tt> if this Map maps one or more keys to the specified
   *  value.  <em>Note</em>: This method requires a full internal traversal of the
   *  hash table and is much slower than {@link #containsKey}.
   *  @param val value whose presence in this map is to be tested
   *  @return <tt>true</tt> if this map maps one or more keys to the specified value
   *  @throws NullPointerException if the specified value is null */
  @Override
  public boolean containsValue( final Object val ) {
    if( val == null ) throw new NullPointerException();
    for( TypeV V : values() )
      if( V == val || V.equals(val) )
        return true;
    return false;
  }

  // This function is supposed to do something for Hashtable, and the JCK
  // tests hang until it gets called... by somebody ... for some reason,
  // any reason....
  protected void rehash() {
  }

  /**
   * Creates a shallow copy of this hashtable. All the structure of the
   * hashtable itself is copied, but the keys and values are not cloned.
   * This is a relatively expensive operation.
   *
   * @return  a clone of the hashtable.
   */
  @Override
  public Object clone() {
    try {
      // Must clone, to get the class right; NBHM might have been
      // extended so it would be wrong to just make a new NBHM.
      NonBlockingHashMap<TypeK,TypeV> t = (NonBlockingHashMap<TypeK,TypeV>) super.clone();
      // But I don't have an atomic clone operation - the underlying _kvs
      // structure is undergoing rapid change.  If I just clone the _kvs
      // field, the CHM in _kvs[0] won't be in sync.
      //
      // Wipe out the cloned array (it was shallow anyways).
      t.clear();
      // Now copy sanely
      for( TypeK K : keySet() ) {
        final TypeV V = get(K);  // Do an official 'get'
        t.put(K,V);
      }
      return t;
    } catch (CloneNotSupportedException e) {
      // this shouldn't happen, since we are Cloneable
      throw new InternalError();
    }
  }

  /**
   * Returns a string representation of this map.  The string representation
   * consists of a list of key-value mappings in the order returned by the
   * map's <tt>entrySet</tt> view's iterator, enclosed in braces
   * (<tt>"{}"</tt>).  Adjacent mappings are separated by the characters
   * <tt>", "</tt> (comma and space).  Each key-value mapping is rendered as
   * the key followed by an equals sign (<tt>"="</tt>) followed by the
   * associated value.  Keys and values are converted to strings as by
   * {@link String#valueOf(Object)}.
   *
   * @return a string representation of this map
   */
  @Override
  public String toString() {
    Iterator<Entry<TypeK,TypeV>> i = entrySet().iterator();
    if( !i.hasNext())
      return "{}";

    StringBuilder sb = new StringBuilder();
    sb.append('{');
    for (;;) {
      Entry<TypeK,TypeV> e = i.next();
      TypeK key = e.getKey();
      TypeV value = e.getValue();
      sb.append(key   == this ? "(this Map)" : key);
      sb.append('=');
      sb.append(value == this ? "(this Map)" : value);
      if( !i.hasNext())
        return sb.append('}').toString();
      sb.append(", ");
    }
  }

  // --- keyeq ---------------------------------------------------------------
  // Check for key equality.  Try direct pointer compare first, then see if
  // the hashes are unequal (fast negative test) and finally do the full-on
  // 'equals' v-call.
  private static boolean keyeq( Object K, Object key, int[] hashes, int hash, int fullhash ) {
    return
      K==key ||                 // Either keys match exactly OR
      // hash exists and matches?  hash can be zero during the install of a
      // new key/value pair.
      ((hashes[hash] == 0 || hashes[hash] == fullhash) &&
       // Do not call the users' "equals()" call with a Tombstone, as this can
       // surprise poorly written "equals()" calls that throw exceptions
       // instead of simply returning false.
       K != TOMBSTONE &&        // Do not call users' equals call with a Tombstone
       // Do the match the hard way - with the users' key being the loop-
       // invariant "this" pointer.  I could have flipped the order of
       // operands (since equals is commutative), but I'm making mega-morphic
       // v-calls in a reprobing loop and nailing down the 'this' argument
       // gives both the JIT and the hardware a chance to prefetch the call target.
       key.equals(K));          // Finally do the hard match
  }
442960
public static <K, V> Map<K, V> zip(Collection<K> keys, Collection<V> values) {
		if (isEmpty(keys) || isEmpty(values)) {
			return null;
		}

		final List<K> keyList = new ArrayList<K>(keys);
		final List<V> valueList = new ArrayList<V>(values);

		final int size = Math.min(keys.size(), values.size());
		final Map<K, V> map = new HashMap<K, V>((int) (size / 0.75));
		for (int i = 0; i < size; i++) {
			map.put(keyList.get(i), valueList.get(i));
		}

		return map;
	}
715802
private void compactGroups() {
    for (int i = 0; i < groups.size(); i++) {
      List<Segment> group = groups.get(i);
      List<OffsetPredicate> groupPredicates = predicates.get(i);
      Segment segment = compactGroup(group, groupPredicates);
      mergeReleased(group, groupPredicates, segment);
      deleteGroup(group);
    }
  }
867844
def _maybe_restore_empty_groups(self, combined):
        
        if (self._full_index is not None and
                self._group.name in combined.dims):
            indexers = {self._group.name: self._full_index}
            combined = combined.reindex(**indexers)
        return combined
319326
public static <K, V> Multimap<K, V> zipToMap(List<K> keys, List<V> values)
    {
        if (keys.isEmpty() || values.isEmpty()) {
            return null;
        }

        Iterator<K> keyIter = keys.iterator();
        Iterator<V> valueIter = values.iterator();
        ArrayListMultimap<K, V> result = ArrayListMultimap.create();

        while (keyIter.hasNext() && valueIter.hasNext()) {
            result.put(keyIter.next(), valueIter.next());
        }

        // In case there are more values than keys, assign the rest of the
        // values to the first key
        K firstKey = keys.get(0);
        while (valueIter.hasNext()) {
            result.put(firstKey, valueIter.next());
        }

        return result;
    }
1370410
public void setSlotSharingGroup(SlotSharingGroup grp) {
		if (this.slotSharingGroup != null) {
			this.slotSharingGroup.removeVertexFromGroup(id);
		}

		this.slotSharingGroup = grp;
		if (grp != null) {
			grp.addVertexToGroup(id);
		}
	}
1119460
def flatMap(self, f, preservesPartitioning=False):
        
        return self.mapPartitions(
            lambda p: (e for pp in p for e in f(pp)),
            preservesPartitioning,
        )