예제 #1
0
 /**
  * Reduces the size of the backing arrays to be the specified capacity or less. If the capacity is
  * already less, nothing is done. If the map contains more items than the specified capacity, the
  * next highest power of two capacity is used instead.
  */
 public void shrink(int maximumCapacity) {
   if (maximumCapacity < 0)
     throw new IllegalArgumentException("maximumCapacity must be >= 0: " + maximumCapacity);
   if (size > maximumCapacity) maximumCapacity = size;
   if (capacity <= maximumCapacity) return;
   maximumCapacity = MathUtils.nextPowerOfTwo(maximumCapacity);
   resize(maximumCapacity);
 }
예제 #2
0
 /**
  * Clears the map and reduces the size of the backing arrays to be the specified capacity if they
  * are larger.
  */
 public void clear(int maximumCapacity) {
   if (capacity <= maximumCapacity) {
     clear();
     return;
   }
   hasZeroValue = false;
   size = 0;
   resize(maximumCapacity);
 }
예제 #3
0
 private void putStash(int key, float value) {
   if (stashSize == stashCapacity) {
     // Too many pushes occurred and the stash is full, increase the table size.
     resize(capacity << 1);
     put(key, value);
     return;
   }
   // Store key in the stash.
   int index = capacity + stashSize;
   keyTable[index] = key;
   valueTable[index] = value;
   stashSize++;
   size++;
 }
예제 #4
0
  /** Skips checks for existing keys. */
  private void putResize(int key, float value) {
    if (key == 0) {
      zeroValue = value;
      hasZeroValue = true;
      return;
    }

    // Check for empty buckets.
    int index1 = key & mask;
    int key1 = keyTable[index1];
    if (key1 == EMPTY) {
      keyTable[index1] = key;
      valueTable[index1] = value;
      if (size++ >= threshold) resize(capacity << 1);
      return;
    }

    int index2 = hash2(key);
    int key2 = keyTable[index2];
    if (key2 == EMPTY) {
      keyTable[index2] = key;
      valueTable[index2] = value;
      if (size++ >= threshold) resize(capacity << 1);
      return;
    }

    int index3 = hash3(key);
    int key3 = keyTable[index3];
    if (key3 == EMPTY) {
      keyTable[index3] = key;
      valueTable[index3] = value;
      if (size++ >= threshold) resize(capacity << 1);
      return;
    }

    push(key, value, index1, key1, index2, key2, index3, key3);
  }
예제 #5
0
 /**
  * Increases the size of the backing array to accommodate the specified number of additional
  * items. Useful before adding many items to avoid multiple backing array resizes.
  */
 public void ensureCapacity(int additionalCapacity) {
   int sizeNeeded = size + additionalCapacity;
   if (sizeNeeded >= threshold)
     resize(MathUtils.nextPowerOfTwo((int) Math.ceil(sizeNeeded / loadFactor)));
 }
예제 #6
0
  private void push(
      int insertKey,
      float insertValue,
      int index1,
      int key1,
      int index2,
      int key2,
      int index3,
      int key3) {
    int[] keyTable = this.keyTable;
    float[] valueTable = this.valueTable;
    int mask = this.mask;

    // Push keys until an empty bucket is found.
    int evictedKey;
    float evictedValue;
    int i = 0, pushIterations = this.pushIterations;
    do {
      // Replace the key and value for one of the hashes.
      switch (MathUtils.random(2)) {
        case 0:
          evictedKey = key1;
          evictedValue = valueTable[index1];
          keyTable[index1] = insertKey;
          valueTable[index1] = insertValue;
          break;
        case 1:
          evictedKey = key2;
          evictedValue = valueTable[index2];
          keyTable[index2] = insertKey;
          valueTable[index2] = insertValue;
          break;
        default:
          evictedKey = key3;
          evictedValue = valueTable[index3];
          keyTable[index3] = insertKey;
          valueTable[index3] = insertValue;
          break;
      }

      // If the evicted key hashes to an empty bucket, put it there and stop.
      index1 = evictedKey & mask;
      key1 = keyTable[index1];
      if (key1 == EMPTY) {
        keyTable[index1] = evictedKey;
        valueTable[index1] = evictedValue;
        if (size++ >= threshold) resize(capacity << 1);
        return;
      }

      index2 = hash2(evictedKey);
      key2 = keyTable[index2];
      if (key2 == EMPTY) {
        keyTable[index2] = evictedKey;
        valueTable[index2] = evictedValue;
        if (size++ >= threshold) resize(capacity << 1);
        return;
      }

      index3 = hash3(evictedKey);
      key3 = keyTable[index3];
      if (key3 == EMPTY) {
        keyTable[index3] = evictedKey;
        valueTable[index3] = evictedValue;
        if (size++ >= threshold) resize(capacity << 1);
        return;
      }

      if (++i == pushIterations) break;

      insertKey = evictedKey;
      insertValue = evictedValue;
    } while (true);

    putStash(evictedKey, evictedValue);
  }
예제 #7
0
  public void put(int key, float value) {
    if (key == 0) {
      zeroValue = value;
      if (!hasZeroValue) {
        hasZeroValue = true;
        size++;
      }
      return;
    }

    int[] keyTable = this.keyTable;

    // Check for existing keys.
    int index1 = key & mask;
    int key1 = keyTable[index1];
    if (key == key1) {
      valueTable[index1] = value;
      return;
    }

    int index2 = hash2(key);
    int key2 = keyTable[index2];
    if (key == key2) {
      valueTable[index2] = value;
      return;
    }

    int index3 = hash3(key);
    int key3 = keyTable[index3];
    if (key == key3) {
      valueTable[index3] = value;
      return;
    }

    // Update key in the stash.
    for (int i = capacity, n = i + stashSize; i < n; i++) {
      if (key == keyTable[i]) {
        valueTable[i] = value;
        return;
      }
    }

    // Check for empty buckets.
    if (key1 == EMPTY) {
      keyTable[index1] = key;
      valueTable[index1] = value;
      if (size++ >= threshold) resize(capacity << 1);
      return;
    }

    if (key2 == EMPTY) {
      keyTable[index2] = key;
      valueTable[index2] = value;
      if (size++ >= threshold) resize(capacity << 1);
      return;
    }

    if (key3 == EMPTY) {
      keyTable[index3] = key;
      valueTable[index3] = value;
      if (size++ >= threshold) resize(capacity << 1);
      return;
    }

    push(key, value, index1, key1, index2, key2, index3, key3);
  }