public static RowRanges calculateRowRanges(
      FilterCompat.Filter filter, ColumnIndexStore columnIndexStore, Set<ColumnPath> paths, long rowCount) {
    return filter.accept(new FilterCompat.Visitor<RowRanges>() {
      @Override
      public RowRanges visit(FilterPredicateCompat filterPredicateCompat) {
        try {
          return filterPredicateCompat
              .getFilterPredicate()
              .accept(new ColumnIndexFilter(columnIndexStore, paths, rowCount));
        } catch (MissingOffsetIndexException e) {
          LOGGER.info(e.getMessage());
          return RowRanges.createSingle(rowCount);
        }
      }

      @Override
      public RowRanges visit(UnboundRecordFilterCompat unboundRecordFilterCompat) {
        return RowRanges.createSingle(rowCount);
      }

      @Override
      public RowRanges visit(NoOpFilter noOpFilter) {
        return RowRanges.createSingle(rowCount);
      }
    });
  }
@Test
  public void testFiltering() {
    Set<ColumnPath> paths = paths("column1", "column2", "column3", "column4", "column6");

    assertAllRows(
        calculateRowRanges(
            FilterCompat.get(userDefined(intColumn("column1"), AnyInt.class)),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        TOTAL_ROW_COUNT);

    assertRows(
        calculateRowRanges(
            FilterCompat.get(contains(eq(intColumn("column6"), 7))), STORE, paths, TOTAL_ROW_COUNT),
        7,
        8,
        9,
        10,
        11,
        12,
        13);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(
                and(contains(eq(intColumn("column6"), 7)), contains(eq(intColumn("column6"), 10)))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        9,
        10,
        11,
        12,
        13);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(
                or(contains(eq(intColumn("column6"), 7)), contains(eq(intColumn("column6"), 20)))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        21,
        22,
        23,
        24,
        25,
        26);
    Set<Integer> set1 = new HashSet<>();
    set1.add(7);
    assertRows(
        calculateRowRanges(FilterCompat.get(in(intColumn("column1"), set1)), STORE, paths, TOTAL_ROW_COUNT),
        7,
        8,
        9,
        10,
        11,
        12,
        13);
    set1.add(1);
    assertRows(
        calculateRowRanges(FilterCompat.get(in(intColumn("column1"), set1)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13);
    assertRows(
        calculateRowRanges(FilterCompat.get(notIn(intColumn("column1"), set1)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);

    Set<Binary> set2 = new HashSet<>();
    set2.add(fromString("Zulu"));
    set2.add(fromString("Alfa"));
    assertRows(
        calculateRowRanges(FilterCompat.get(in(binaryColumn("column2"), set2)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(notIn(binaryColumn("column2"), set2)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);

    Set<Double> set3 = new HashSet<>();
    set3.add(2.03);
    assertRows(
        calculateRowRanges(FilterCompat.get(in(doubleColumn("column3"), set3)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        16,
        17,
        18,
        19,
        20,
        21,
        22);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(notIn(doubleColumn("column3"), set3)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);
    set3.add(9.98);
    assertRows(
        calculateRowRanges(FilterCompat.get(in(doubleColumn("column3"), set3)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(notIn(doubleColumn("column3"), set3)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);
    set3.add(null);
    assertRows(
        calculateRowRanges(FilterCompat.get(in(doubleColumn("column3"), set3)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(notIn(doubleColumn("column3"), set3)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);

    Set<Boolean> set4 = new HashSet<>();
    set4.add(null);
    assertRows(
        calculateRowRanges(FilterCompat.get(in(booleanColumn("column4"), set4)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);
    // no column index, can't filter this row
    assertRows(
        calculateRowRanges(
            FilterCompat.get(notIn(booleanColumn("column4"), set4)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);

    Set<Integer> set5 = new HashSet<>();
    set5.add(7);
    set5.add(20);
    assertRows(
        calculateRowRanges(FilterCompat.get(in(intColumn("column5"), set5)), STORE, paths, TOTAL_ROW_COUNT),
        new long[0]);
    assertRows(
        calculateRowRanges(FilterCompat.get(notIn(intColumn("column5"), set5)), STORE, paths, TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29);

    assertRows(
        calculateRowRanges(
            FilterCompat.get(and(
                and(eq(intColumn("column1"), null), eq(binaryColumn("column2"), null)),
                and(eq(doubleColumn("column3"), null), eq(booleanColumn("column4"), null)))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        6,
        9);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(and(
                and(notEq(intColumn("column1"), null), notEq(binaryColumn("column2"), null)),
                and(notEq(doubleColumn("column3"), null), notEq(booleanColumn("column4"), null)))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(or(
                and(lt(intColumn("column1"), 20), gtEq(binaryColumn("column2"), fromString("Quebec"))),
                and(
                    gt(doubleColumn("column3"), 5.32),
                    ltEq(binaryColumn("column4"), fromString("XYZ"))))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        10,
        11,
        12,
        13,
        14,
        15,
        23,
        24,
        25);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(and(
                and(gtEq(intColumn("column1"), 7), gt(binaryColumn("column2"), fromString("India"))),
                and(eq(doubleColumn("column3"), null), notEq(binaryColumn("column4"), null)))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        7,
        16,
        17,
        18,
        19,
        20);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(and(
                or(
                    invert(userDefined(intColumn("column1"), AnyInt.class)),
                    eq(binaryColumn("column2"), fromString("Echo"))),
                eq(doubleColumn("column3"), 6.0))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        23,
        24,
        25);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(and(
                userDefined(intColumn("column1"), IntegerIsDivisableWith3.class),
                and(
                    userDefined(binaryColumn("column2"), BinaryUtf8StartsWithB.class),
                    userDefined(doubleColumn("column3"), DoubleIsInteger.class)))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        21,
        22,
        23,
        24,
        25);
    assertRows(
        calculateRowRanges(
            FilterCompat.get(and(
                and(gtEq(intColumn("column1"), 7), lt(intColumn("column1"), 11)),
                and(
                    gt(binaryColumn("column2"), fromString("Romeo")),
                    ltEq(binaryColumn("column2"), fromString("Tango"))))),
            STORE,
            paths,
            TOTAL_ROW_COUNT),
        7,
        11,
        12,
        13);
  }