Exemplo n.º 1
0
  @Override
  public V remove(Object key) {
    if (key == null) {
      return null;
    }

    V priorValue = null;
    int bucket = bucket(key, _table.length);

    if (_table[bucket] == null) {
      // Nothing to do
    } else if (_table[bucket] instanceof ChainedEntry) {
      // The front of the bucket is a ChainedEntry, so we need to walk the chain and splice out the
      // link
      ChainedEntry<V> previousLink = null;
      ChainedEntry<V> currentLink = (ChainedEntry<V>) _table[bucket];

      while (true) {
        if (keyMatches(key, currentLink._entry)) {
          // We have a match, so splice out the link
          priorValue = currentLink._entry;
          if (previousLink == null) {
            // There's no prior link, so pull the next object directly into the table
            _table[bucket] = currentLink._next;
          } else {
            // There's a prior link, so just splice out the current one
            previousLink._next = currentLink._next;
          }
          break;
        } else if (currentLink._next instanceof ChainedEntry) {
          // Just
          previousLink = currentLink;
          currentLink = (ChainedEntry<V>) currentLink._next;
        } else {
          // The next link in the chain is a direct entry.  If it matches the key we're looking
          // for, we need to remove the current link, as it's no longer necessary, and set
          // the _next pointer (if any) of the prior link to point directly to the current link's
          // entry
          if (keyMatches(key, (V) currentLink._next)) {
            priorValue = (V) currentLink._next;
            if (previousLink == null) {
              _table[bucket] = currentLink._entry;
            } else {
              previousLink._next = currentLink._entry;
            }
          }
          break;
        }
      }
    } else {
      // The entry is directly in _table, so just null it out
      priorValue = (V) _table[bucket];
      _table[bucket] = null;
    }

    if (priorValue != null) {
      _size--;
    }
    return priorValue;
  }
Exemplo n.º 2
0
  public V putImpl(K key, V value, Object[] table, boolean resizeIfNecessary) {
    if (key == null) {
      throw new IllegalArgumentException(
          "Cannot add a value with a null key to a DerivedKeyHashMap");
    }

    if (value == null) {
      throw new IllegalArgumentException("Cannot add a null value to a DerivedKeyHashMap");
    }

    V priorValue = null;
    int bucket = bucket(key, table.length);
    if (table[bucket] == null) {
      table[bucket] = value;
    } else if (table[bucket] instanceof ChainedEntry) {
      // The front of the bucket is a ChainedEntry, so we need to walk the chain
      ChainedEntry<V> lastChain = (ChainedEntry<V>) table[bucket];
      while (true) {
        if (keyMatches(key, lastChain._entry)) {
          // If the entry of the chain directly matches our value's key, then update it in place
          priorValue = lastChain._entry;
          lastChain._entry = value;
          break;
        } else if (lastChain._next instanceof ChainedEntry) {
          // If the entry doesn't match and the next object is another chain entry, keep walking the
          // chain
          lastChain = (ChainedEntry<V>) lastChain._next;
        } else {
          // If the next link in the chain isn't another chain link, either update the value pointer
          // directly,
          // if it matches this value's key, or
          if (keyMatches(key, (V) lastChain._next)) {
            priorValue = (V) lastChain._next;
            lastChain._next = value;
          } else {
            ChainedEntry<V> newChain = new ChainedEntry<V>((V) lastChain._next, value);
            lastChain._next = newChain;
          }
          break;
        }
      }
    } else {
      // The entry is directly in _table, so if the existing value there matches this key, overwrite
      // it
      // Otherwise, chain the new value in
      if (keyMatches(key, (V) table[bucket])) {
        priorValue = (V) table[bucket];
        table[bucket] = value;
      } else {
        table[bucket] = new ChainedEntry<V>((V) table[bucket], value);
      }
    }

    return priorValue;
  }
Exemplo n.º 3
0
 @Override
 protected void addEntry(int bucket, int key, long value, BucketEntry next) {
   ChainedEntry newEntry = new ChainedEntry(key, value, next);
   this._buckets[bucket] = newEntry;
   newEntry.addBefore(entryChainHeader);
   ++_size;
   if (removeEldestEntry()) {
     ChainedEntry eldest = entryChainHeader.next;
     remove(eldest.key);
   } else {
     if (_size > _threshold) {
       resize(2 * _buckets.length);
     }
   }
 }
Exemplo n.º 4
0
 /** Inserts this entry before the specified existing entry in the list. */
 private void addBefore(ChainedEntry existingEntry) {
   next = existingEntry;
   prev = existingEntry.prev;
   prev.next = this;
   next.prev = this;
 }
Exemplo n.º 5
0
 /** Removes this entry from the linked list. */
 private void remove() {
   prev.next = next;
   next.prev = prev;
   prev = null;
   next = null;
 }
Exemplo n.º 6
0
 private ChainedEntry initEntryChain() {
   ChainedEntry header = new ChainedEntry(-1, -1, null);
   header.prev = header.next = header;
   return header;
 }