Skip to content

Commit

Permalink
Simplify the ImmutableMapEntry shared code by making the base Immutab…
Browse files Browse the repository at this point in the history
…leMapEntry class terminal and sharing the subclasses for non-terminal nodes in the hash table.

-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=89319446
  • Loading branch information
lowasser authored and cgdecker committed Mar 23, 2015
1 parent 8d6c684 commit 7af428e
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 187 deletions.
4 changes: 1 addition & 3 deletions guava/src/com/google/common/collect/ImmutableBiMap.java
Expand Up @@ -18,10 +18,8 @@

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableMap.Builder;

import java.util.Map;
import java.util.Map.Entry;

/**
* An immutable {@link BiMap} with reliable user-specified iteration order. Does
Expand Down Expand Up @@ -249,7 +247,7 @@ public static <K, V> ImmutableBiMap<K, V> copyOf(
Entry<K, V> entry = (Entry<K, V>) entryArray[0];
return of(entry.getKey(), entry.getValue());
default:
return new RegularImmutableBiMap<K, V>(entryArray);
return new RegularImmutableBiMap<K, V>(entryArray.length, entryArray);
}
}

Expand Down
13 changes: 6 additions & 7 deletions guava/src/com/google/common/collect/ImmutableMap.java
Expand Up @@ -20,7 +20,6 @@

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableMapEntry.TerminalEntry;

import java.io.Serializable;
import java.util.Collections;
Expand Down Expand Up @@ -116,8 +115,8 @@ public static <K, V> ImmutableMap<K, V> of(
* <p>A call to {@link Map.Entry#setValue} on the returned entry will always
* throw {@link UnsupportedOperationException}.
*/
static <K, V> TerminalEntry<K, V> entryOf(K key, V value) {
return new TerminalEntry<K, V>(key, value);
static <K, V> ImmutableMapEntry<K, V> entryOf(K key, V value) {
return new ImmutableMapEntry<K, V>(key, value);
}

/**
Expand Down Expand Up @@ -157,7 +156,7 @@ static void checkNoConflict(boolean safe, String conflictDescription,
* @since 2.0 (imported from Google Collections Library)
*/
public static class Builder<K, V> {
TerminalEntry<K, V>[] entries;
ImmutableMapEntry<K, V>[] entries;
int size;

/**
Expand All @@ -170,7 +169,7 @@ public Builder() {

@SuppressWarnings("unchecked")
Builder(int initialCapacity) {
this.entries = new TerminalEntry[initialCapacity];
this.entries = new ImmutableMapEntry[initialCapacity];
this.size = 0;
}

Expand All @@ -187,7 +186,7 @@ private void ensureCapacity(int minCapacity) {
*/
public Builder<K, V> put(K key, V value) {
ensureCapacity(size + 1);
TerminalEntry<K, V> entry = entryOf(key, value);
ImmutableMapEntry<K, V> entry = entryOf(key, value);
// don't inline this: we want to fail atomically if key or value is null
entries[size++] = entry;
return this;
Expand Down Expand Up @@ -302,7 +301,7 @@ public static <K, V> ImmutableMap<K, V> copyOf(
Entry<K, V> onlyEntry = (Entry<K, V>) entryArray[0];
return of(onlyEntry.getKey(), onlyEntry.getValue());
default:
return new RegularImmutableMap<K, V>(entryArray);
return new RegularImmutableMap<K, V>(entryArray.length, entryArray);
}
}

Expand Down
54 changes: 42 additions & 12 deletions guava/src/com/google/common/collect/ImmutableMapEntry.java
Expand Up @@ -27,11 +27,14 @@
* hash buckets for the key and the value. This allows reuse in {@link RegularImmutableMap} and
* {@link RegularImmutableBiMap}, which don't have to recopy the entries created by their
* {@code Builder} implementations.
*
* This base implementation has no key or value pointers, so instances of ImmutableMapEntry
* (but not its subclasses) can be reused when copied from one ImmutableMap to another.
*
* @author Louis Wasserman
*/
@GwtIncompatible("unnecessary")
abstract class ImmutableMapEntry<K, V> extends ImmutableEntry<K, V> {
class ImmutableMapEntry<K, V> extends ImmutableEntry<K, V> {
/**
* Creates an {@code ImmutableMapEntry} array to hold parameterized entries. The
* result must never be upcast back to ImmutableMapEntry[] (or Object[], etc.), or
Expand All @@ -53,30 +56,57 @@ static <K, V> ImmutableMapEntry<K, V>[] createEntryArray(int size) {
}

@Nullable
abstract ImmutableMapEntry<K, V> getNextInKeyBucket();
ImmutableMapEntry<K, V> getNextInKeyBucket() {
return null;
}

@Nullable
abstract ImmutableMapEntry<K, V> getNextInValueBucket();

static final class TerminalEntry<K, V> extends ImmutableMapEntry<K, V> {
TerminalEntry(ImmutableMapEntry<K, V> contents) {
super(contents);
}
ImmutableMapEntry<K, V> getNextInValueBucket() {
return null;
}

/**
* Returns true if this entry has no bucket links and can safely be reused as a terminal
* entry in a bucket in another map.
*/
boolean isReusable() {
return true;
}

static class NonTerminalImmutableMapEntry<K, V> extends ImmutableMapEntry<K, V> {
private final transient ImmutableMapEntry<K, V> nextInKeyBucket;

TerminalEntry(K key, V value) {
NonTerminalImmutableMapEntry(K key, V value, ImmutableMapEntry<K, V> nextInKeyBucket) {
super(key, value);
this.nextInKeyBucket = nextInKeyBucket;
}

@Override
@Nullable
ImmutableMapEntry<K, V> getNextInKeyBucket() {
return null;
final ImmutableMapEntry<K, V> getNextInKeyBucket() {
return nextInKeyBucket;
}

@Override
final boolean isReusable() {
return false;
}
}

static final class NonTerminalImmutableBiMapEntry<K, V>
extends NonTerminalImmutableMapEntry<K, V> {
private final transient ImmutableMapEntry<K, V> nextInValueBucket;

NonTerminalImmutableBiMapEntry(K key, V value, ImmutableMapEntry<K, V> nextInKeyBucket,
ImmutableMapEntry<K, V> nextInValueBucket) {
super(key, value, nextInKeyBucket);
this.nextInValueBucket = nextInValueBucket;
}

@Override
@Nullable
ImmutableMapEntry<K, V> getNextInValueBucket() {
return null;
return nextInValueBucket;
}
}
}
5 changes: 1 addition & 4 deletions guava/src/com/google/common/collect/ImmutableSortedMap.java
Expand Up @@ -23,14 +23,11 @@

import com.google.common.annotations.Beta;
import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.ImmutableMapEntry.TerminalEntry;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.SortedMap;
import java.util.TreeMap;
Expand Down Expand Up @@ -108,7 +105,7 @@ private static <K, V> ImmutableSortedMap<K, V> of(Comparator<? super K> comparat
}

private static <K extends Comparable<? super K>, V> ImmutableSortedMap<K, V>
ofEntries(TerminalEntry<K, V>... entries) {
ofEntries(ImmutableMapEntry<K, V>... entries) {
return fromEntries(Ordering.natural(), false, entries, entries.length);
}

Expand Down

0 comments on commit 7af428e

Please sign in to comment.