Example #1
0
  /**
   * Returns the long associated with the String or 0 if there is no long associated with the
   * string. If newValue is not equal to 0 then this becomes the new value associated with the
   * string.
   *
   * @param str the String.
   * @param newValue if not equal to 0, the new value to be associated with the string.
   * @return the long currently associated with the String or 0 if there is no long associated with
   *     the string.
   * @throws IOException if an I/O error occurs or the hash table is full.
   */
  public long getAndPut(String str, long newValue) throws IOException {
    if (str == null) {
      throw new IllegalArgumentException("str is null");
    }

    if (newValue == 0) {
      Long l = cache.get(str);
      if (l != null) {
        return l.longValue();
      }
    }

    int hashCode = str.hashCode();
    int startBucket = calcBucket(hashCode);
    int bucket = startBucket;
    long value;

    // Try buckets until we find the correct string or an empty bucket.
    while ((value = getValue(bucket)) != 0) {
      // Check the hash code.
      long offset = (long) bucket * 4;
      if (hashCode == hashFile.getInt(offset)) {
        // Fetch the string and compare with the target string.
        String bucketStr = readString(hashFile.getUInt(offset + 1));
        if (str.equals(bucketStr)) {
          if (newValue != 0) {
            hashFile.putLong((long) bucket * 2 + 1, newValue);
            // Add the new value to the cache.
            cache.put(str, newValue);
          } else {
            // Add the value to the cache.
            cache.put(str, value);
          }
          return value;
        }
      }

      // Try the next bucket.
      bucket = (bucket + 1) % nrBuckets;
      if (bucket == startBucket) {
        throw new IOException("Hash table full");
      }
    }

    if (newValue != 0) {
      // Add the new value to the cache.
      cache.put(str, newValue);

      // Add a new hash bucket.
      long bucketOffset = (long) bucket * 4;
      hashFile.putInt(bucketOffset, hashCode);
      hashFile.putUInt(bucketOffset + 1, writeString(str));
      hashFile.putLong((long) bucket * 2 + 1, newValue);
      ++nrUsedBuckets;

      if (nrUsedBuckets >= (int) (nrBuckets * REHASH_LIMIT)) {
        rehash(findPrime(nrBuckets));
      }
    }

    return 0;
  }