Github user JamesRTaylor commented on a diff in the pull request:
https://github.com/apache/phoenix/pull/8#discussion_r16699691
--- 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 --
I wouldn't assume that only the size changing means it's different. Just
compare the hash code in the equals check and add a hashCode member variable
that gets set at construction time.
Also, I'm not sure we need a Map - take a look and see if you can get away
with just a List<byte[]> where they're ordered. See my comments in
ParallelIterators - I believe well basically just use all of them, all the time.
---
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.
---