@Test
  public void testPrefixScanning() throws IOException {
    final TableName tableName = TableName.valueOf(name.getMethodName());
    createTable(tableName, "F");
    Table table = openTable(tableName);

    /**
     * Note that about half of these tests were relevant for a different implementation approach of
     * setStartStopRowForPrefixScan. These test cases have been retained to ensure that also the
     * edge cases found there are still covered.
     */

    final byte[][] rowIds = { { (byte) 0x11 }, // 0
      { (byte) 0x12 }, // 1
      { (byte) 0x12, (byte) 0x23, (byte) 0xFF, (byte) 0xFE }, // 2
      { (byte) 0x12, (byte) 0x23, (byte) 0xFF, (byte) 0xFF }, // 3
      { (byte) 0x12, (byte) 0x23, (byte) 0xFF, (byte) 0xFF, (byte) 0x00 }, // 4
      { (byte) 0x12, (byte) 0x23, (byte) 0xFF, (byte) 0xFF, (byte) 0x01 }, // 5
      { (byte) 0x12, (byte) 0x24 }, // 6
      { (byte) 0x12, (byte) 0x24, (byte) 0x00 }, // 7
      { (byte) 0x12, (byte) 0x24, (byte) 0x00, (byte) 0x00 }, // 8
      { (byte) 0x12, (byte) 0x25 }, // 9
      { (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF }, // 10
    };
    for (byte[] rowId : rowIds) {
      Put p = new Put(rowId);
      // Use the rowId as the column qualifier
      p.addColumn(Bytes.toBytes("F"), rowId, Bytes.toBytes("Dummy value"));
      table.put(p);
    }

    byte[] prefix0 = {};
    List<byte[]> expected0 = new ArrayList<>(16);
    expected0.addAll(Arrays.asList(rowIds)); // Expect all rows

    byte[] prefix1 = { (byte) 0x12, (byte) 0x23 };
    List<byte[]> expected1 = new ArrayList<>(16);
    expected1.add(rowIds[2]);
    expected1.add(rowIds[3]);
    expected1.add(rowIds[4]);
    expected1.add(rowIds[5]);

    byte[] prefix2 = { (byte) 0x12, (byte) 0x23, (byte) 0xFF, (byte) 0xFF };
    List<byte[]> expected2 = new ArrayList<>();
    expected2.add(rowIds[3]);
    expected2.add(rowIds[4]);
    expected2.add(rowIds[5]);

    byte[] prefix3 = { (byte) 0x12, (byte) 0x24 };
    List<byte[]> expected3 = new ArrayList<>();
    expected3.add(rowIds[6]);
    expected3.add(rowIds[7]);
    expected3.add(rowIds[8]);

    byte[] prefix4 = { (byte) 0xFF, (byte) 0xFF };
    List<byte[]> expected4 = new ArrayList<>();
    expected4.add(rowIds[10]);

    // ========
    // PREFIX 0
    Scan scan = new Scan();
    scan.setStartStopRowForPrefixScan(prefix0);
    verifyScanResult(table, scan, expected0, "Scan empty prefix failed");

    // ========
    // PREFIX 1
    scan = new Scan();
    scan.setStartStopRowForPrefixScan(prefix1);
    verifyScanResult(table, scan, expected1, "Scan normal prefix failed");

    scan.setStartStopRowForPrefixScan(null);
    verifyScanResult(table, scan, expected0, "Scan after prefix reset failed");

    scan = new Scan();
    scan.setFilter(new ColumnPrefixFilter(prefix1));
    verifyScanResult(table, scan, expected1, "Double check on column prefix failed");

    // ========
    // PREFIX 2
    scan = new Scan();
    scan.setStartStopRowForPrefixScan(prefix2);
    verifyScanResult(table, scan, expected2, "Scan edge 0xFF prefix failed");

    scan.setStartStopRowForPrefixScan(null);
    verifyScanResult(table, scan, expected0, "Scan after prefix reset failed");

    scan = new Scan();
    scan.setFilter(new ColumnPrefixFilter(prefix2));
    verifyScanResult(table, scan, expected2, "Double check on column prefix failed");

    // ========
    // PREFIX 3
    scan = new Scan();
    scan.setStartStopRowForPrefixScan(prefix3);
    verifyScanResult(table, scan, expected3, "Scan normal with 0x00 ends failed");

    scan.setStartStopRowForPrefixScan(null);
    verifyScanResult(table, scan, expected0, "Scan after prefix reset failed");

    scan = new Scan();
    scan.setFilter(new ColumnPrefixFilter(prefix3));
    verifyScanResult(table, scan, expected3, "Double check on column prefix failed");

    // ========
    // PREFIX 4
    scan = new Scan();
    scan.setStartStopRowForPrefixScan(prefix4);
    verifyScanResult(table, scan, expected4, "Scan end prefix failed");

    scan.setStartStopRowForPrefixScan(null);
    verifyScanResult(table, scan, expected0, "Scan after prefix reset failed");

    scan = new Scan();
    scan.setFilter(new ColumnPrefixFilter(prefix4));
    verifyScanResult(table, scan, expected4, "Double check on column prefix failed");

    // ========
    // COMBINED
    // Prefix + Filter
    scan = new Scan();
    scan.setStartStopRowForPrefixScan(prefix1);
    verifyScanResult(table, scan, expected1, "Prefix filter failed");

    scan.setFilter(new ColumnPrefixFilter(prefix2));
    verifyScanResult(table, scan, expected2, "Combined Prefix + Filter failed");

    scan.setStartStopRowForPrefixScan(null);
    verifyScanResult(table, scan, expected2, "Combined Prefix + Filter; removing Prefix failed");

    scan.setFilter(null);
    verifyScanResult(table, scan, expected0, "Scan after Filter reset failed");

    // ========
    // Reversed: Filter + Prefix
    scan = new Scan();
    scan.setFilter(new ColumnPrefixFilter(prefix2));
    verifyScanResult(table, scan, expected2, "Test filter failed");

    scan.setStartStopRowForPrefixScan(prefix1);
    verifyScanResult(table, scan, expected2, "Combined Filter + Prefix failed");

    scan.setFilter(null);
    verifyScanResult(table, scan, expected1, "Combined Filter + Prefix ; removing Filter failed");

    scan.setStartStopRowForPrefixScan(null);
    verifyScanResult(table, scan, expected0, "Scan after prefix reset failed");
  }
Test if Scan.setStartStopRowForPrefixScan works as intended.
hbase-server/src/test/java/org/apache/hadoop/hbase/filter/TestScanRowPrefix.java