// Called between every row.
 public void reset() {
   this.index = 0;
   this.column = this.columns[this.index];
   for (ColumnCount col : this.columns) {
     col.setCount(0);
   }
   resetTS();
 }
  /** {@inheritDoc} */
  @Override
  public ScanQueryMatcher.MatchCode checkColumn(Cell cell, byte type) {
    // delete markers should never be passed to an
    // *Explicit*ColumnTracker
    assert !CellUtil.isDelete(type);
    do {
      // No more columns left, we are done with this query
      if (done()) {
        return ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW; // done_row
      }

      // No more columns to match against, done with storefile
      if (this.column == null) {
        return ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW; // done_row
      }

      // Compare specific column to current column
      int ret =
          CellComparator.compareQualifiers(
              cell, column.getBuffer(), column.getOffset(), column.getLength());

      // Column Matches. Return include code. The caller would call checkVersions
      // to limit the number of versions.
      if (ret == 0) {
        return ScanQueryMatcher.MatchCode.INCLUDE;
      }

      resetTS();

      if (ret < 0) {
        // The current KV is smaller than the column the ExplicitColumnTracker
        // is interested in, so seek to that column of interest.
        return ScanQueryMatcher.MatchCode.SEEK_NEXT_COL;
      }

      // The current KV is bigger than the column the ExplicitColumnTracker
      // is interested in. That means there is no more data for the column
      // of interest. Advance the ExplicitColumnTracker state to next
      // column of interest, and check again.
      if (ret > 0) {
        ++this.index;
        if (done()) {
          // No more to match, do not include, done with this row.
          return ScanQueryMatcher.MatchCode.SEEK_NEXT_ROW; // done_row
        }
        // This is the recursive case.
        this.column = this.columns[this.index];
      }
    } while (true);
  }
 /**
  * This method is used to inform the column tracker that we are done with this column. We may get
  * this information from external filters or timestamp range and we then need to indicate this
  * information to tracker. It is required only in case of ExplicitColumnTracker.
  *
  * @param cell
  */
 public void doneWithColumn(Cell cell) {
   while (this.column != null) {
     int compare =
         CellComparator.compareQualifiers(
             cell, column.getBuffer(), column.getOffset(), column.getLength());
     resetTS();
     if (compare >= 0) {
       ++this.index;
       if (done()) {
         // Will not hit any more columns in this storefile
         this.column = null;
       } else {
         this.column = this.columns[this.index];
       }
       if (compare > 0) {
         continue;
       }
     }
     return;
   }
 }