public SkipScanFilter(List<List<KeyRange>> slots, RowKeySchema schema) { int maxKeyLength = getTerminatorCount(schema); for (List<KeyRange> slot : slots) { int maxSlotLength = 0; for (KeyRange range : slot) { int maxRangeLength = Math.max(range.getLowerRange().length, range.getUpperRange().length); if (maxSlotLength < maxRangeLength) { maxSlotLength = maxRangeLength; } } maxKeyLength += maxSlotLength; } init(slots, schema, maxKeyLength); }
private boolean intersect( byte[] lowerInclusiveKey, byte[] upperExclusiveKey, List<List<KeyRange>> newSlots) { boolean lowerUnbound = (lowerInclusiveKey.length == 0); Arrays.fill(position, 0); isDone = false; int startPos = 0; int lastSlot = slots.size() - 1; if (!lowerUnbound) { // Find the position of the first slot of the lower range ptr.set(lowerInclusiveKey); schema.first(ptr, 0, ValueBitSet.EMPTY_VALUE_BITSET); startPos = ScanUtil.searchClosestKeyRangeWithUpperHigherThanPtr(slots.get(0), ptr, 0); // Lower range is past last upper range of first slot, so cannot possibly be in range if (startPos >= slots.get(0).size()) { return false; } } boolean upperUnbound = (upperExclusiveKey.length == 0); int endPos = slots.get(0).size() - 1; if (!upperUnbound) { // Find the position of the first slot of the upper range ptr.set(upperExclusiveKey); schema.first(ptr, 0, ValueBitSet.EMPTY_VALUE_BITSET); endPos = ScanUtil.searchClosestKeyRangeWithUpperHigherThanPtr(slots.get(0), ptr, startPos); // Upper range lower than first lower range of first slot, so cannot possibly be in range if (endPos == 0 && Bytes.compareTo(upperExclusiveKey, slots.get(0).get(0).getLowerRange()) <= 0) { return false; } // Past last position, so we can include everything from the start position if (endPos >= slots.get(0).size()) { upperUnbound = true; endPos = slots.get(0).size() - 1; } } if (!lowerUnbound) { position[0] = startPos; navigate(lowerInclusiveKey, 0, lowerInclusiveKey.length, Terminate.AFTER); if (filterAllRemaining()) { return false; } } if (upperUnbound) { if (newSlots != null) { newSlots.add(slots.get(0).subList(startPos, endPos + 1)); newSlots.addAll(slots.subList(1, slots.size())); } return true; } int[] lowerPosition = Arrays.copyOf(position, position.length); // Navigate to the upperExclusiveKey, but not past it ReturnCode endCode = navigate(upperExclusiveKey, 0, upperExclusiveKey.length, Terminate.AT); if (endCode == ReturnCode.INCLUDE) { setStartKey(); // If the upperExclusiveKey is equal to the start key, we've gone one position too far, since // our upper key is exclusive. In that case, go to the previous key if (Bytes.compareTo( startKey, 0, startKeyLength, upperExclusiveKey, 0, upperExclusiveKey.length) == 0 && (previousPosition(lastSlot) < 0 || position[0] < lowerPosition[0])) { // If by backing up one position we have an empty range, then return return false; } } else if (endCode == ReturnCode.SEEK_NEXT_USING_HINT) { // The upperExclusive key is smaller than the slots stored in the position. Check if it's the // same position // as the slots for lowerInclusive. If so, there is no intersection. if (Arrays.equals(lowerPosition, position)) { return false; } } // Copy inclusive all positions for (int i = 0; i <= lastSlot; i++) { List<KeyRange> newRanges = slots.get(i).subList(lowerPosition[i], Math.min(position[i] + 1, slots.get(i).size())); if (newRanges.isEmpty()) { return false; } if (newSlots != null) { newSlots.add(newRanges); } if (position[i] > lowerPosition[i]) { if (newSlots != null) { newSlots.addAll(slots.subList(i + 1, slots.size())); } break; } } return true; }