protected int computeStartPreceding(int rowIdx, PTFPartition p) throws HiveException {
    int amt = start.getAmt();
    // Use Case 1.
    if ( amt == BoundarySpec.UNBOUNDED_AMOUNT ) {
      return 0;
    }
    Object sortKey = computeValueUseCache(rowIdx, p);

    if ( sortKey == null ) {
      // Use Case 3.
      if (nullsLast || expressionDef.getOrder() == Order.DESC) {
        while ( sortKey == null && rowIdx >= 0 ) {
          Pair<Integer, Object> stepResult = skipOrStepBack(rowIdx, p);
          rowIdx = stepResult.getLeft();
          sortKey = stepResult.getRight();
        }
        return rowIdx + 1;
      }
      else { // Use Case 2.
        if ( expressionDef.getOrder() == Order.ASC ) {
          return 0;
        }
      }
    }

    // Use Case 4,5
    if (enableBinarySearch) {
      return binarySearchBack(rowIdx, p, sortKey, amt, expressionDef.getOrder());
    } else {
      return linearSearchBack(rowIdx, p, sortKey, amt, expressionDef.getOrder());
    }
  }
Uses cache to lookup row value. Computes it on the fly on cache miss.
@param r
@param p
@return row value.
@throws HiveException
ql/src/java/org/apache/hadoop/hive/ql/udf/ptf/ValueBoundaryScanner.java