wgtmac commented on code in PR #3597:
URL: https://github.com/apache/parquet-java/pull/3597#discussion_r3497150029


##########
parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java:
##########
@@ -316,4 +316,72 @@ public List<Range> getRanges() {
   public String toString() {
     return ranges.toString();
   }
+
+  /**
+   * @return a new {@link Builder} for constructing a {@link RowRanges} from a 
sequence of
+   *     selected row indices.
+   */
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  /**
+   * Constructs a {@link RowRanges} by appending selected row indices in 
strictly increasing
+   * order. Consecutive indices are coalesced into a single {@link Range}; 
gaps close the
+   * current run and start a new one.
+   *
+   * <p>Usage:
+   * <pre>{@code
+   * RowRanges.Builder builder = RowRanges.builder();
+   * for (long row : selectedRowsInOrder) {
+   *   builder.addSelected(row);
+   * }
+   * RowRanges ranges = builder.build();
+   * }</pre>
+   */
+  public static class Builder {
+    private final List<Range> ranges = new ArrayList<>();
+    private long runStart = -1; // -1 = no active run
+    private long runEnd = -1; // valid iff runStart >= 0
+
+    /**
+     * Marks {@code blockRow} as selected. Must be called in strictly 
increasing order; calling
+     * with a value less than or equal to the previous call's value throws
+     * {@link IllegalArgumentException}.
+     *
+     * @param blockRow the row index to mark selected (must be {@code >} the 
last value passed)
+     * @return this builder for chaining
+     */
+    public Builder addSelected(long blockRow) {

Review Comment:
   `addSelected` should reject negative row indexes explicitly. `-1` also 
collides with the builder’s sentinel state, so invalid input can be silently 
swallowed or corrupt the active run.



##########
parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java:
##########
@@ -316,4 +316,72 @@ public List<Range> getRanges() {
   public String toString() {
     return ranges.toString();
   }
+
+  /**

Review Comment:
   This needs a clearer API commitment. The motivation is external 
readers/Spark, but the type lives under `internal` and the PR says there are no 
user-facing changes. If this is meant to be supported externally, the 
package/API contract should say so; otherwise downstream users may depend on an 
unsupported API.



##########
parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java:
##########
@@ -316,4 +316,72 @@ public List<Range> getRanges() {
   public String toString() {
     return ranges.toString();
   }
+
+  /**
+   * @return a new {@link Builder} for constructing a {@link RowRanges} from a 
sequence of
+   *     selected row indices.
+   */
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  /**
+   * Constructs a {@link RowRanges} by appending selected row indices in 
strictly increasing
+   * order. Consecutive indices are coalesced into a single {@link Range}; 
gaps close the
+   * current run and start a new one.
+   *
+   * <p>Usage:
+   * <pre>{@code
+   * RowRanges.Builder builder = RowRanges.builder();
+   * for (long row : selectedRowsInOrder) {
+   *   builder.addSelected(row);
+   * }
+   * RowRanges ranges = builder.build();
+   * }</pre>
+   */
+  public static class Builder {

Review Comment:
   Consider making `Builder` `final` and adding an explicit constructor. 
Otherwise subclassing and `new RowRanges.Builder()` become part of the public 
API surface by accident.



##########
parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java:
##########
@@ -316,4 +316,72 @@ public List<Range> getRanges() {
   public String toString() {
     return ranges.toString();
   }
+
+  /**
+   * @return a new {@link Builder} for constructing a {@link RowRanges} from a 
sequence of
+   *     selected row indices.
+   */
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  /**
+   * Constructs a {@link RowRanges} by appending selected row indices in 
strictly increasing
+   * order. Consecutive indices are coalesced into a single {@link Range}; 
gaps close the
+   * current run and start a new one.
+   *
+   * <p>Usage:
+   * <pre>{@code
+   * RowRanges.Builder builder = RowRanges.builder();
+   * for (long row : selectedRowsInOrder) {
+   *   builder.addSelected(row);
+   * }
+   * RowRanges ranges = builder.build();
+   * }</pre>
+   */
+  public static class Builder {
+    private final List<Range> ranges = new ArrayList<>();
+    private long runStart = -1; // -1 = no active run
+    private long runEnd = -1; // valid iff runStart >= 0
+
+    /**
+     * Marks {@code blockRow} as selected. Must be called in strictly 
increasing order; calling
+     * with a value less than or equal to the previous call's value throws
+     * {@link IllegalArgumentException}.
+     *
+     * @param blockRow the row index to mark selected (must be {@code >} the 
last value passed)
+     * @return this builder for chaining
+     */
+    public Builder addSelected(long blockRow) {

Review Comment:
   The naming could be clearer before this API ships. `addSelected(long 
blockRow)` is ambiguous; something like `addSelectedRow(long rowIndex)` would 
better communicate that the value is a 0-based row index within the current row 
group.



##########
parquet-column/src/main/java/org/apache/parquet/internal/filter2/columnindex/RowRanges.java:
##########
@@ -316,4 +316,72 @@ public List<Range> getRanges() {
   public String toString() {
     return ranges.toString();
   }
+
+  /**
+   * @return a new {@link Builder} for constructing a {@link RowRanges} from a 
sequence of
+   *     selected row indices.
+   */
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  /**
+   * Constructs a {@link RowRanges} by appending selected row indices in 
strictly increasing
+   * order. Consecutive indices are coalesced into a single {@link Range}; 
gaps close the
+   * current run and start a new one.
+   *
+   * <p>Usage:
+   * <pre>{@code
+   * RowRanges.Builder builder = RowRanges.builder();
+   * for (long row : selectedRowsInOrder) {
+   *   builder.addSelected(row);
+   * }
+   * RowRanges ranges = builder.build();
+   * }</pre>
+   */
+  public static class Builder {
+    private final List<Range> ranges = new ArrayList<>();
+    private long runStart = -1; // -1 = no active run
+    private long runEnd = -1; // valid iff runStart >= 0
+
+    /**
+     * Marks {@code blockRow} as selected. Must be called in strictly 
increasing order; calling
+     * with a value less than or equal to the previous call's value throws
+     * {@link IllegalArgumentException}.
+     *
+     * @param blockRow the row index to mark selected (must be {@code >} the 
last value passed)
+     * @return this builder for chaining
+     */
+    public Builder addSelected(long blockRow) {
+      if (runStart < 0) {
+        runStart = blockRow;
+        runEnd = blockRow;
+      } else if (blockRow == runEnd + 1) {
+        runEnd = blockRow;
+      } else if (blockRow > runEnd + 1) {
+        ranges.add(new Range(runStart, runEnd));
+        runStart = blockRow;
+        runEnd = blockRow;
+      } else {
+        throw new IllegalArgumentException(
+            "addSelected requires strictly increasing row indices; got " + 
blockRow + " after " + runEnd);
+      }
+      return this;
+    }
+
+    /**
+     * @return the constructed {@link RowRanges}, or {@link RowRanges#EMPTY} 
when no rows were
+     *     selected.
+     */
+    public RowRanges build() {

Review Comment:
   `build()` should return a snapshot or become terminal. As written, the 
returned `RowRanges` shares the builder’s mutable `ranges` list, so later calls 
on the same builder can mutate a previously built result and even break the 
sorted-ranges invariant.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to