org.apache.hadoop.hbase.Cell#getTimestamp ( )源码实例Demo

下面列出了org.apache.hadoop.hbase.Cell#getTimestamp ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

@Override
public Cell transformCell(Cell cell) throws IOException {
  // Convert Tephra deletes back into HBase deletes
  if (tx.getVisibilityLevel() == Transaction.VisibilityLevel.SNAPSHOT_ALL) {
    if (DeleteTracker.isFamilyDelete(cell)) {
      return new KeyValue(CellUtil.cloneRow(cell), CellUtil.cloneFamily(cell), null, cell.getTimestamp(),
                          KeyValue.Type.DeleteFamily);
    } else if (isColumnDelete(cell)) {
      // Note: in some cases KeyValue.Type.Delete is used in Delete object,
      // and in some other cases KeyValue.Type.DeleteColumn is used.
      // Since Tephra cannot distinguish between the two, we return KeyValue.Type.DeleteColumn.
      // KeyValue.Type.DeleteColumn makes both CellUtil.isDelete and CellUtil.isDeleteColumns return true, and will
      // work in both cases.
      return new KeyValue(CellUtil.cloneRow(cell), CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell),
                          cell.getTimestamp(), KeyValue.Type.DeleteColumn);
    }
  }
  return cell;
}
 
源代码2 项目: phoenix-tephra   文件: DataJanitorState.java
/**
 * Gets a list of {@link RegionPruneInfo} for given regions. Returns all regions if the given regions set is null.
 *
 * @param regions a set of regions
 * @return list of {@link RegionPruneInfo}s.
 * @throws IOException when not able to read the data from HBase
 */
public List<RegionPruneInfo> getPruneInfoForRegions(@Nullable SortedSet<byte[]> regions) throws IOException {
  List<RegionPruneInfo> regionPruneInfos = new ArrayList<>();
  try (Table stateTable = stateTableSupplier.get()) {
    byte[] startRow = makeRegionKey(EMPTY_BYTE_ARRAY);
    Scan scan = new Scan(startRow, REGION_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, PRUNE_UPPER_BOUND_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] region = getRegionFromKey(next.getRow());
        if (regions == null || regions.contains(region)) {
          Cell cell = next.getColumnLatestCell(FAMILY, PRUNE_UPPER_BOUND_COL);
          if (cell != null) {
            byte[] pruneUpperBoundBytes = CellUtil.cloneValue(cell);
            long timestamp = cell.getTimestamp();
            regionPruneInfos.add(new RegionPruneInfo(region, Bytes.toStringBinary(region),
                                                     Bytes.toLong(pruneUpperBoundBytes), timestamp));
          }
        }
      }
    }
  }
  return Collections.unmodifiableList(regionPruneInfos);
}
 
源代码3 项目: phoenix-tephra   文件: DataJanitorState.java
/**
 * Gets a list of {@link RegionPruneInfo} for given regions. Returns all regions if the given regions set is null.
 *
 * @param regions a set of regions
 * @return list of {@link RegionPruneInfo}s.
 * @throws IOException when not able to read the data from HBase
 */
public List<RegionPruneInfo> getPruneInfoForRegions(@Nullable SortedSet<byte[]> regions) throws IOException {
  List<RegionPruneInfo> regionPruneInfos = new ArrayList<>();
  try (Table stateTable = stateTableSupplier.get()) {
    byte[] startRow = makeRegionKey(EMPTY_BYTE_ARRAY);
    Scan scan = new Scan(startRow, REGION_KEY_PREFIX_STOP);
    scan.addColumn(FAMILY, PRUNE_UPPER_BOUND_COL);

    try (ResultScanner scanner = stateTable.getScanner(scan)) {
      Result next;
      while ((next = scanner.next()) != null) {
        byte[] region = getRegionFromKey(next.getRow());
        if (regions == null || regions.contains(region)) {
          Cell cell = next.getColumnLatestCell(FAMILY, PRUNE_UPPER_BOUND_COL);
          if (cell != null) {
            byte[] pruneUpperBoundBytes = CellUtil.cloneValue(cell);
            long timestamp = cell.getTimestamp();
            regionPruneInfos.add(new RegionPruneInfo(region, Bytes.toStringBinary(region),
                                                     Bytes.toLong(pruneUpperBoundBytes), timestamp));
          }
        }
      }
    }
  }
  return Collections.unmodifiableList(regionPruneInfos);
}
 
@Override
public Cell transformCell(Cell cell) throws IOException {
  // Convert Tephra deletes back into HBase deletes
  if (tx.getVisibilityLevel() == Transaction.VisibilityLevel.SNAPSHOT_ALL) {
    if (DeleteTracker.isFamilyDelete(cell)) {
      return new KeyValue(CellUtil.cloneRow(cell), CellUtil.cloneFamily(cell), null, cell.getTimestamp(),
                          KeyValue.Type.DeleteFamily);
    } else if (isColumnDelete(cell)) {
      // Note: in some cases KeyValue.Type.Delete is used in Delete object,
      // and in some other cases KeyValue.Type.DeleteColumn is used.
      // Since Tephra cannot distinguish between the two, we return KeyValue.Type.DeleteColumn.
      // KeyValue.Type.DeleteColumn makes both CellUtil.isDelete and CellUtil.isDeleteColumns return true, and will
      // work in both cases.
      return new KeyValue(CellUtil.cloneRow(cell), CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell),
                          cell.getTimestamp(), KeyValue.Type.DeleteColumn);
    }
  }
  return cell;
}
 
源代码5 项目: hbase-tools   文件: CommandAdapter.java
public static Map<String, Map<String, String>> versionedRegionMap(HBaseAdmin admin, long timestamp)
    throws IOException {
    Map<String, Map<String, String>> regionLocationMap = new HashMap<>();
    try (HTable metaTable = new HTable(admin.getConfiguration(), metaTableName())) {
        Scan scan = new Scan();
        scan.setSmall(true);
        scan.setCaching(1000);
        scan.setMaxVersions();
        ResultScanner scanner = metaTable.getScanner(scan);
        for (Result result : scanner) {
            List<Cell> columnCells = result.getColumnCells("info".getBytes(), "server".getBytes());
            for (Cell cell : columnCells) {
                if (cell.getTimestamp() <= timestamp) {
                    String tableName = Bytes.toString(HRegionInfo.getTableName(cell.getRow()));
                    String encodeRegionName = HRegionInfo.encodeRegionName(cell.getRow());
                    String regionServer = Bytes.toString(cell.getValue()).replaceAll(":", ",");

                    Map<String, String> innerMap = regionLocationMap.get(tableName);
                    if (innerMap == null) {
                        innerMap = new HashMap<>();
                        regionLocationMap.put(tableName, innerMap);
                    }
                    if (innerMap.get(encodeRegionName) == null)
                        innerMap.put(encodeRegionName, regionServer);
                }
            }
        }
    }
    return regionLocationMap;
}
 
源代码6 项目: phoenix   文件: UpgradeUtil.java
@SuppressWarnings("deprecation")
private static KeyValue addSaltByte(Cell keyValue, int nSaltBuckets) {
    byte[] buf = keyValue.getRowArray();
    int length = keyValue.getRowLength();
    int offset = keyValue.getRowOffset();
    boolean isViewSeq = length > SEQ_PREFIX_BYTES.length && Bytes.compareTo(SEQ_PREFIX_BYTES, 0, SEQ_PREFIX_BYTES.length, buf, offset, SEQ_PREFIX_BYTES.length) == 0;
    if (!isViewSeq && nSaltBuckets == 0) {
        return null;
    }
    byte[] newBuf;
    if (isViewSeq) { // We messed up the name for the sequences for view indexes so we'll take this opportunity to fix it
        if (buf[length-1] == 0) { // Global indexes on views have trailing null byte
            length--;
        }
        byte[][] rowKeyMetaData = new byte[3][];
        SchemaUtil.getVarChars(buf, offset, length, 0, rowKeyMetaData);
        byte[] schemaName = rowKeyMetaData[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX];
        byte[] unprefixedSchemaName = new byte[schemaName.length - MetaDataUtil.VIEW_INDEX_SEQUENCE_PREFIX_BYTES.length];
        System.arraycopy(schemaName, MetaDataUtil.VIEW_INDEX_SEQUENCE_PREFIX_BYTES.length, unprefixedSchemaName, 0, unprefixedSchemaName.length);
        byte[] tableName = rowKeyMetaData[PhoenixDatabaseMetaData.TABLE_NAME_INDEX];
        PName physicalName = PNameFactory.newName(unprefixedSchemaName);
        // Reformulate key based on correct data
        newBuf = MetaDataUtil.getViewIndexSequenceKey(tableName == null ? null : Bytes.toString(tableName),
                physicalName, nSaltBuckets, false).getKey();
    } else {
        newBuf = new byte[length + 1];
        System.arraycopy(buf, offset, newBuf, SaltingUtil.NUM_SALTING_BYTES, length);
        newBuf[0] = SaltingUtil.getSaltingByte(newBuf, SaltingUtil.NUM_SALTING_BYTES, length, nSaltBuckets);
    }
    return new KeyValue(newBuf, 0, newBuf.length,
            buf, keyValue.getFamilyOffset(), keyValue.getFamilyLength(),
            buf, keyValue.getQualifierOffset(), keyValue.getQualifierLength(),
            keyValue.getTimestamp(), KeyValue.Type.codeToType(keyValue.getTypeByte()),
            buf, keyValue.getValueOffset(), keyValue.getValueLength());
}
 
源代码7 项目: hbase   文件: CompactionScanQueryMatcher.java
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);
  }
}
 
源代码8 项目: simplified-lambda   文件: SimplifiedLambda.java
public long getTimestampForKey(String key, byte[] column) throws IOException {
    Cell cell = getCell(key, column);

    if (cell != null) {
        return cell.getTimestamp();
    } else {
        throw new IOException("Cannot retrieve string from hbase");
    }
}
 
源代码9 项目: phoenix-tephra   文件: TransactionProcessor.java
@Override
public ReturnCode filterKeyValue(Cell cell) throws IOException {
  // include all cells visible to in-progress transactions, except for those already
  // marked as invalid
  long ts = cell.getTimestamp();
  if (ts > visibilityUpperBound) {
    // include everything that could still be in-progress except invalids
    if (invalidIds.contains(ts)) {
      return ReturnCode.SKIP;
    }
    return ReturnCode.INCLUDE;
  }
  return txFilter.filterKeyValue(cell);
}
 
源代码10 项目: phoenix   文件: GlobalIndexRegionScanner.java
public static long getTimestamp(Mutation m) {
    for (List<Cell> cells : m.getFamilyCellMap().values()) {
        for (Cell cell : cells) {
            return cell.getTimestamp();
        }
    }
    throw new IllegalStateException("No cell found");
}
 
源代码11 项目: phoenix   文件: Sequence.java
public long createSequence(Result result, long minValue, long maxValue, boolean cycle) throws SQLException {
    Cell statusKV = result.rawCells()[0];
    long timestamp = statusKV.getTimestamp();
    int statusCode = PInteger.INSTANCE.getCodec().decodeInt(statusKV.getValueArray(), statusKV.getValueOffset(), SortOrder.getDefault());
    if (statusCode == 0) {  // Success - add sequence value and return timestamp
        SequenceValue value = new SequenceValue(timestamp, minValue, maxValue, cycle);
        insertSequenceValue(value);
        return timestamp;
    }
    SQLExceptionCode code = SQLExceptionCode.fromErrorCode(statusCode);
    throw new SQLExceptionInfo.Builder(code)
        .setSchemaName(key.getSchemaName())
        .setTableName(key.getSequenceName())
        .build().buildException();
}
 
源代码12 项目: phoenix-tephra   文件: TransactionProcessor.java
@Override
public ReturnCode filterKeyValue(Cell cell) throws IOException {
  // include all cells visible to in-progress transactions, except for those already marked as invalid
  long ts = cell.getTimestamp();
  if (ts > visibilityUpperBound) {
    // include everything that could still be in-progress except invalids
    if (invalidIds.contains(ts)) {
      return ReturnCode.SKIP;
    }
    return ReturnCode.INCLUDE;
  }
  return txFilter.filterKeyValue(cell);
}
 
源代码13 项目: phoenix   文件: GlobalIndexRegionScanner.java
public static long getMaxTimestamp(Mutation m) {
    long ts = 0;
    for (List<Cell> cells : m.getFamilyCellMap().values()) {
        if (cells == null) {
            continue;
        }
        for (Cell cell : cells) {
            if (ts < cell.getTimestamp()) {
                ts = cell.getTimestamp();
            }
        }
    }
    return ts;
}
 
@Override
public ReturnCode filterKeyValue(Cell v) {
  long timestamp = v.getTimestamp();
  if (timestamp > ts) {
    this.column.setTs(timestamp);
    return ReturnCode.SKIP;
  }
  return ReturnCode.INCLUDE;
}
 
@Override
public ReturnCode filterKeyValue(Cell cell) throws IOException {
  if (!CellUtil.matchingFamily(cell, currentFamily.get(), currentFamily.getOffset(), currentFamily.getLength())) {
    // column family changed
    currentFamily.set(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
    Long familyOldestTs = oldestTsByFamily.get(currentFamily);
    currentOldestTs = familyOldestTs != null ? familyOldestTs : 0;
    deleteTracker.reset();
  }
  // need to apply TTL for the column family here
  long kvTimestamp = cell.getTimestamp();
  if (TxUtils.getTimestampForTTL(kvTimestamp) < currentOldestTs) {
    // passed TTL for this column, seek to next
    return ReturnCode.NEXT_COL;
  } else if (tx.isVisible(kvTimestamp)) {
    // Return all writes done by current transaction (including deletes) for VisibilityLevel.SNAPSHOT_ALL
    if (tx.getVisibilityLevel() == Transaction.VisibilityLevel.SNAPSHOT_ALL && tx.isCurrentWrite(kvTimestamp)) {
      // cell is visible
      // visibility SNAPSHOT_ALL needs all matches
      return runSubFilter(ReturnCode.INCLUDE, cell);
    }
    if (DeleteTracker.isFamilyDelete(cell)) {
      deleteTracker.addFamilyDelete(cell);
      if (clearDeletes) {
        return ReturnCode.NEXT_COL;
      } else {
        // cell is visible
        // as soon as we find a KV to include we can move to the next column
        return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
      }
    }
    // check if masked by family delete
    if (deleteTracker.isDeleted(cell)) {
      return ReturnCode.NEXT_COL;
    }
    // check for column delete
    if (isColumnDelete(cell)) {
      if (clearDeletes) {
        // skip "deleted" cell
        return ReturnCode.NEXT_COL;
      } else {
        // keep the marker but skip any remaining versions
        return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
      }
    }
    // cell is visible
    // as soon as we find a KV to include we can move to the next column
    return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
  } else {
    return ReturnCode.SKIP;
  }
}
 
源代码16 项目: cloud-bigtable-examples   文件: HBaseCLI.java
public void run(Connection connection, List<String> args) throws InvalidArgsException, IOException {
    if (args.size() < 1 || args.size() > 2) {
        throw new InvalidArgsException(args);
    }
    String tableName = args.get(0);
    String filterVal = null;
    if (args.size() > 1) {
        filterVal = args.get(1);
    }

    Table table = connection.getTable(TableName.valueOf(tableName));

    // Create a new Scan instance.
    Scan scan = new Scan();

    // This command supports using a columnvalue filter.
    // The filter takes the form of <columnfamily>:<column><operator><value>
    // An example would be cf:col>=10
    if (filterVal != null) {
        String splitVal = "=";
        CompareFilter.CompareOp op = CompareFilter.CompareOp.EQUAL;

        if (filterVal.contains(">=")) {
             op = CompareFilter.CompareOp.GREATER_OR_EQUAL;
             splitVal = ">=";
        } else if (filterVal.contains("<=")) {
             op = CompareFilter.CompareOp.LESS_OR_EQUAL;
             splitVal = "<=";
        } else if (filterVal.contains(">")) {
             op = CompareFilter.CompareOp.GREATER;
             splitVal = ">";
        } else if (filterVal.contains("<")) {
             op = CompareFilter.CompareOp.LESS;
             splitVal = "<";
        }
        String[] filter = filterVal.split(splitVal);
        String[] filterCol = filter[0].split(":");
        scan.setFilter(new SingleColumnValueFilter(filterCol[0].getBytes(), filterCol[1].getBytes(), op, filter[1].getBytes()));
    }
    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result : resultScanner) {
        for (Cell cell : result.listCells()) {
            String row = new String(CellUtil.cloneRow(cell));
            String family = new String(CellUtil.cloneFamily(cell));
            String column = new String(CellUtil.cloneQualifier(cell));
            String value = new String(CellUtil.cloneValue(cell));
            long timestamp = cell.getTimestamp();
            System.out.printf("%-20s column=%s:%s, timestamp=%s, value=%s\n", row, family, column, timestamp, value);
        }
    }
}
 
源代码17 项目: hbase   文件: StoreFileScanner.java
/**
 * Pretend we have done a seek but don't do it yet, if possible. The hope is
 * that we find requested columns in more recent files and won't have to seek
 * in older files. Creates a fake key/value with the given row/column and the
 * highest (most recent) possible timestamp we might get from this file. When
 * users of such "lazy scanner" need to know the next KV precisely (e.g. when
 * this scanner is at the top of the heap), they run {@link #enforceSeek()}.
 * <p>
 * Note that this function does guarantee that the current KV of this scanner
 * will be advanced to at least the given KV. Because of this, it does have
 * to do a real seek in cases when the seek timestamp is older than the
 * highest timestamp of the file, e.g. when we are trying to seek to the next
 * row/column and use OLDEST_TIMESTAMP in the seek key.
 */
@Override
public boolean requestSeek(Cell kv, boolean forward, boolean useBloom)
    throws IOException {
  if (kv.getFamilyLength() == 0) {
    useBloom = false;
  }

  boolean haveToSeek = true;
  if (useBloom) {
    // check ROWCOL Bloom filter first.
    if (reader.getBloomFilterType() == BloomType.ROWCOL) {
      haveToSeek = reader.passesGeneralRowColBloomFilter(kv);
    } else if (canOptimizeForNonNullColumn
        && ((PrivateCellUtil.isDeleteFamily(kv)
            || PrivateCellUtil.isDeleteFamilyVersion(kv)))) {
      // if there is no such delete family kv in the store file,
      // then no need to seek.
      haveToSeek = reader.passesDeleteFamilyBloomFilter(kv.getRowArray(), kv.getRowOffset(),
        kv.getRowLength());
    }
  }

  delayedReseek = forward;
  delayedSeekKV = kv;

  if (haveToSeek) {
    // This row/column might be in this store file (or we did not use the
    // Bloom filter), so we still need to seek.
    realSeekDone = false;
    long maxTimestampInFile = reader.getMaxTimestamp();
    long seekTimestamp = kv.getTimestamp();
    if (seekTimestamp > maxTimestampInFile) {
      // Create a fake key that is not greater than the real next key.
      // (Lower timestamps correspond to higher KVs.)
      // To understand this better, consider that we are asked to seek to
      // a higher timestamp than the max timestamp in this file. We know that
      // the next point when we have to consider this file again is when we
      // pass the max timestamp of this file (with the same row/column).
      setCurrentCell(PrivateCellUtil.createFirstOnRowColTS(kv, maxTimestampInFile));
    } else {
      // This will be the case e.g. when we need to seek to the next
      // row/column, and we don't know exactly what they are, so we set the
      // seek key's timestamp to OLDEST_TIMESTAMP to skip the rest of this
      // row/column.
      enforceSeek();
    }
    return cur != null;
  }

  // Multi-column Bloom filter optimization.
  // Create a fake key/value, so that this scanner only bubbles up to the top
  // of the KeyValueHeap in StoreScanner after we scanned this row/column in
  // all other store files. The query matcher will then just skip this fake
  // key/value and the store scanner will progress to the next column. This
  // is obviously not a "real real" seek, but unlike the fake KV earlier in
  // this method, we want this to be propagated to ScanQueryMatcher.
  setCurrentCell(PrivateCellUtil.createLastOnRowCol(kv));

  realSeekDone = true;
  return true;
}
 
@Override
public ReturnCode filterKeyValue(Cell cell) throws IOException {
  if (!CellUtil.matchingFamily(cell, currentFamily.get(), currentFamily.getOffset(), currentFamily.getLength())) {
    // column family changed
    currentFamily.set(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
    Long familyOldestTs = oldestTsByFamily.get(currentFamily);
    currentOldestTs = familyOldestTs != null ? familyOldestTs : 0;
    deleteTracker.reset();
  }
  // need to apply TTL for the column family here
  long kvTimestamp = cell.getTimestamp();
  if (TxUtils.getTimestampForTTL(kvTimestamp) < currentOldestTs) {
    // passed TTL for this column, seek to next
    return ReturnCode.NEXT_COL;
  } else if (tx.isVisible(kvTimestamp)) {
    // Return all writes done by current transaction (including deletes) for VisibilityLevel.SNAPSHOT_ALL
    if (tx.getVisibilityLevel() == Transaction.VisibilityLevel.SNAPSHOT_ALL && tx.isCurrentWrite(kvTimestamp)) {
      // cell is visible
      // visibility SNAPSHOT_ALL needs all matches
      return runSubFilter(ReturnCode.INCLUDE, cell);
    }
    if (DeleteTracker.isFamilyDelete(cell)) {
      deleteTracker.addFamilyDelete(cell);
      if (clearDeletes) {
        return ReturnCode.NEXT_COL;
      } else {
        // cell is visible
        // as soon as we find a KV to include we can move to the next column
        return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
      }
    }
    // check if masked by family delete
    if (deleteTracker.isDeleted(cell)) {
      return ReturnCode.NEXT_COL;
    }
    // check for column delete
    if (isColumnDelete(cell)) {
      if (clearDeletes) {
        // skip "deleted" cell
        return ReturnCode.NEXT_COL;
      } else {
        // keep the marker but skip any remaining versions
        return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
      }
    }
    // cell is visible
    // as soon as we find a KV to include we can move to the next column
    return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
  } else {
    return ReturnCode.SKIP;
  }
}
 
源代码19 项目: phoenix   文件: StatisticsWriter.java
public void splitStats(HRegion p, HRegion l, HRegion r, StatisticsCollector tracker, ImmutableBytesPtr cfKey,
        List<Mutation> mutations) throws IOException {
    if (tracker == null) { return; }
    boolean useMaxTimeStamp = clientTimeStamp == StatisticsCollector.NO_TIMESTAMP;
    if (!useMaxTimeStamp) {
        mutations.add(getLastStatsUpdatedTimePut(clientTimeStamp));
    }
    long readTimeStamp = useMaxTimeStamp ? HConstants.LATEST_TIMESTAMP : clientTimeStamp;
    Result result = StatisticsUtil.readRegionStatistics(statsReaderTable, tableName, cfKey, p.getRegionName(),
            readTimeStamp);
    if (result != null && !result.isEmpty()) {
    	Cell cell = result.getColumnLatestCell(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, PhoenixDatabaseMetaData.GUIDE_POSTS_BYTES);
    	Cell rowCountCell = result.getColumnLatestCell(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES, PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT_BYTES);
        long rowCount = 0;
    	if (cell != null) {
            long writeTimeStamp = useMaxTimeStamp ? cell.getTimestamp() : clientTimeStamp;

            GuidePostsInfo guidePostsRegionInfo = GuidePostsInfo.deserializeGuidePostsInfo(cell.getValueArray(),
                    cell.getValueOffset(), cell.getValueLength(), rowCount);
            byte[] pPrefix = StatisticsUtil.getRowKey(tableName, cfKey, p.getRegionName());
            mutations.add(new Delete(pPrefix, writeTimeStamp));
            
     	long byteSize = 0;
            Cell byteSizeCell = result.getColumnLatestCell(QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES,
                    PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH_BYTES);
            int index = Collections.binarySearch(guidePostsRegionInfo.getGuidePosts(), r.getStartKey(),
                    Bytes.BYTES_COMPARATOR);
            int size = guidePostsRegionInfo.getGuidePosts().size();
            int midEndIndex, midStartIndex;
            if (index < 0) {
                midEndIndex = midStartIndex = -(index + 1);
            } else {
                // For an exact match, we want to get rid of the exact match guidepost,
                // since it's replaced by the region boundary.
                midEndIndex = index;
                midStartIndex = index + 1;
            }
            double per = (double)(midEndIndex) / size;
            long leftRowCount = 0;
            long rightRowCount = 0;
            long leftByteCount = 0;
            long rightByteCount = 0;
            if (rowCountCell != null) {
                rowCount = PLong.INSTANCE.getCodec().decodeLong(rowCountCell.getValueArray(),
                        rowCountCell.getValueOffset(), SortOrder.getDefault());
                leftRowCount = (long)(per * rowCount);
                rightRowCount = (long)((1 - per) * rowCount);
            }
            if (byteSizeCell != null) {
                byteSize = PLong.INSTANCE.getCodec().decodeLong(byteSizeCell.getValueArray(),
                        byteSizeCell.getValueOffset(), SortOrder.getDefault());
                leftByteCount = (long)(per * byteSize);
                rightByteCount = (long)((1 - per) * byteSize);
            }
         if (midEndIndex > 0) {
             GuidePostsInfo lguidePosts = new GuidePostsInfo(leftByteCount, guidePostsRegionInfo
                        .getGuidePosts().subList(0, midEndIndex), leftRowCount);
                tracker.clear();
             tracker.addGuidePost(cfKey, lguidePosts, leftByteCount, cell.getTimestamp());
             addStats(l.getRegionName(), tracker, cfKey, mutations);
         }
         if (midStartIndex < size) {
             GuidePostsInfo rguidePosts = new GuidePostsInfo(rightByteCount, guidePostsRegionInfo
                        .getGuidePosts().subList(midStartIndex, size),
                        rightRowCount);
             tracker.clear();
             tracker.addGuidePost(cfKey, rguidePosts, rightByteCount, cell.getTimestamp());
             addStats(r.getRegionName(), tracker, cfKey, mutations);
         }
    	}
    }
}
 
@Override
public ReturnCode filterKeyValue(Cell cell) throws IOException {
  if (!CellUtil.matchingFamily(cell, currentFamily)) {
    // column family changed
    currentFamily = CellUtil.cloneFamily(cell);
    Long familyOldestTs = oldestTsByFamily.get(currentFamily);
    currentOldestTs = familyOldestTs != null ? familyOldestTs : 0;
    deleteTracker.reset();
  }
  // need to apply TTL for the column family here
  long kvTimestamp = cell.getTimestamp();
  if (TxUtils.getTimestampForTTL(kvTimestamp) < currentOldestTs) {
    // passed TTL for this column, seek to next
    return ReturnCode.NEXT_COL;
  } else if (tx.isVisible(kvTimestamp)) {
    // Return all writes done by current transaction (including deletes) for VisibilityLevel.SNAPSHOT_ALL
    if (tx.getVisibilityLevel() == Transaction.VisibilityLevel.SNAPSHOT_ALL && tx.isCurrentWrite(kvTimestamp)) {
      // cell is visible
      // visibility SNAPSHOT_ALL needs all matches
      return runSubFilter(ReturnCode.INCLUDE, cell);
    }
    if (DeleteTracker.isFamilyDelete(cell)) {
      deleteTracker.addFamilyDelete(cell);
      if (clearDeletes) {
        return ReturnCode.NEXT_COL;
      } else {
        // cell is visible
        // as soon as we find a KV to include we can move to the next column
        return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
      }
    }
    // check if masked by family delete
    if (deleteTracker.isDeleted(cell)) {
      return ReturnCode.NEXT_COL;
    }
    // check for column delete
    if (isColumnDelete(cell)) {
      if (clearDeletes) {
        // skip "deleted" cell
        return ReturnCode.NEXT_COL;
      } else {
        // keep the marker but skip any remaining versions
        return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
      }
    }
    // cell is visible
    // as soon as we find a KV to include we can move to the next column
    return runSubFilter(ReturnCode.INCLUDE_AND_NEXT_COL, cell);
  } else {
    return ReturnCode.SKIP;
  }
}