BinShi-SecularBird commented on a change in pull request #463: Phoenix stats 
Initial Commit
URL: https://github.com/apache/phoenix/pull/463#discussion_r267035548
 
 

 ##########
 File path: 
phoenix-core/src/main/java/org/apache/phoenix/compile/ScanRanges.java
 ##########
 @@ -694,4 +694,136 @@ public TimeRange getRowTimestampRange() {
         return rowTimestampRange;
     }
 
+    /**
+     * Produces the list of KeyRanges representing the fully qualified row key 
by calling into ScanUtil.setKey
+     * repeatedly for every combination of KeyRanges in the ranges field. The 
bounds will be set according to the
+     * properties of the setKey method.
+     * 
+     * @return list of KeyRanges representing the fully qualified rowkey, 
coalesced
+     */
+    public List<KeyRange> getRowKeyRanges() {
+        // If its scanRanges are everything or nothing, then we short circuit 
and leave
+        // as schema is not filled in
+        if (isEverything()) { return 
Lists.newArrayList(KeyRange.EVERYTHING_RANGE); }
+        if (isDegenerate()) { return Lists.newArrayList(KeyRange.EMPTY_RANGE); 
}
+
+        List<KeyRange> queryRowKeyRanges = 
Lists.newArrayListWithExpectedSize(this.ranges.size());
+
+        // Point lookups are stored in the first range as a whole and already 
a rowkey
+        // see ScanRanges.getPointLookupKeyIterator
+        if (this.isPointLookup()) {
+            queryRowKeyRanges.addAll(this.getRanges().get(0));
+        } else {
+            // If scanRanges.ranges has no information then should be in the 
scanRanges.scanRange
+            if (this.getRanges().size() == 0) {
+                queryRowKeyRanges.add(this.getScanRange());
+            } else { // We have a composite key need the row key from the 
combination
+                // make a copy of ranges as we may add items to fully qualify 
our rowkey
+                List<List<KeyRange>> newRanges = new 
ArrayList<>(this.getRanges());
+
+                int[] slotSpans = this.getSlotSpans();
+
+                // If the ranges here do not qualify all the keys then those 
keys are unbound
+                if (newRanges.size() < schema.getMaxFields()) {
+                    int originalSize = newRanges.size();
+                    for (int i = 0; i < schema.getMaxFields() - originalSize; 
i++) {
+                        
newRanges.add(Lists.newArrayList(KeyRange.EVERYTHING_RANGE));
+                    }
+                    slotSpans = new int[schema.getMaxFields()];
+                    System.arraycopy(this.getSlotSpans(), 0, slotSpans, 0, 
this.getSlotSpans().length);
+                }
+
+                // Product to bound our counting loop for safety
+                int rangesPermutationsCount = 1;
+                for (int i = 0; i < newRanges.size(); i++) {
+                    rangesPermutationsCount *= newRanges.get(i).size();
+                }
+
+                // Have to construct the intersection
+                List<KeyRange> expandedRanges = 
Lists.newArrayListWithCapacity(rangesPermutationsCount);
+                int[] positions = new int[slotSpans.length];
+
+                int maxKeyLength = SchemaUtil.getMaxKeyLength(schema, 
newRanges);
+                byte[] keyBuffer = new byte[maxKeyLength];
+
+                // Counting Loop
+                int count = 0;
+                while (count < rangesPermutationsCount) {
+                    byte[] lowerBound;
+                    byte[] upperBound;
+
+                    // Note ScanUtil.setKey internally handles the upper/lower 
exclusive from a Scan
+                    // point of view. It would be good to break it out in the 
future for rowkey
+                    // construction vs ScanKey construction To handle 
differences between
+                    // hbase 2 and hbase 1 scan boundaries
+                    int result = ScanUtil.setKey(schema, newRanges, slotSpans, 
positions, KeyRange.Bound.LOWER, keyBuffer,
+                            0, 0, slotSpans.length);
+
+                    if (result < 0) {
+                        // unbound
+                        lowerBound = KeyRange.UNBOUND;
+                    } else {
+                        lowerBound = Arrays.copyOf(keyBuffer, result);
+                    }
+
+                    result = ScanUtil.setKey(schema, newRanges, slotSpans, 
positions, KeyRange.Bound.UPPER, keyBuffer, 0, 0,
+                            slotSpans.length);
+
+                    if (result < 0) {
+                        // unbound
+                        upperBound = KeyRange.UNBOUND;
+                    } else {
+                        upperBound = Arrays.copyOf(keyBuffer, result);
+                    }
+
+
+                    /*
+                     * This is already considered inside of ScanUtil.setKey we 
may want to refactor to pull these out.
+                     * range/single    boundary       bound      increment
+                     *  range          inclusive      lower         no
+                     *  range          inclusive      upper         yes, at 
the end if occurs at any slots.
+                     *  range          exclusive      lower         yes
+                     *  range          exclusive      upper         no
+                     *  single         inclusive      lower         no
+                     *  single         inclusive      upper         yes, at 
the end if it is the last slots.
+                     */
 
 Review comment:
   Can we have test case for this func spec, i.e., for all these cases in 
comments, every returned key range's upper boundary is exclusive?

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to