Github user ctubbsii commented on a diff in the pull request:

    https://github.com/apache/accumulo/pull/292#discussion_r133068592
  
    --- Diff: 
core/src/main/java/org/apache/accumulo/core/client/impl/Table.java ---
    @@ -16,24 +16,59 @@
      */
     package org.apache.accumulo.core.client.impl;
     
    +import java.lang.ref.WeakReference;
    +import java.util.WeakHashMap;
    +
     import org.apache.accumulo.core.client.Instance;
     
     public class Table {
     
       /**
        * Object representing an internal table ID. This class was created to 
help with type safety. For help obtaining the value of a table ID from 
Zookeeper, see
        * {@link Tables#getTableId(Instance, String)}
    +   *
    +   * Uses an internal WeakHashMap and private constructor for storing a 
WeakReference of every Table.ID. Therefore, a Table.ID can't be instantiated 
outside
    +   * this class and is accessed by calling Table.ID.{@link #of(String)}.
        */
       public static class ID extends AbstractId {
         private static final long serialVersionUID = 7399913185860577809L;
    +    static final WeakHashMap<String,WeakReference<Table.ID>> tableIds = 
new WeakHashMap<>();
     
    -    public static final ID METADATA = new ID("!0");
    -    public static final ID REPLICATION = new ID("+rep");
    -    public static final ID ROOT = new ID("+r");
    +    public static final ID METADATA = of("!0");
    +    public static final ID REPLICATION = of("+rep");
    +    public static final ID ROOT = of("+r");
     
    -    public ID(final String canonical) {
    +    private ID(final String canonical) {
           super(canonical);
         }
    +
    +    /**
    +     * Get a Table.ID object for the provided canonical string.
    +     *
    +     * @param canonical
    +     *          table ID string
    +     * @return Table.ID object
    +     */
    +    public static Table.ID of(final String canonical) {
    +      return dedupeTableId(canonical);
    +    }
    +
    +    private static Table.ID dedupeTableId(String tableIdString) {
    +      Table.ID tableId;
    +      synchronized (tableIds) {
    +        WeakReference<Table.ID> tableIdRef = tableIds.get(tableIdString);
    +        if (tableIdRef != null) {
    +          tableId = tableIdRef.get();
    +          if (tableId != null) {
    +            return tableId;
    +          }
    +        }
    +
    +        tableId = new ID(tableIdString);
    +        tableIds.put(tableIdString, new WeakReference<>(tableId));
    --- End diff --
    
    Talked to @keith-turner about this briefly. I think the 
`WeakHashMap<String,WeakReference<>>` is the right type, but the String that's 
used as a key should be a new one, so its presence in the map is not dependent 
on the caller's strong reference to the key, but on the caller's strong 
reference to the returned Table.ID object. In other words, it should be:
    
    ```java
        T ret;
        WeakReference<T> ref = cache.get(canonical);
        if (ref == null || (ret = ref.get()) == null) {
            String s = new String(canonical);
            cache.put(s, ret = new Table.ID(s));
        }
        return ret;
    ```
    
    That way, the new String is only contained inside the ID and its presence 
in the map is contingent on the ID object still having a strong reference to 
it. Of course, the user could call `ID.getCanonical()` and get a strong 
reference to the key, thus holding it in the map even when the ID object is 
gone. This could be avoided by the constructor creating a second copy... the 
first is held by the ID only for the purposes of having a strong reference to 
the map key, and the second would be returned in `.getCanonical()` and 
`.toString()`.


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---

Reply via email to