From issues-return-5298-archive-asf-public=cust-asf.ponee.io@phoenix.apache.org Sun Mar 17 16:50:48 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx-eu-01.ponee.io (Postfix) with SMTP id 3DF8018077A for ; Sun, 17 Mar 2019 17:50:48 +0100 (CET) Received: (qmail 34629 invoked by uid 500); 17 Mar 2019 16:50:47 -0000 Mailing-List: contact issues-help@phoenix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@phoenix.apache.org Delivered-To: mailing list issues@phoenix.apache.org Received: (qmail 34617 invoked by uid 99); 17 Mar 2019 16:50:47 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 17 Mar 2019 16:50:47 +0000 From: GitBox To: issues@phoenix.apache.org Subject: [GitHub] [phoenix] BinShi-SecularBird commented on a change in pull request #463: Phoenix stats Initial Commit Message-ID: <155284144666.27770.7542359716694351928.gitbox@gitbox.apache.org> Date: Sun, 17 Mar 2019 16:50:46 -0000 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit BinShi-SecularBird commented on a change in pull request #463: Phoenix stats Initial Commit URL: https://github.com/apache/phoenix/pull/463#discussion_r266173360 ########## File path: phoenix-core/src/main/java/org/apache/phoenix/compile/ScanRanges.java ########## @@ -694,4 +694,127 @@ 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 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 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> ranges = new ArrayList<>(); + ranges.addAll(this.getRanges()); + + int[] slotSpans = this.getSlotSpans(); + + // If the ranges here do not qualify all the keys then those keys are unbound + if (ranges.size() < schema.getMaxFields()) { + int originalSize = ranges.size(); + for (int i = 0; i < schema.getMaxFields() - originalSize; i++) { + ranges.add(Lists.newArrayList(KeyRange.EVERYTHING_RANGE)); + } + slotSpans = new int[schema.getMaxFields()]; + } + + // Product to bound our counting loop for safety + int rangesPermutations = 1; + for (int i = 0; i < ranges.size(); i++) { + rangesPermutations *= ranges.get(i).size(); + } + + // Have to construct the intersection + List expandedRanges = Lists.newArrayListWithExpectedSize(rangesPermutations); + int[] position = new int[slotSpans.length]; + + int maxKeyLength = SchemaUtil.getMaxKeyLength(schema, ranges); + byte[] keyBuffer = new byte[maxKeyLength]; + + // Counting Loop + int count = 0; + while (count < rangesPermutations) { + 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, ranges, slotSpans, position, 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, ranges, slotSpans, position, 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 those out. + boolean lowerInclusive = true; + boolean upperInclusive = true; + // If we are not a single key + if (!Arrays.equals(lowerBound, upperBound)) { + upperInclusive = false; + } + + // Don't send a null range, send an empty range. + if (lowerBound.length == 0 && upperBound.length == 0) { + lowerInclusive = false; + upperInclusive = false; + } + + KeyRange keyRange = KeyRange.getKeyRange(lowerBound, lowerInclusive, upperBound, upperInclusive); + expandedRanges.add(keyRange); + + // update position + int i; + for (i = 0; i < position.length; i++) { + + if (position[i] < ranges.get(i).size() - 1) { + position[i]++; + break; + } else { + position[i] = 0; + } + } + + if (i == position.length) { + break; + } + rangesPermutations++; Review comment: Do you mean count++? ---------------------------------------------------------------- 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: users@infra.apache.org With regards, Apache Git Services