private void unselectPositions(Column column, boolean shouldTestValues) {
    int positionCount = column.getPositionCount();
    checkArgument(
        positionCount == this.positionCount,
        "Block position count does not match current position count");
    if (isSelectNone()) {
      return;
    }

    // short circuit if there are no nulls, and we are not testing the value
    if (!column.mayHaveNull() && !shouldTestValues) {
      // all positions selected, so change nothing
      return;
    }

    if (column instanceof RunLengthEncodedColumn) {
      if (test(column, 0, shouldTestValues)) {
        // all positions selected, so change nothing
        return;
      }
      // no positions selected
      selectedPositionCount = 0;
      return;
    }

    if (positionCount == selectedPositionCount) {
      if (selectedPositions.length < positionCount) {
        selectedPositions = new int[positionCount];
      }

      // add all positions that pass the test
      int selectedPositionsIndex = 0;
      for (int position = 0; position < positionCount; position++) {
        if (test(column, position, shouldTestValues)) {
          selectedPositions[selectedPositionsIndex] = position;
          selectedPositionsIndex++;
        }
      }
      selectedPositionCount = selectedPositionsIndex;
      return;
    }

    // keep only the positions that pass the test
    int originalIndex = 0;
    int newIndex = 0;
    for (; originalIndex < selectedPositionCount; originalIndex++) {
      int position = selectedPositions[originalIndex];
      if (test(column, position, shouldTestValues)) {
        selectedPositions[newIndex] = position;
        newIndex++;
      }
    }
    selectedPositionCount = newIndex;
  }
Do not use this to filter a page, as the underlying array can change, and this will change the
page after the filtering.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AggregationMask.java