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

    https://github.com/apache/phoenix/pull/8#discussion_r16696186
  
    --- Diff: 
phoenix-core/src/main/java/org/apache/phoenix/schema/stat/PTableStatsImpl.java 
---
    @@ -16,40 +16,249 @@
      * limitations under the License.
      */
     package org.apache.phoenix.schema.stat;
    -
    + import java.util.Collection;
    +import java.util.HashMap;
     import java.util.Map;
    +import java.util.Map.Entry;
    +import java.util.Set;
     
     import org.apache.hadoop.hbase.HRegionInfo;
    +import org.apache.hadoop.hbase.util.Bytes;
    +import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
     
     import com.google.common.collect.ImmutableMap;
    + 
    + /**
    +  * Implementation for PTableStats.
    +  */
    + public class PTableStatsImpl implements PTableStats {
    + 
    +   public static final PTableStats NO_STATS = new PTableStatsImpl();
    +   // The map for guide posts should be immutable. We only take the current
    +   // snapshot from outside
    +   // method call and store it.
    +   private Map<String, byte[]> regionGuidePosts = new HashMap<String, 
byte[]>();
    +   // TODO : see if a thread safe map would be needed here
    +   private Map<String, byte[]> minKey = new HashMap<String, byte[]>();
    +   private Map<String, byte[]> maxKey = new HashMap<String, byte[]>();
    + 
    +   public PTableStatsImpl() {
    +     this(new HashMap<String, byte[]>(), new HashMap<String, byte[]>(),
    +         new HashMap<String, byte[]>());
    +   }
    + 
    +   public PTableStatsImpl(Map<String, byte[]> guidePosts,
    +       Map<String, byte[]> minKey, Map<String, byte[]> maxKey) {
    +     this.regionGuidePosts = guidePosts;
    +     this.minKey = minKey;
    +     this.maxKey = maxKey;
    +   }
    + 
    +   @Override
    +   public byte[] getRegionGuidePostsOfARegion(HRegionInfo region) {
    +     return regionGuidePosts.get(Bytes.toString(region.getRegionName()));
    +   }
    + 
    +   @Override
    +   public Map<String, byte[]> getGuidePosts() {
    +     if (regionGuidePosts != null) {
    +       return ImmutableMap.copyOf(regionGuidePosts);
    +     }
    + 
    +     return null;
    +   }
    + 
    +   @Override
    +   public byte[] getMaxKeyOfARegion(HRegionInfo region) {
    +     return 
Bytes.copy(this.minKey.get(Bytes.toString(region.getRegionName())));
    +   }
    + 
    +   @Override
    +   public byte[] getMinKeyOfARegion(HRegionInfo region) {
    +     return 
Bytes.copy(this.maxKey.get(Bytes.toString(region.getRegionName())));
    +   }
    + 
    +   @Override
    +   public Map<String, byte[]> getMaxKey() {
    +     if (maxKey != null) {
    +       return ImmutableMap.copyOf(maxKey);
    +     }
    +     return null;
    +   }
    + 
    +   @Override
    +   public Map<String, byte[]> getMinKey() {
    +     if (minKey != null) {
    +       return ImmutableMap.copyOf(minKey);
    +     }
    +     return null;
    +   }
    + 
    +   @Override
    +   public void setMinKey(HRegionInfo region, byte[] minKey, int offset, 
int length) {
    +     ImmutableBytesPtr ptr = new ImmutableBytesPtr(minKey, offset, length);
    +     this.minKey.put(region.getRegionNameAsString(), 
ImmutableBytesPtr.copyBytesIfNecessary(ptr));
    +   }
    + 
    +   @Override
    +   public void setMaxKey(HRegionInfo region, byte[] maxKey, int offset, 
int length) {
    +     ImmutableBytesPtr ptr = new ImmutableBytesPtr(maxKey, offset, length);
    +     this.maxKey.put(region.getRegionNameAsString(), 
ImmutableBytesPtr.copyBytesIfNecessary(ptr));
    +   }
    + 
    +   @Override
    +   public void setGuidePosts(HRegionInfo region, byte[] guidePosts, int 
offset, int length) {
    +     ImmutableBytesPtr ptr = new ImmutableBytesPtr(guidePosts, offset, 
length);
    +     this.regionGuidePosts.put(region.getRegionNameAsString(),
    +         ImmutableBytesPtr.copyBytesIfNecessary(ptr));
    +   }
    + 
    +   @Override
    +   public void setMinKey(byte[] region, byte[] minKey, int offset, int 
length) {
    +     ImmutableBytesPtr ptr = new ImmutableBytesPtr(minKey, offset, length);
    +     this.minKey.put(Bytes.toString(region), 
ImmutableBytesPtr.copyBytesIfNecessary(ptr));
    +   }
    + 
    +   @Override
    +   public void setMaxKey(byte[] region, byte[] maxKey, int offset, int 
length) {
    +     ImmutableBytesPtr ptr = new ImmutableBytesPtr(maxKey, offset, length);
    +     this.maxKey.put(Bytes.toString(region), 
ImmutableBytesPtr.copyBytesIfNecessary(ptr));
    +   }
    + 
    +   @Override
    +   public void setGuidePosts(byte[] region, byte[] guidePosts, int offset, 
int length) {
    +     ImmutableBytesPtr ptr = new ImmutableBytesPtr(guidePosts, offset, 
length);
    +     this.regionGuidePosts.put(Bytes.toString(region), 
ImmutableBytesPtr.copyBytesIfNecessary(ptr));
    +   }
    + 
    +   @Override
    +   public boolean equals(Object obj) {
    +     if (!(obj instanceof PTableStats)) {
    +       return false;
    +     }
    +     PTableStats pTableStats = (PTableStats) obj;
    +     // compare the max keys
    +     Map<String, byte[]> thatMaxKey = pTableStats.getMaxKey();
    +     Map<String, byte[]> thisMaxKey = this.getMaxKey();
    +     if (thatMaxKey.size() != thisMaxKey.size()) {
    +       return false;
    +     } else {
    +       Set<Entry<String, byte[]>> thatEntrySet = thatMaxKey.entrySet();
    +       Set<Entry<String, byte[]>> thisEntrySet = thisMaxKey.entrySet();
    +       for (Entry<String, byte[]> thatEntry : thatEntrySet) {
    +         boolean matchFound = false;
    +         Entry<String, byte[]> temp = null;
    +         for (Entry<String, byte[]> thisEntry : thisEntrySet) {
    +           if (thatEntry.getKey().equals(thisEntry.getKey())) {
    +             matchFound = true;
    +             temp = thisEntry;
    +             break;
    +           }
    +         }
    +         if (!matchFound) {
    +           return false;
    +         } else {
    +           if (temp != null) {
    +             if (!Bytes.equals(thatEntry.getValue(), temp.getValue())) {
    +               return false;
    +             }
    +           } else {
    +             return false;
    +           }
    +         }
    + 
    +       }
    +     }
    + 
    +     // Check for min key
    +     Map<String, byte[]> thatMinKey = pTableStats.getMinKey();
    +     Map<String, byte[]> thisMinKey = this.getMinKey();
    +     if (thatMinKey.size() != thisMinKey.size()) {
    +       return false;
    +     } else {
    +       Set<Entry<String, byte[]>> thatEntrySet = thatMinKey.entrySet();
    +       Set<Entry<String, byte[]>> thisEntrySet = thisMinKey.entrySet();
    +       for (Entry<String, byte[]> thatEntry : thatEntrySet) {
    +         boolean matchFound = false;
    +         Entry<String, byte[]> temp = null;
    +         for (Entry<String, byte[]> thisEntry : thisEntrySet) {
    +           if (thatEntry.getKey().equals(thisEntry.getKey())) {
    +             matchFound = true;
    +             temp = thisEntry;
    +             break;
    +           }
    +         }
    +         if (!matchFound) {
    +           return false;
    +         } else {
    +           if (temp != null) {
    +             if (!Bytes.equals(thatEntry.getValue(), temp.getValue())) {
    +               return false;
    +             }
    +           } else {
    +             return false;
    +           }
    +         }
    + 
    +       }
    +     }
    + 
    +     // Check for guide posts
    +     Map<String, byte[]> thatGuidePosts = pTableStats.getGuidePosts();
    +     Map<String, byte[]> thisGuidePosts = this.getGuidePosts();
    +     if (thatGuidePosts.size() != thisGuidePosts.size()) {
    +       return false;
    +     } else {
    +       Set<Entry<String, byte[]>> thatEntrySet = thatGuidePosts.entrySet();
    +       Set<Entry<String, byte[]>> thisEntrySet = thisGuidePosts.entrySet();
    +       for (Entry<String, byte[]> thatEntry : thatEntrySet) {
    +         boolean matchFound = false;
    +         Entry<String, byte[]> temp = null;
    +         for (Entry<String, byte[]> thisEntry : thisEntrySet) {
    +           if (thatEntry.getKey().equals(thisEntry.getKey())) {
    +             matchFound = true;
    +             temp = thisEntry;
    +             break;
    +           }
    +         }
    +         if (!matchFound) {
    +           return false;
    +         } else {
    +           if (temp != null) {
    +             if (!Bytes.equals(thatEntry.getValue(), temp.getValue())) {
    +               return false;
    +             }
    +           } else {
    +             return false;
    +           }
    +         }
    + 
    +       }
    +     }
    +     return true;
    +   }
     
    -
    -/**
    - * Implementation for PTableStats.
    - */
    -public class PTableStatsImpl implements PTableStats {
    -
    -    // The map for guide posts should be immutable. We only take the 
current snapshot from outside
    -    // method call and store it.
    -    private Map<String, byte[][]> regionGuidePosts;
    -
    -    public PTableStatsImpl() { }
    -
    -    public PTableStatsImpl(Map<String, byte[][]> stats) {
    -        regionGuidePosts = ImmutableMap.copyOf(stats);
    -    }
    -
    -    @Override
    -    public byte[][] getRegionGuidePosts(HRegionInfo region) {
    -        return regionGuidePosts.get(region.getRegionNameAsString());
    -    }
    -
    -    @Override
    -    public Map<String, byte[][]> getGuidePosts(){
    -      if(regionGuidePosts != null) {
    -        return ImmutableMap.copyOf(regionGuidePosts);
    -      }
    -      
    -      return null;
    -    }
    +   @Override
    +   public int hashCode() {
    +     int hash = 1;
    --- End diff --
    
    Looks somewhat expensive to calculate. PTableStats should be immutable, so 
instead calculate this in a static method and set during construction.


---
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 [email protected] or file a JIRA ticket
with INFRA.
---

Reply via email to