Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 1 addition & 24 deletions cli/src/main/java/io/github/dfa1/vortex/cli/TuiCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@

import io.github.dfa1.vortex.cli.tui.IoWorker;
import io.github.dfa1.vortex.cli.tui.VortexInspectorTui;
import io.github.dfa1.vortex.inspect.InspectorTree;
import io.github.dfa1.vortex.reader.VortexHandle;

import java.io.IOException;
import java.io.PrintStream;
import java.util.Optional;

@SuppressWarnings("java:S106") // CLI command: stdout is the intended output channel
Expand All @@ -27,7 +25,7 @@ static int run(String[] args) {
}
VortexHandle handle = opened.get();
try {
VortexInspectorTui.show(handle, worker, progressBar(System.err));
VortexInspectorTui.show(handle, worker);
} finally {
CliHandles.closeOnWorker(worker, handle);
}
Expand All @@ -41,25 +39,4 @@ static int run(String[] args) {
return ExitStatus.ERROR;
}
}

private static InspectorTree.Progress progressBar(PrintStream out) {
int width = 30;
return (current, total) -> {
if (total <= 0) {
return;
}
int filled = (int) ((long) current * width / total);
StringBuilder bar = new StringBuilder(width + 32);
bar.append('\r').append("Loading metadata [");
for (int i = 0; i < width; i++) {
bar.append(i < filled ? '#' : '-');
}
bar.append("] ").append(current).append('/').append(total);
if (current == total) {
bar.append('\n');
}
out.print(bar);
out.flush();
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,44 +39,20 @@ public final class VortexInspectorTui {
private VortexInspectorTui() {
}

/// Opens the terminal in raw mode, builds an inspector tree, and runs the
/// interactive viewer until quit.
/// Opens the terminal in raw mode and runs the interactive viewer until quit. The tree is built
/// shallow, so the screen is interactive immediately; encoding, stats and data previews are
/// fetched lazily as the user navigates.
///
/// @param handle open Vortex file handle
/// @throws IOException if the terminal cannot be initialized
public static void show(VortexHandle handle) throws IOException {
show(handle, InspectorTree.Progress.NOOP);
}

/// Builds an inspector tree (reporting progress on each segment peek)
/// and runs the interactive viewer until quit. The TUI now uses the
/// shallow builder so the screen is interactive immediately; encoding,
/// stats and data previews are fetched lazily as the user navigates.
/// The `progress` parameter is retained for source compatibility
/// but is no longer invoked - shallow build does no peeks.
///
/// @param handle open Vortex file handle
/// @param progress unused; kept for API stability
/// @throws IOException if the terminal cannot be initialized
public static void show(VortexHandle handle, InspectorTree.Progress progress) throws IOException {
show(handle, null, progress);
}

/// Variant that dispatches every `handle` I/O call onto the supplied
/// [IoWorker]. Required when the handle was opened on a different
/// thread (Vortex readers use a confined [java.lang.foreign.Arena],
/// so cross-thread access throws `WrongThreadException`).
///
/// Passing `null` for `worker` falls back to synchronous I/O
/// on the render thread — fine for tests but causes the sluggishness this
/// Every `handle` I/O call is dispatched onto `worker`: Vortex readers use a confined
/// [java.lang.foreign.Arena], so a handle opened on another thread throws
/// `WrongThreadException` when touched from the render thread. Passing `null` falls back to
/// synchronous I/O on the render thread — fine for tests but causes the sluggishness this
/// machinery was built to avoid.
///
/// @param handle open Vortex file handle
/// @param worker I/O dispatcher that owns the handle's thread; may be `null`
/// @param progress unused; kept for API stability
/// @param handle open Vortex file handle
/// @param worker I/O dispatcher that owns the handle's thread; may be `null`
/// @throws IOException if the terminal cannot be initialized
public static void show(VortexHandle handle, IoWorker worker, InspectorTree.Progress progress)
throws IOException {
public static void show(VortexHandle handle, IoWorker worker) throws IOException {
InspectorTree tree = InspectorTree.buildShallow(handle);
try (Terminal term = Terminal.open()) {
run(term, tree, handle, worker);
Expand All @@ -86,7 +62,7 @@ public static void show(VortexHandle handle, IoWorker worker, InspectorTree.Prog
/// Runs the inspector viewer against a caller-supplied terminal. Package-private
/// seam used by tests to drive the loop with a scripted fake terminal,
/// bypassing the OS raw-mode setup in
/// [#show(VortexHandle, IoWorker, InspectorTree.Progress)].
/// [#show(VortexHandle, IoWorker)].
///
/// @param term terminal to render to and read keys from
/// @param tree pre-built inspector tree for `handle`
Expand Down
4 changes: 2 additions & 2 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,11 +183,11 @@ than rounded. Every precision Rust supports (1–76, i8 … i256 storage) and ne

### `WriteOptions` (`io.github.dfa1.vortex.writer.WriteOptions`)

Record: `(boolean enableZoneMaps, double compressionRatioThreshold, int allowedCascading, boolean globalDict, MemorySize globalDictMaxRetainedBytes, Map<EditionFamily, Edition> editions)`.
A plain final class: start from a factory below and adjust with the `withXxx` methods, each returning a copy.

| Factory | Defaults |
|---------------------------------|---------------------------------------------------------------------------------------------------|
| `WriteOptions.defaults()` | `enableZoneMaps=true`, `compressionRatioThreshold=0.90`, `allowedCascading=3` (Rust's `MAX_CASCADE`), `globalDict=true`, `compact=false`, `globalDictMaxRetainedBytes=MemorySize.ofGiB(2)`, `editions={CORE: Editions.CORE_2026_08_3}` |
| `WriteOptions.defaults()` | `enableZoneMaps=true`, `allowedCascading=3` (Rust's `MAX_CASCADE`), `globalDict=true`, `compact=false`, `globalDictMaxRetainedBytes=MemorySize.ofGiB(2)`, `editions={CORE: Editions.CORE_2026_08_3}` |
| `WriteOptions.cascading(depth)` | Same defaults, `allowedCascading=depth`; `0` disables cascading (each column takes the first accepting encoder) |

| Method | Notes |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ private static long rawBytes(DType dtype, long rows) {
// An extension's storage dtype is what occupies the bytes, so a timestamp column compares
// against its i64 storage width rather than reporting no ratio at all.
DType effective = dtype instanceof DType.Extension ext ? ext.storageDType() : dtype;
return effective instanceof DType.Primitive(PType ptype, boolean ignored) ? rows * ptype.byteSize() : 0L;
return effective instanceof DType.Primitive(PType ptype, boolean _) ? rows * ptype.byteSize() : 0L;
}

/// The dtype that actually occupies the bytes: an extension's storage dtype, or the column's
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ private static Path writeJava(Path dir, Pattern pattern, int depth) throws IOExc
private static Path writeJni(Path dir, Pattern pattern) throws IOException {
Path file = dir.resolve(pattern.name() + "-jni.vtx");
ArrowType arrowType = switch (pattern.data()) {
case long[] ignored -> new ArrowType.Int(64, true);
case double[] ignored -> new ArrowType.FloatingPoint(FloatingPointPrecision.DOUBLE);
case long[] _ -> new ArrowType.Int(64, true);
case double[] _ -> new ArrowType.FloatingPoint(FloatingPointPrecision.DOUBLE);
default -> ArrowType.Utf8.INSTANCE;
};
Schema schema = new Schema(java.util.List.of(Field.notNullable("v", arrowType)));
Expand Down
Loading
Loading