Beispiel #1
0
 /**
  * Advanced use only. Add an existing delete marker to this Delete object.
  *
  * @param kv An existing KeyValue of type "delete".
  * @return this for invocation chaining
  * @throws IOException
  */
 @SuppressWarnings("unchecked")
 public Delete addDeleteMarker(Cell kv) throws IOException {
   // TODO: Deprecate and rename 'add' so it matches how we add KVs to Puts.
   if (!CellUtil.isDelete(kv)) {
     throw new IOException(
         "The recently added KeyValue is not of type "
             + "delete. Rowkey: "
             + Bytes.toStringBinary(this.row));
   }
   if (Bytes.compareTo(
           this.row, 0, row.length, kv.getRowArray(), kv.getRowOffset(), kv.getRowLength())
       != 0) {
     throw new WrongRowIOException(
         "The row in "
             + kv.toString()
             + " doesn't match the original one "
             + Bytes.toStringBinary(this.row));
   }
   byte[] family = CellUtil.cloneFamily(kv);
   List<Cell> list = familyMap.get(family);
   if (list == null) {
     list = new ArrayList<Cell>();
   }
   list.add(kv);
   familyMap.put(family, list);
   return this;
 }
Beispiel #2
0
 /**
  * This utility method creates a list of Thrift TRowResult "struct" based on an Hbase RowResult
  * object. The empty list is returned if the input is null.
  *
  * @param in Hbase RowResult object
  * @param sortColumns This boolean dictates if row data is returned in a sorted order sortColumns
  *     = True will set TRowResult's sortedColumns member which is an ArrayList of TColumn struct
  *     sortColumns = False will set TRowResult's columns member which is a map of columnName and
  *     TCell struct
  * @return Thrift TRowResult array
  */
 public static List<TRowResult> rowResultFromHBase(Result[] in, boolean sortColumns) {
   List<TRowResult> results = new ArrayList<TRowResult>();
   for (Result result_ : in) {
     if (result_ == null || result_.isEmpty()) {
       continue;
     }
     TRowResult result = new TRowResult();
     result.row = ByteBuffer.wrap(result_.getRow());
     if (sortColumns) {
       result.sortedColumns = new ArrayList<TColumn>();
       for (Cell kv : result_.rawCells()) {
         result.sortedColumns.add(
             new TColumn(
                 ByteBuffer.wrap(
                     KeyValue.makeColumn(CellUtil.cloneFamily(kv), CellUtil.cloneQualifier(kv))),
                 new TCell(ByteBuffer.wrap(CellUtil.cloneValue(kv)), kv.getTimestamp())));
       }
     } else {
       result.columns = new TreeMap<ByteBuffer, TCell>();
       for (Cell kv : result_.rawCells()) {
         result.columns.put(
             ByteBuffer.wrap(
                 KeyValue.makeColumn(CellUtil.cloneFamily(kv), CellUtil.cloneQualifier(kv))),
             new TCell(ByteBuffer.wrap(CellUtil.cloneValue(kv)), kv.getTimestamp()));
       }
     }
     results.add(result);
   }
   return results;
 }
 @Override
 public ReturnCode filterKeyValue(Cell kv) {
   if (sortedPrefixes.size() == 0 || kv.getQualifierArray() == null) {
     return ReturnCode.INCLUDE;
   } else {
     return filterColumn(kv.getQualifierArray(), kv.getQualifierOffset(), kv.getQualifierLength());
   }
 }
      @Override
      public void process(long now, HRegion region, List<Mutation> mutations, WALEdit walEdit)
          throws IOException {

        // Override the time to avoid race-condition in the unit test caused by
        // inacurate timer on some machines
        now = myTimer.getAndIncrement();

        // Scan both rows
        List<Cell> kvs1 = new ArrayList<Cell>();
        List<Cell> kvs2 = new ArrayList<Cell>();
        doScan(region, new Scan(row1, row1), kvs1);
        doScan(region, new Scan(row2, row2), kvs2);

        // Assert swapped
        if (swapped) {
          assertEquals(rowSize, kvs2.size());
          assertEquals(row2Size, kvs1.size());
        } else {
          assertEquals(rowSize, kvs1.size());
          assertEquals(row2Size, kvs2.size());
        }
        swapped = !swapped;

        // Add and delete keyvalues
        List<List<Cell>> kvs = new ArrayList<List<Cell>>();
        kvs.add(kvs1);
        kvs.add(kvs2);
        byte[][] rows = new byte[][] {row1, row2};
        for (int i = 0; i < kvs.size(); ++i) {
          for (Cell kv : kvs.get(i)) {
            // Delete from the current row and add to the other row
            Delete d = new Delete(rows[i]);
            KeyValue kvDelete =
                new KeyValue(
                    rows[i],
                    CellUtil.cloneFamily(kv),
                    CellUtil.cloneQualifier(kv),
                    kv.getTimestamp(),
                    KeyValue.Type.Delete);
            d.addDeleteMarker(kvDelete);
            Put p = new Put(rows[1 - i]);
            KeyValue kvAdd =
                new KeyValue(
                    rows[1 - i],
                    CellUtil.cloneFamily(kv),
                    CellUtil.cloneQualifier(kv),
                    now,
                    CellUtil.cloneValue(kv));
            p.add(kvAdd);
            mutations.add(d);
            walEdit.add(kvDelete);
            mutations.add(p);
            walEdit.add(kvAdd);
          }
        }
      }
Beispiel #5
0
 public ProjectedValueTuple projectResults(Tuple tuple) {
   byte[] bytesValue = schema.toBytes(tuple, expressions, valueSet, ptr);
   Cell base = tuple.getValue(0);
   return new ProjectedValueTuple(
       base.getRowArray(),
       base.getRowOffset(),
       base.getRowLength(),
       base.getTimestamp(),
       bytesValue,
       valueSet.getEstimatedLength());
 }
Beispiel #6
0
  @Test(timeOut = 10_000)
  public void testShadowCellSuffixConcatenationToQualifier() {

    Cell cell = new KeyValue(row, family, qualifier, 1, Bytes.toBytes("value"));
    byte[] suffixedQualifier =
        CellUtils.addShadowCellSuffix(
            cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
    byte[] expectedQualifier =
        com.google.common.primitives.Bytes.concat(qualifier, SHADOW_CELL_SUFFIX);
    assertEquals(suffixedQualifier, expectedQualifier);
  }
Beispiel #7
0
  @GET
  @Produces({MIMETYPE_XML, MIMETYPE_JSON, MIMETYPE_PROTOBUF, MIMETYPE_PROTOBUF_IETF})
  public Response get(final @Context UriInfo uriInfo) {
    MultivaluedMap<String, String> params = uriInfo.getQueryParameters();

    servlet.getMetrics().incrementRequests(1);
    try {
      CellSetModel model = new CellSetModel();
      for (String rk : params.get(ROW_KEYS_PARAM_NAME)) {
        RowSpec rowSpec = new RowSpec(rk);

        if (this.versions != null) {
          rowSpec.setMaxVersions(this.versions);
        }
        ResultGenerator generator =
            ResultGenerator.fromRowSpec(
                this.tableResource.getName(),
                rowSpec,
                null,
                !params.containsKey(NOCACHE_PARAM_NAME));
        Cell value = null;
        RowModel rowModel = new RowModel(rk);
        if (generator.hasNext()) {
          while ((value = generator.next()) != null) {
            rowModel.addCell(
                new CellModel(
                    CellUtil.cloneFamily(value),
                    CellUtil.cloneQualifier(value),
                    value.getTimestamp(),
                    CellUtil.cloneValue(value)));
          }
          model.addRow(rowModel);
        } else {
          LOG.trace("The row : " + rk + " not found in the table.");
        }
      }

      if (model.getRows().size() == 0) {
        // If no rows found.
        servlet.getMetrics().incrementFailedGetRequests(1);
        return Response.status(Response.Status.NOT_FOUND)
            .type(MIMETYPE_TEXT)
            .entity("No rows found." + CRLF)
            .build();
      } else {
        servlet.getMetrics().incrementSucessfulGetRequests(1);
        return Response.ok(model).build();
      }
    } catch (Exception e) {
      servlet.getMetrics().incrementFailedGetRequests(1);
      return processException(e);
    }
  }
 @Override
 public void postGetOp(
     ObserverContext<RegionCoprocessorEnvironment> e, Get get, List<Cell> results)
     throws IOException {
   if (results.size() > 0) {
     // Check tag presence in the 1st cell in 1st Result
     if (!results.isEmpty()) {
       Cell cell = results.get(0);
       tags = Tag.asList(cell.getTagsArray(), cell.getTagsOffset(), cell.getTagsLength());
     }
   }
 }
Beispiel #9
0
 /*
  * Private method to determine if this object's familyMap contains
  * the given value assigned to the given family, qualifier and timestamp
  * respecting the 2 boolean arguments
  *
  * @param family
  * @param qualifier
  * @param ts
  * @param value
  * @param ignoreTS
  * @param ignoreValue
  * @return returns true if the given family, qualifier timestamp and value
  * already has an existing KeyValue object in the family map.
  */
 private boolean has(
     byte[] family,
     byte[] qualifier,
     long ts,
     byte[] value,
     boolean ignoreTS,
     boolean ignoreValue) {
   List<Cell> list = getCellList(family);
   if (list.size() == 0) {
     return false;
   }
   // Boolean analysis of ignoreTS/ignoreValue.
   // T T => 2
   // T F => 3 (first is always true)
   // F T => 2
   // F F => 1
   if (!ignoreTS && !ignoreValue) {
     for (Cell cell : list) {
       if (CellUtil.matchingFamily(cell, family)
           && CellUtil.matchingQualifier(cell, qualifier)
           && CellUtil.matchingValue(cell, value)
           && cell.getTimestamp() == ts) {
         return true;
       }
     }
   } else if (ignoreValue && !ignoreTS) {
     for (Cell cell : list) {
       if (CellUtil.matchingFamily(cell, family)
           && CellUtil.matchingQualifier(cell, qualifier)
           && cell.getTimestamp() == ts) {
         return true;
       }
     }
   } else if (!ignoreValue && ignoreTS) {
     for (Cell cell : list) {
       if (CellUtil.matchingFamily(cell, family)
           && CellUtil.matchingQualifier(cell, qualifier)
           && CellUtil.matchingValue(cell, value)) {
         return true;
       }
     }
   } else {
     for (Cell cell : list) {
       if (CellUtil.matchingFamily(cell, family) && CellUtil.matchingQualifier(cell, qualifier)) {
         return true;
       }
     }
   }
   return false;
 }
Beispiel #10
0
  @Test(dataProvider = "shadow-cell-suffixes", timeOut = 10_000)
  public void testShadowCellSuffixRemovalFromQualifier(byte[] shadowCellSuffixToTest)
      throws IOException {

    // Test removal from a correclty suffixed qualifier
    byte[] suffixedQualifier =
        com.google.common.primitives.Bytes.concat(qualifier, shadowCellSuffixToTest);
    Cell cell = new KeyValue(row, family, suffixedQualifier, 1, Bytes.toBytes("value"));
    byte[] resultedQualifier =
        CellUtils.removeShadowCellSuffix(
            cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
    byte[] expectedQualifier = qualifier;
    assertEquals(resultedQualifier, expectedQualifier);

    // Test removal from a badly suffixed qualifier
    byte[] badlySuffixedQualifier =
        com.google.common.primitives.Bytes.concat(qualifier, Bytes.toBytes("BAD"));
    Cell badCell = new KeyValue(row, family, badlySuffixedQualifier, 1, Bytes.toBytes("value"));
    try {
      CellUtils.removeShadowCellSuffix(
          badCell.getQualifierArray(), badCell.getQualifierOffset(), badCell.getQualifierLength());
      fail();
    } catch (IllegalArgumentException e) {
      // Expected
    }
  }
Beispiel #11
0
 /**
  * This utility method creates a list of Thrift TCell "struct" based on an Hbase Cell object. The
  * empty list is returned if the input is null.
  *
  * @param in Hbase Cell object
  * @return Thrift TCell array
  */
 public static List<TCell> cellFromHBase(Cell in) {
   List<TCell> list = new ArrayList<TCell>(1);
   if (in != null) {
     list.add(new TCell(ByteBuffer.wrap(CellUtil.cloneValue(in)), in.getTimestamp()));
   }
   return list;
 }
Beispiel #12
0
    /**
     * @param row 为主键,不能通过toString直接转换
     * @param value 取出后得到jack/course:english/1436449989754/Put/vlen=2/seqid=0,不能单独取出
     * @param context
     */
    @Override
    public void map(ImmutableBytesWritable row, Result value, Context context)
        throws UnsupportedEncodingException {
      context.getCounter(Counters.ROWS).increment(1);
      System.out.println(context.getCounter(Counters.ROWS).getValue());
      String s = new String(row.copyBytes(), "GB2312");
      System.out.println(s);

      List<Cell> valuelist = value.getColumnCells("course".getBytes(), "english".getBytes());
      // 得到结果为  valuelist[0] = "jack/course:english/1436449989754/Put/vlen=2/seqid=0"

      for (Cell cell : valuelist) {
        System.out.println(cell.toString());
      }
      // System.out.println(value.getColumnCells("course".getBytes(),"english".getBytes())+"\n");

    }
Beispiel #13
0
 /**
  * Add the specified KeyValue to this Put operation. Operation assumes that the passed KeyValue is
  * immutable and its backing array will not be modified for the duration of this Put.
  *
  * @param kv individual KeyValue
  * @return this
  * @throws java.io.IOException e
  */
 public Put add(Cell kv) throws IOException {
   byte[] family = CellUtil.cloneFamily(kv);
   List<Cell> list = getCellList(family);
   // Checking that the row of the kv is the same as the put
   int res =
       Bytes.compareTo(
           this.row, 0, row.length, kv.getRowArray(), kv.getRowOffset(), kv.getRowLength());
   if (res != 0) {
     throw new WrongRowIOException(
         "The row in "
             + kv.toString()
             + " doesn't match the original one "
             + Bytes.toStringBinary(this.row));
   }
   list.add(kv);
   familyMap.put(family, list);
   return this;
 }
 protected final void trackDelete(Cell cell) {
   // If keepDeletedCells is true, then we only remove cells by versions or TTL during
   // compaction, so we do not need to track delete here.
   // If keepDeletedCells is TTL and the delete marker is expired, then we can make sure that the
   // minVerions is larger than 0(otherwise we will just return at preCheck). So here we still
   // need to track the delete marker to see if it masks some cells.
   if (keepDeletedCells == KeepDeletedCells.FALSE
       || (keepDeletedCells == KeepDeletedCells.TTL && cell.getTimestamp() < oldestUnexpiredTS)) {
     deletes.add(cell);
   }
 }
  public static void main(String[] args) throws IOException {
    Configuration conf = HBaseConfiguration.create();

    HBaseHelper helper = HBaseHelper.getHelper(conf);
    helper.dropTable("testtable");
    helper.createTable("testtable", "colfam1", "colfam2");
    System.out.println("Adding rows to table...");
    helper.fillTable("testtable", 1, 10, 10, "colfam1", "colfam2");

    Connection connection = ConnectionFactory.createConnection(conf);
    Table table = connection.getTable(TableName.valueOf("testtable"));
    // vv SingleColumnValueFilterExample
    SingleColumnValueFilter filter =
        new SingleColumnValueFilter(
            Bytes.toBytes("colfam1"),
            Bytes.toBytes("col-5"),
            CompareFilter.CompareOp.NOT_EQUAL,
            new SubstringComparator("val-5"));
    filter.setFilterIfMissing(true);

    Scan scan = new Scan();
    scan.setFilter(filter);
    ResultScanner scanner = table.getScanner(scan);
    // ^^ SingleColumnValueFilterExample
    System.out.println("Results of scan:");
    // vv SingleColumnValueFilterExample
    for (Result result : scanner) {
      for (Cell cell : result.rawCells()) {
        System.out.println(
            "Cell: "
                + cell
                + ", Value: "
                + Bytes.toString(
                    cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
      }
    }
    scanner.close();

    Get get = new Get(Bytes.toBytes("row-6"));
    get.setFilter(filter);
    Result result = table.get(get);
    System.out.println("Result of get: ");
    for (Cell cell : result.rawCells()) {
      System.out.println(
          "Cell: "
              + cell
              + ", Value: "
              + Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
    }
    // ^^ SingleColumnValueFilterExample
  }
 /**
  * @param cell
  * @param out
  * @param encodingCtx
  * @return unencoded size added
  * @throws IOException
  */
 protected final int afterEncodingKeyValue(
     Cell cell, DataOutputStream out, HFileBlockDefaultEncodingContext encodingCtx)
     throws IOException {
   int size = 0;
   if (encodingCtx.getHFileContext().isIncludesTags()) {
     int tagsLength = cell.getTagsLength();
     ByteBufferUtils.putCompressedInt(out, tagsLength);
     // There are some tags to be written
     if (tagsLength > 0) {
       TagCompressionContext tagCompressionContext = encodingCtx.getTagCompressionContext();
       // When tag compression is enabled, tagCompressionContext will have a not null value. Write
       // the tags using Dictionary compression in such a case
       if (tagCompressionContext != null) {
         tagCompressionContext.compressTags(
             out, cell.getTagsArray(), cell.getTagsOffset(), tagsLength);
       } else {
         out.write(cell.getTagsArray(), cell.getTagsOffset(), tagsLength);
       }
     }
     size += tagsLength + KeyValue.TAGS_LENGTH_SIZE;
   }
   if (encodingCtx.getHFileContext().isIncludesMvcc()) {
     // Copy memstore timestamp from the byte buffer to the output stream.
     long memstoreTS = cell.getSequenceId();
     WritableUtils.writeVLong(out, memstoreTS);
     // TODO use a writeVLong which returns the #bytes written so that 2 time parsing can be
     // avoided.
     size += WritableUtils.getVIntSize(memstoreTS);
   }
   return size;
 }
 @Override
 protected boolean nextRow(ScannerContext scannerContext, Cell curRowCell) throws IOException {
   assert super.joinedContinuationRow == null : "Trying to go to next row during joinedHeap read.";
   byte[] row = new byte[curRowCell.getRowLength()];
   CellUtil.copyRowTo(curRowCell, row, 0);
   this.storeHeap.seekToPreviousRow(KeyValueUtil.createFirstOnRow(row));
   resetFilters();
   // Calling the hook in CP which allows it to do a fast forward
   if (this.region.getCoprocessorHost() != null) {
     return this.region.getCoprocessorHost().postScannerFilterRow(this, curRowCell);
   }
   return true;
 }
  @SuppressWarnings("rawtypes")
  ObserverAggregationCache buildAggrCache(
      final RegionScanner innerScanner,
      CoprocessorRowType type,
      CoprocessorProjector projector,
      ObserverAggregators aggregators,
      CoprocessorFilter filter,
      Stats stats)
      throws IOException {

    ObserverAggregationCache aggCache = new ObserverAggregationCache(aggregators);

    ObserverTuple tuple = new ObserverTuple(type);
    boolean hasMore = true;
    List<Cell> results = new ArrayList<Cell>();
    while (hasMore) {
      results.clear();
      hasMore = innerScanner.nextRaw(results);
      if (results.isEmpty()) continue;

      if (stats != null) stats.countInputRow(results);

      Cell cell = results.get(0);
      tuple.setUnderlying(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());

      if (behavior.ordinal() >= ObserverBehavior.SCAN_FILTER.ordinal()) {
        if (filter != null && filter.evaluate(tuple) == false) continue;

        if (behavior.ordinal() >= ObserverBehavior.SCAN_FILTER_AGGR.ordinal()) {
          AggrKey aggKey = projector.getAggrKey(results);
          MeasureAggregator[] bufs = aggCache.getBuffer(aggKey);
          aggregators.aggregate(bufs, results);

          aggCache.checkMemoryUsage();
        }
      }
    }
    return aggCache;
  }
 private static int findCommonPrefixInRowPart(Cell left, Cell right, int rowCommonPrefix) {
   return Bytes.findCommonPrefix(
       left.getRowArray(),
       right.getRowArray(),
       left.getRowLength() - rowCommonPrefix,
       right.getRowLength() - rowCommonPrefix,
       left.getRowOffset() + rowCommonPrefix,
       right.getRowOffset() + rowCommonPrefix);
 }
 // Having this as static is fine but if META is having DBE then we should
 // change this.
 public static int compareCommonRowPrefix(Cell left, Cell right, int rowCommonPrefix) {
   return Bytes.compareTo(
       left.getRowArray(),
       left.getRowOffset() + rowCommonPrefix,
       left.getRowLength() - rowCommonPrefix,
       right.getRowArray(),
       right.getRowOffset() + rowCommonPrefix,
       right.getRowLength() - rowCommonPrefix);
 }
 public static int compareCommonQualifierPrefix(Cell left, Cell right, int qualCommonPrefix) {
   return Bytes.compareTo(
       left.getQualifierArray(),
       left.getQualifierOffset() + qualCommonPrefix,
       left.getQualifierLength() - qualCommonPrefix,
       right.getQualifierArray(),
       right.getQualifierOffset() + qualCommonPrefix,
       right.getQualifierLength() - qualCommonPrefix);
 }
 private static int findCommonPrefixInFamilyPart(Cell left, Cell right, int familyCommonPrefix) {
   return Bytes.findCommonPrefix(
       left.getFamilyArray(),
       right.getFamilyArray(),
       left.getFamilyLength() - familyCommonPrefix,
       right.getFamilyLength() - familyCommonPrefix,
       left.getFamilyOffset() + familyCommonPrefix,
       right.getFamilyOffset() + familyCommonPrefix);
 }
 public static int compareCommonFamilyPrefix(Cell left, Cell right, int familyCommonPrefix) {
   return Bytes.compareTo(
       left.getFamilyArray(),
       left.getFamilyOffset() + familyCommonPrefix,
       left.getFamilyLength() - familyCommonPrefix,
       right.getFamilyArray(),
       right.getFamilyOffset() + familyCommonPrefix,
       right.getFamilyLength() - familyCommonPrefix);
 }
Beispiel #24
0
  @Override
  public ReturnCode filterKeyValue(Cell kv) {
    // TODO have a column compare method in Cell
    byte[] buffer = kv.getQualifierArray();
    int qualifierOffset = kv.getQualifierOffset();
    int qualifierLength = kv.getQualifierLength();
    int cmpMin = 1;

    if (this.minColumn != null) {
      cmpMin =
          Bytes.compareTo(
              buffer, qualifierOffset, qualifierLength, this.minColumn, 0, this.minColumn.length);
    }

    if (cmpMin < 0) {
      return ReturnCode.SEEK_NEXT_USING_HINT;
    }

    if (!this.minColumnInclusive && cmpMin == 0) {
      return ReturnCode.SKIP;
    }

    if (this.maxColumn == null) {
      return ReturnCode.INCLUDE;
    }

    int cmpMax =
        Bytes.compareTo(
            buffer, qualifierOffset, qualifierLength, this.maxColumn, 0, this.maxColumn.length);

    if (this.maxColumnInclusive && cmpMax <= 0 || !this.maxColumnInclusive && cmpMax < 0) {
      return ReturnCode.INCLUDE;
    }

    return ReturnCode.NEXT_ROW;
  }
 private static int findCommonPrefixInQualifierPart(
     Cell left, Cell right, int qualifierCommonPrefix) {
   return Bytes.findCommonPrefix(
       left.getQualifierArray(),
       right.getQualifierArray(),
       left.getQualifierLength() - qualifierCommonPrefix,
       right.getQualifierLength() - qualifierCommonPrefix,
       left.getQualifierOffset() + qualifierCommonPrefix,
       right.getQualifierOffset() + qualifierCommonPrefix);
 }
 /**
  * Find the column index which will replace the column name in the aggregated array and will be
  * restored in Reducer
  *
  * @param cell KeyValue for the column
  * @return column index for the specified cell or -1 if was not found
  */
 private int findIndex(Cell cell) throws IOException {
   byte[] familyName =
       Bytes.copy(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
   byte[] name =
       Bytes.copy(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
   byte[] cfn = Bytes.add(familyName, QueryConstants.NAMESPACE_SEPARATOR_BYTES, name);
   if (columnIndexes.containsKey(cfn)) {
     return columnIndexes.get(cfn);
   }
   return -1;
 }
 private int compareTypeBytes(Cell key, Cell right) {
   if (key.getFamilyLength() + key.getQualifierLength() == 0
       && key.getTypeByte() == Type.Minimum.getCode()) {
     // left is "bigger", i.e. it appears later in the sorted order
     return 1;
   }
   if (right.getFamilyLength() + right.getQualifierLength() == 0
       && right.getTypeByte() == Type.Minimum.getCode()) {
     return -1;
   }
   return 0;
 }
 @Override
 public Cell getNextCellHint(Cell kv) {
   return KeyValueUtil.createFirstOnRow(
       kv.getRowArray(),
       kv.getRowOffset(),
       kv.getRowLength(),
       kv.getFamilyArray(),
       kv.getFamilyOffset(),
       kv.getFamilyLength(),
       hint,
       0,
       hint.length);
 }
Beispiel #29
0
 @Override
 public Cell getNextCellHint(Cell kv) {
   return KeyValue.createFirstOnRow(
       kv.getRowArray(),
       kv.getRowOffset(),
       kv.getRowLength(),
       kv.getFamilyArray(),
       kv.getFamilyOffset(),
       kv.getFamilyLength(),
       this.minColumn,
       0,
       len(this.minColumn));
 }
    @Override
    public int seekToKeyInBlock(Cell seekCell, boolean seekBefore) {
      int rowCommonPrefix = 0;
      int familyCommonPrefix = 0;
      int qualCommonPrefix = 0;
      previous.invalidate();
      do {
        int comp;
        keyOnlyKV.setKey(current.keyBuffer, 0, current.keyLength);
        if (current.lastCommonPrefix != 0) {
          // The KV format has row key length also in the byte array. The
          // common prefix
          // includes it. So we need to subtract to find out the common prefix
          // in the
          // row part alone
          rowCommonPrefix = Math.min(rowCommonPrefix, current.lastCommonPrefix - 2);
        }
        if (current.lastCommonPrefix <= 2) {
          rowCommonPrefix = 0;
        }
        rowCommonPrefix += findCommonPrefixInRowPart(seekCell, keyOnlyKV, rowCommonPrefix);
        comp = compareCommonRowPrefix(seekCell, keyOnlyKV, rowCommonPrefix);
        if (comp == 0) {
          comp = compareTypeBytes(seekCell, keyOnlyKV);
          if (comp == 0) {
            // Subtract the fixed row key length and the family key fixed length
            familyCommonPrefix =
                Math.max(
                    0,
                    Math.min(
                        familyCommonPrefix,
                        current.lastCommonPrefix - (3 + keyOnlyKV.getRowLength())));
            familyCommonPrefix +=
                findCommonPrefixInFamilyPart(seekCell, keyOnlyKV, familyCommonPrefix);
            comp = compareCommonFamilyPrefix(seekCell, keyOnlyKV, familyCommonPrefix);
            if (comp == 0) {
              // subtract the rowkey fixed length and the family key fixed
              // length
              qualCommonPrefix =
                  Math.max(
                      0,
                      Math.min(
                          qualCommonPrefix,
                          current.lastCommonPrefix
                              - (3 + keyOnlyKV.getRowLength() + keyOnlyKV.getFamilyLength())));
              qualCommonPrefix +=
                  findCommonPrefixInQualifierPart(seekCell, keyOnlyKV, qualCommonPrefix);
              comp = compareCommonQualifierPrefix(seekCell, keyOnlyKV, qualCommonPrefix);
              if (comp == 0) {
                comp = CellComparator.compareTimestamps(seekCell, keyOnlyKV);
                if (comp == 0) {
                  // Compare types. Let the delete types sort ahead of puts;
                  // i.e. types
                  // of higher numbers sort before those of lesser numbers.
                  // Maximum
                  // (255)
                  // appears ahead of everything, and minimum (0) appears
                  // after
                  // everything.
                  comp = (0xff & keyOnlyKV.getTypeByte()) - (0xff & seekCell.getTypeByte());
                }
              }
            }
          }
        }
        if (comp == 0) { // exact match
          if (seekBefore) {
            if (!previous.isValid()) {
              // The caller (seekBefore) has to ensure that we are not at the
              // first key in the block.
              throw new IllegalStateException(
                  "Cannot seekBefore if "
                      + "positioned at the first key in the block: key="
                      + Bytes.toStringBinary(seekCell.getRowArray()));
            }
            moveToPrevious();
            return 1;
          }
          return 0;
        }

        if (comp < 0) { // already too large, check previous
          if (previous.isValid()) {
            moveToPrevious();
          } else {
            return HConstants.INDEX_KEY_MAGIC; // using optimized index key
          }
          return 1;
        }

        // move to next, if more data is available
        if (currentBuffer.hasRemaining()) {
          previous.copyFromNext(current);
          decodeNext();
          current.setKey(current.keyBuffer, current.memstoreTS);
        } else {
          break;
        }
      } while (true);

      // we hit the end of the block, not an exact match
      return 1;
    }