Beispiel #1
0
 // Given the splits and the rowKeySchema, find out the keys that
 public static byte[][] processSplits(
     byte[][] splits,
     LinkedHashSet<PColumn> pkColumns,
     Integer saltBucketNum,
     boolean defaultRowKeyOrder)
     throws SQLException {
   // FIXME: shouldn't this return if splits.length == 0?
   if (splits == null) return null;
   // We do not accept user specified splits if the table is salted and we specify
   // defaultRowKeyOrder. In this case,
   // throw an exception.
   if (splits.length > 0 && saltBucketNum != null && defaultRowKeyOrder) {
     throw new SQLExceptionInfo.Builder(SQLExceptionCode.NO_SPLITS_ON_SALTED_TABLE)
         .build()
         .buildException();
   }
   // If the splits are not specified and table is salted, pre-split the table.
   if (splits.length == 0 && saltBucketNum != null) {
     splits = SaltingUtil.getSalteByteSplitPoints(saltBucketNum);
   }
   byte[][] newSplits = new byte[splits.length][];
   for (int i = 0; i < splits.length; i++) {
     newSplits[i] = processSplit(splits[i], pkColumns);
   }
   return newSplits;
 }
Beispiel #2
0
 private static List<byte[]> getPointKeys(
     List<List<KeyRange>> ranges, int[] slotSpan, RowKeySchema schema, Integer bucketNum) {
   if (ranges == null || ranges.isEmpty()) {
     return Collections.emptyList();
   }
   boolean isSalted = bucketNum != null;
   int count = 1;
   int offset = isSalted ? 1 : 0;
   // Skip salt byte range in the first position if salted
   for (int i = offset; i < ranges.size(); i++) {
     count *= ranges.get(i).size();
   }
   List<byte[]> keys = Lists.newArrayListWithExpectedSize(count);
   int[] position = new int[ranges.size()];
   int maxKeyLength = SchemaUtil.getMaxKeyLength(schema, ranges);
   int length;
   byte[] key = new byte[maxKeyLength];
   do {
     length =
         ScanUtil.setKey(
             schema,
             ranges,
             slotSpan,
             position,
             Bound.LOWER,
             key,
             offset,
             offset,
             ranges.size(),
             offset);
     if (isSalted) {
       key[0] = SaltingUtil.getSaltingByte(key, offset, length, bucketNum);
     }
     keys.add(Arrays.copyOf(key, length + offset));
   } while (incrementKey(ranges, position));
   return keys;
 }
Beispiel #3
0
  private ScanRanges(
      RowKeySchema schema,
      int[] slotSpan,
      List<List<KeyRange>> ranges,
      KeyRange scanRange,
      KeyRange minMaxRange,
      boolean useSkipScanFilter,
      boolean isPointLookup,
      Integer bucketNum,
      TimeRange rowTimestampRange) {
    this.isPointLookup = isPointLookup;
    this.isSalted = bucketNum != null;
    this.useSkipScanFilter = useSkipScanFilter;
    this.scanRange = scanRange;
    this.minMaxRange = minMaxRange;
    this.rowTimestampRange = rowTimestampRange;

    // Only blow out the bucket values if we're using the skip scan. We need all the
    // bucket values in this case because we use intersect against a key that may have
    // any of the possible bucket values. Otherwise, we can pretty easily ignore the
    // bucket values.
    if (useSkipScanFilter && isSalted && !isPointLookup) {
      ranges.set(0, SaltingUtil.generateAllSaltingRanges(bucketNum));
    }
    this.ranges = ImmutableList.copyOf(ranges);
    this.slotSpan = slotSpan;
    this.schema = schema;
    if (schema != null && !ranges.isEmpty()) {
      if (!this.useSkipScanFilter) {
        int boundSlotCount = this.getBoundSlotCount();
        ranges = ranges.subList(0, boundSlotCount);
        slotSpan = Arrays.copyOf(slotSpan, boundSlotCount);
      }
      this.filter = new SkipScanFilter(ranges, slotSpan, this.schema);
    }
  }