Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
  * Copyright (C) 2008 The Guava Authors
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package com.google.common.collect;
 
 import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
 
 
Implementation of ImmutableMap with two or more entries.

Author(s):
Jesse Wilson
Kevin Bourrillion
Gregory Kick
 
 @GwtCompatible(serializable = true, emulated = true)
 final class RegularImmutableMap<K, V> extends ImmutableMap<K, V> {
 
   // entries in insertion order
   private final transient ImmutableMapEntry<K, V>[] entries;
   // array of linked lists of entries
   private final transient ImmutableMapEntry<K, V>[] table;
   // 'and' with an int to get a table index
   private final transient int mask;
   
   RegularImmutableMap(TerminalEntry<?, ?>... theEntries) {
     this(theEntries.lengththeEntries);
   }
  
  
Constructor for RegularImmutableMap that takes as input an array of TerminalEntry entries. Assumes that these entries have already been checked for null.

This allows reuse of the entry objects from the array in the actual implementation.

 
   RegularImmutableMap(int size, TerminalEntry<?, ?>[] theEntries) {
      = createEntryArray(size);
     int tableSize = Hashing.closedTableSize(size);
      = createEntryArray(tableSize);
      = tableSize - 1;
     for (int entryIndex = 0; entryIndex < sizeentryIndex++) {
       @SuppressWarnings("unchecked")
       TerminalEntry<K, V> entry = (TerminalEntry<K, V>) theEntries[entryIndex];
       K key = entry.getKey();
       int tableIndex = Hashing.smear(key.hashCode()) & ;
       @Nullable ImmutableMapEntry<K, V> existing = [tableIndex];
       // prepend, not append, so the entries can be immutable
       ImmutableMapEntry<K, V> newEntry = (existing == null)
           ? entry
           : new NonTerminalMapEntry<K, V>(entryexisting);
       [tableIndex] = newEntry;
       [entryIndex] = newEntry;
       checkNoConflictInBucket(keynewEntryexisting);
     }
   }
  
  
Constructor for RegularImmutableMap that makes no assumptions about the input entries.
 
   RegularImmutableMap(Entry<?, ?>[] theEntries) {
     int size = theEntries.length;
      = createEntryArray(size);
     int tableSize = Hashing.closedTableSize(size);
      = createEntryArray(tableSize);
      = tableSize - 1;
     for (int entryIndex = 0; entryIndex < sizeentryIndex++) {
       @SuppressWarnings("unchecked"// all our callers carefully put in only Entry<K, V>s
       Entry<K, V> entry = (Entry<K, V>) theEntries[entryIndex];
       K key = entry.getKey();
       V value = entry.getValue();
       checkEntryNotNull(keyvalue);
       int tableIndex = Hashing.smear(key.hashCode()) & ;
       @Nullable ImmutableMapEntry<K, V> existing = [tableIndex];
       // prepend, not append, so the entries can be immutable
       ImmutableMapEntry<K, V> newEntry = (existing == null)
           ? new TerminalEntry<K, V>(keyvalue)
           : new NonTerminalMapEntry<K, V>(keyvalueexisting);
       [tableIndex] = newEntry;
       [entryIndex] = newEntry;
       checkNoConflictInBucket(keynewEntryexisting);
     }
   }
  private void checkNoConflictInBucket(
      K keyImmutableMapEntry<K, V> entryImmutableMapEntry<K, V> bucketHead) {
    for (; bucketHead != nullbucketHead = bucketHead.getNextInKeyBucket()) {
      checkNoConflict(!key.equals(bucketHead.getKey()), "key"entrybucketHead);
    }
  }
  
  private static final class NonTerminalMapEntry<K, V> extends ImmutableMapEntry<K, V> {
    private final ImmutableMapEntry<K, V> nextInKeyBucket;
    NonTerminalMapEntry(K key, V valueImmutableMapEntry<K, V> nextInKeyBucket) {
      super(keyvalue);
      this. = nextInKeyBucket;
    }
    NonTerminalMapEntry(ImmutableMapEntry<K, V> contentsImmutableMapEntry<K, V> nextInKeyBucket) {
      super(contents);
      this. = nextInKeyBucket;
    }
    @Override
      return ;
    }
    @Override
    @Nullable
      return null;
    }
    
  }

  
Closed addressing tends to perform well even with high load factors. Being conservative here ensures that the table is still likely to be relatively sparse (hence it misses fast) while saving space.
  private static final double MAX_LOAD_FACTOR = 1.2;

  
Creates an ImmutableMapEntry array to hold parameterized entries. The result must never be upcast back to ImmutableMapEntry[] (or Object[], etc.), or allowed to escape the class.
  @SuppressWarnings("unchecked"// Safe as long as the javadocs are followed
  private ImmutableMapEntry<K, V>[] createEntryArray(int size) {
    return new ImmutableMapEntry[size];
  }
  @Override public V get(@Nullable Object key) {
    if (key == null) {
      return null;
    }
    int index = Hashing.smear(key.hashCode()) & ;
    for (ImmutableMapEntry<K, V> entry = [index];
        entry != null;
        entry = entry.getNextInKeyBucket()) {
      K candidateKey = entry.getKey();
      /*
       * Assume that equals uses the == optimization when appropriate, and that
       * it would check hash codes as an optimization when appropriate. If we
       * did these things, it would just make things worse for the most
       * performance-conscious users.
       */
      if (key.equals(candidateKey)) {
        return entry.getValue();
      }
    }
    return null;
  }
  public int size() {
    return .;
  }
  
  @Override boolean isPartialView() {
    return false;
  }
    return new EntrySet();
  }
  @SuppressWarnings("serial"// uses writeReplace(), not default serialization
  private class EntrySet extends ImmutableMapEntrySet<K, V> {
    @Override ImmutableMap<K, V> map() {
      return RegularImmutableMap.this;
    }
    @Override
    public UnmodifiableIterator<Entry<K, V>> iterator() {
      return asList().iterator();
    }
    @Override
    ImmutableList<Entry<K, V>> createAsList() {
      return new RegularImmutableAsList<Entry<K, V>>(this);
    }
  }
  // This class is never actually serialized directly, but we have to make the
  // warning go away (and suppressing would suppress for all nested classes too)
  private static final long serialVersionUID = 0;
New to GrepCode? Check out our FAQ X