@Test
  public void testTimestampsFilter() throws Exception {
    final byte[] TABLE = Bytes.toBytes(name.getMethodName());
    byte[] FAMILY = Bytes.toBytes("event_log");
    byte[][] FAMILIES = new byte[][] { FAMILY };
    Cell kvs[];

    // create table; set versions to max...
    Table ht = TEST_UTIL.createTable(TableName.valueOf(TABLE), FAMILIES, Integer.MAX_VALUE);

    for (int rowIdx = 0; rowIdx < 5; rowIdx++) {
      for (int colIdx = 0; colIdx < 5; colIdx++) {
        // insert versions 201..300
        putNVersions(ht, FAMILY, rowIdx, colIdx, 201, 300);
        // insert versions 1..100
        putNVersions(ht, FAMILY, rowIdx, colIdx, 1, 100);
      }
    }

    // do some verification before flush
    verifyInsertedValues(ht, FAMILY);

    TEST_UTIL.flush();

    // do some verification after flush
    verifyInsertedValues(ht, FAMILY);

    // Insert some more versions after flush. These should be in memstore.
    // After this we should have data in both memstore & HFiles.
    for (int rowIdx = 0; rowIdx < 5; rowIdx++) {
      for (int colIdx = 0; colIdx < 5; colIdx++) {
        putNVersions(ht, FAMILY, rowIdx, colIdx, 301, 400);
        putNVersions(ht, FAMILY, rowIdx, colIdx, 101, 200);
      }
    }

    for (int rowIdx = 0; rowIdx < 5; rowIdx++) {
      for (int colIdx = 0; colIdx < 5; colIdx++) {
        kvs = getNVersions(ht, FAMILY, rowIdx, colIdx, Arrays.asList(505L, 5L, 105L, 305L, 205L));
        assertEquals(4, kvs.length);
        checkOneCell(kvs[0], FAMILY, rowIdx, colIdx, 305);
        checkOneCell(kvs[1], FAMILY, rowIdx, colIdx, 205);
        checkOneCell(kvs[2], FAMILY, rowIdx, colIdx, 105);
        checkOneCell(kvs[3], FAMILY, rowIdx, colIdx, 5);
      }
    }

    // Request an empty list of versions using the Timestamps filter;
    // Should return none.
    kvs = getNVersions(ht, FAMILY, 2, 2, new ArrayList<>());
    assertEquals(0, kvs == null ? 0 : kvs.length);

    //
    // Test the filter using a Scan operation
    // Scan rows 0..4. For each row, get all its columns, but only
    // those versions of the columns with the specified timestamps.
    Result[] results = scanNVersions(ht, FAMILY, 0, 4, Arrays.asList(6L, 106L, 306L));
    assertEquals("# of rows returned from scan", 5, results.length);
    for (int rowIdx = 0; rowIdx < 5; rowIdx++) {
      kvs = results[rowIdx].rawCells();
      // each row should have 5 columns.
      // And we have requested 3 versions for each.
      assertEquals("Number of KeyValues in result for row:" + rowIdx, 3 * 5, kvs.length);
      for (int colIdx = 0; colIdx < 5; colIdx++) {
        int offset = colIdx * 3;
        checkOneCell(kvs[offset + 0], FAMILY, rowIdx, colIdx, 306);
        checkOneCell(kvs[offset + 1], FAMILY, rowIdx, colIdx, 106);
        checkOneCell(kvs[offset + 2], FAMILY, rowIdx, colIdx, 6);
      }
    }
    ht.close();
  }
Test from client side for TimestampsFilter. The TimestampsFilter provides the ability to
request cells (KeyValues) whose timestamp/version is in the specified list of
timestamps/version.
hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestTimestampsFilter.java