Index: dart/compiler/java/com/google/dart/compiler/common/NameFactory.java |
diff --git a/dart/compiler/java/com/google/dart/compiler/common/NameFactory.java b/dart/compiler/java/com/google/dart/compiler/common/NameFactory.java |
deleted file mode 100644 |
index 1edfe141283847e11e45ee19a759b2a1b6c95c6e..0000000000000000000000000000000000000000 |
--- a/dart/compiler/java/com/google/dart/compiler/common/NameFactory.java |
+++ /dev/null |
@@ -1,226 +0,0 @@ |
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
-// for details. All rights reserved. Use of this source code is governed by a |
-// BSD-style license that can be found in the LICENSE file. |
- |
-package com.google.dart.compiler.common; |
- |
-import com.google.common.annotations.VisibleForTesting; |
-import com.google.common.collect.MapMaker; |
- |
-import java.lang.ref.ReferenceQueue; |
-import java.lang.ref.WeakReference; |
-import java.util.Arrays; |
-import java.util.concurrent.ConcurrentMap; |
- |
-/** |
- * Manages the life cycle, uniqueness, and object identity invariants of |
- * {@link Name}. |
- */ |
-final class NameFactory { |
- /* |
- * TODO: does this actually save memory in practice? For each interned Name, |
- * we use: |
- * |
- * 1) The data array (n bytes). |
- * |
- * 2) The Name object (2 fields) |
- * |
- * 3) The RealKey (1 field + 4 fields from Reference). |
- * |
- * 4) ConcurrentMap.Entry (4 fields) |
- * |
- * Of course, a Map is really much heavier than we need, all we really need is |
- * a Set where you can retrieve an object already in the Set. A bare linear |
- * probe hash table of RealKey would let us get rid of the Entry object. |
- */ |
- |
- /** |
- * The whole point of this class is to cheaply create a light-weight key that |
- * doesn't need to make its own copy of the data. This object is constructed |
- * with equality semantics to {@link RealKey}, for doing cheap map lookups. |
- */ |
- private static final class FakeKey { |
- private final char[] data; |
- private final int hashCode; |
- private final int length; |
- private final int offset; |
- |
- public FakeKey(char[] data, int hashCode) { |
- this(data, 0, data.length, hashCode); |
- } |
- |
- public FakeKey(char[] data, int offset, int length, int hashCode) { |
- this.data = data; |
- this.offset = offset; |
- this.length = length; |
- this.hashCode = hashCode; |
- } |
- |
- @Override |
- public boolean equals(Object obj) { |
- /* |
- * NOTE: this ONLY WORKS for comparisons to RealKey. But that's all we |
- * need since we only store real keys in the map. |
- */ |
- Name name = ((RealKey) obj).get(); |
- if (name == null) { |
- return false; |
- } |
- return equalsName(name); |
- } |
- |
- public boolean equalsName(Name name) { |
- if (this.length != name.data.length) { |
- return false; |
- } |
- int itMine = this.offset; |
- int itTheirs = 0; |
- int endMine = this.offset + this.length; |
- while (itMine < endMine) { |
- if (this.data[itMine++] != name.data[itTheirs++]) { |
- return false; |
- } |
- } |
- return true; |
- } |
- |
- @Override |
- public int hashCode() { |
- return hashCode; |
- } |
- |
- @Override |
- public String toString() { |
- return "FakeKey(" + String.valueOf(data, offset, length) + ")"; |
- } |
- } |
- |
- /** |
- * Adapted from {@link com.google.common.collect.Interners#newWeakInterner()}. |
- */ |
- private static final class RealKey extends WeakReference<Name> { |
- /** |
- * Must store the hashCode locally so we can be removed from |
- * {@link NameFactory#map} after our referent is cleared. |
- */ |
- private final int hashCode; |
- |
- public RealKey(Name name, ReferenceQueue<Name> queue) { |
- super(name, queue); |
- hashCode = name.hashCode(); |
- } |
- |
- @Override |
- public boolean equals(Object obj) { |
- if (obj == this) { |
- return true; |
- } |
- if (obj instanceof FakeKey) { |
- Name referent = get(); |
- if (referent == null) { |
- return false; |
- } |
- return ((FakeKey) obj).equalsName(referent); |
- } |
- if (obj instanceof RealKey) { |
- Name referent = get(); |
- if (referent == null) { |
- return false; |
- } |
- Name otherReferent = ((RealKey) obj).get(); |
- if (otherReferent == null) { |
- return false; |
- } |
- return Arrays.equals(referent.data, otherReferent.data); |
- } |
- return false; |
- } |
- |
- @Override |
- public int hashCode() { |
- return hashCode; |
- } |
- |
- @Override |
- public String toString() { |
- Name referent = get(); |
- return "RealKey(" + referent + ")"; |
- } |
- } |
- |
- private final ConcurrentMap<Object, RealKey> map = new MapMaker().makeMap(); |
- private final ReferenceQueue<Name> queue = new ReferenceQueue<Name>(); |
- |
- /** |
- * Return the Name corresponding to the data. An internal reference to |
- * <code>data</code> may be kept. |
- */ |
- public Name of(char[] data) { |
- cleanUp(); |
- int hashCode = Name.computeHashCode(data, 0, data.length); |
- FakeKey fakeKey = new FakeKey(data, hashCode); |
- Name result = get(fakeKey); |
- if (result == null) { |
- result = put(new Name(data, hashCode)); |
- } |
- return result; |
- } |
- |
- /** |
- * Return the Name corresponding to the data. An internal copy of the data is |
- * made. |
- */ |
- public Name of(char[] data, int offset, int length) { |
- cleanUp(); |
- int hashCode = Name.computeHashCode(data, offset, length); |
- FakeKey fakeKey = new FakeKey(data, offset, length, hashCode); |
- Name result = get(fakeKey); |
- if (result == null) { |
- char[] copy = new char[length]; |
- System.arraycopy(data, offset, copy, 0, length); |
- result = put(new Name(copy, hashCode)); |
- } |
- return result; |
- } |
- |
- @VisibleForTesting |
- void cleanUp() { |
- RealKey item; |
- while ((item = (RealKey) queue.poll()) != null) { |
- map.remove(item); |
- } |
- } |
- |
- @VisibleForTesting |
- WeakReference<Name> getRefFor(Name name) { |
- return map.get(new FakeKey(name.data, name.hashCode())); |
- } |
- |
- @VisibleForTesting |
- int numEntries() { |
- return map.size(); |
- } |
- |
- private Name get(FakeKey fakeKey) { |
- RealKey realKey = map.get(fakeKey); |
- if (realKey != null) { |
- return realKey.get(); |
- } |
- return null; |
- } |
- |
- private Name put(Name name) { |
- RealKey realKey = new RealKey(name, queue); |
- while (true) { |
- RealKey sneakyRef = map.putIfAbsent(realKey, realKey); |
- if (sneakyRef == null) { |
- return name; |
- } else { |
- Name canonical = sneakyRef.get(); |
- if (canonical != null) { |
- return canonical; |
- } |
- } |
- } |
- } |
-} |