Example #1
0
  /**
   * Ensures that the hash table has sufficient capacity to store the specified number of mappings,
   * with room to grow. If not, it increases the capacity as appropriate. Like doubleCapacity, this
   * method moves existing entries to new buckets as appropriate. Unlike doubleCapacity, this method
   * can grow the table by factors of 2^n for n > 1. Hopefully, a single call to this method will be
   * faster than multiple calls to doubleCapacity.
   *
   * <p>This method is called only by putAll.
   */
  private void ensureCapacity(int numMappings) {
    int newCapacity = roundUpToPowerOfTwo(capacityForInitSize(numMappings));
    HashtableEntry<K, V>[] oldTable = table;
    int oldCapacity = oldTable.length;
    if (newCapacity <= oldCapacity) {
      return;
    }

    rehash(); // Does nothing!!

    if (newCapacity == oldCapacity * 2) {
      doubleCapacity();
      return;
    }

    // We're growing by at least 4x, rehash in the obvious way
    HashtableEntry<K, V>[] newTable = makeTable(newCapacity);
    if (size != 0) {
      int newMask = newCapacity - 1;
      for (int i = 0; i < oldCapacity; i++) {
        for (HashtableEntry<K, V> e = oldTable[i]; e != null; ) {
          HashtableEntry<K, V> oldNext = e.next;
          int newIndex = e.hash & newMask;
          HashtableEntry<K, V> newNext = newTable[newIndex];
          newTable[newIndex] = e;
          e.next = newNext;
          e = oldNext;
        }
      }
    }
  }