From 9d51df02c110550b81a0e8424089effbb7e9251d Mon Sep 17 00:00:00 2001 From: Yorhel Date: Fri, 15 Nov 2024 11:08:26 +0100 Subject: [PATCH] Add --export-block-size option + minor man page adjustments --- ncdu.1 | 34 +++++++++++++++++++++++++++------- src/bin_export.zig | 3 ++- src/main.zig | 6 ++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/ncdu.1 b/ncdu.1 index f1e52a7..3f9e341 100644 --- a/ncdu.1 +++ b/ncdu.1 @@ -23,6 +23,7 @@ .Op Fl t , \-threads Ar num .Op Fl c , \-compress , \-no\-compress .Op Fl \-compress\-level Ar num +.Op Fl \-export\-block\-size Ar num .Op Fl 0 , 1 , 2 .Op Fl q , \-slow\-ui\-updates , \-fast\-ui\-updates .Op Fl \-enable\-shell , \-disable\-shell @@ -193,9 +194,18 @@ The binary format (see .Fl O ) does not have this problem and supports efficient exporting with any number of threads. +.El +. +.Ss Export Options +These options affect behavior when exporting to file with the +.Fl o +or +.Fl O +options. +.Bl -tag -width Ds .It Fl c , \-compress , \-no\-compress Enable or disable Zstandard compression when exporting to JSON (see -.Fl o ) +.Fl o ) . .It Fl \-compress\-level Ar num Set the Zstandard compression level when using .Fl O @@ -203,6 +213,17 @@ or .Fl c . Valid values are 1 (fastest) to 19 (slowest). Defaults to 4. +.It Fl \-export\-block\-size Ar num +Set the block size, in kibibytes, for the binary export format (see +.Fl O ) . +Larger blocks require more memory but result in better compression efficiency. +This option can be combined with a higher +.Fl \-compress\-level +for even better compression. +.Pp +Accepted values are between 4 and 16000. +The defaults is to start at 64 KiB and then gradually increase the block size +for large exports. .El . .Ss Interface Options @@ -497,29 +518,28 @@ Empty directory. .Sh EXAMPLES To scan and browse the directory you're currently in, all you need is a simple: .Dl ncdu -If you want to scan a full filesystem, for example your root filesystem, then -you'll want to use +To scan a full filesystem, for example your root filesystem, you'll want to use .Fl x : .Dl ncdu \-x / .Pp Since scanning a large directory may take a while, you can scan a directory and export the results for later viewing: .Bd -literal -offset indent -ncdu \-1cxo export.json.zst / +ncdu \-1xO export.ncdu / # ...some time later: -ncdu \-f export.json.zst +ncdu \-f export.ncdu .Ed To export from a cron job, make sure to replace .Fl 1 with .Fl 0 -to suppress any unnecessary output. +to suppress unnecessary progress output. .Pp You can also export a directory and browse it once scanning is done: .Dl ncdu \-co\- | tee export.json.zst | ./ncdu \-f\- .Pp To scan a system remotely, but browse through the files locally: -.Dl ssh user@system ncdu \-co\- / | ./ncdu \-cf\- +.Dl ssh user@system ncdu \-co\- / | ./ncdu \-f\- Remote scanning and local viewing has two major advantages when compared to running .Nm diff --git a/src/bin_export.zig b/src/bin_export.zig index b19628a..43a8cf0 100644 --- a/src/bin_export.zig +++ b/src/bin_export.zig @@ -72,7 +72,8 @@ inline fn cborByte(major: CborMajor, arg: u5) u8 { return (@as(u8, @intFromEnum( fn blockSize(num: u32) usize { // block size uncompressed data in this num range // # mil # KiB # GiB - return if (num < ( 1<<20)) 64<<10 // 64 + return main.config.export_block_size + orelse if (num < ( 1<<20)) 64<<10 // 64 else if (num < ( 2<<20)) 128<<10 // 128 else if (num < ( 4<<20)) 256<<10 // 512 else if (num < ( 8<<20)) 512<<10 // 2048 diff --git a/src/main.zig b/src/main.zig index 440ec91..2cf0f8e 100644 --- a/src/main.zig +++ b/src/main.zig @@ -82,6 +82,7 @@ pub const config = struct { pub var threads: usize = 1; pub var complevel: u8 = 4; pub var compress: bool = false; + pub var export_block_size: ?usize = null; pub var update_delay: u64 = 100*std.time.ns_per_ms; pub var scan_ui: ?enum { none, line, full } = null; @@ -283,6 +284,11 @@ fn argConfig(args: *Args, opt: Args.Option) bool { const val = args.arg(); config.complevel = std.fmt.parseInt(u8, val, 10) catch ui.die("Invalid number for --compress-level: {s}.\n", .{val}); if (config.complevel <= 0 or config.complevel > 20) ui.die("Invalid number for --compress-level: {s}.\n", .{val}); + } else if (opt.is("--export-block-size")) { + const val = args.arg(); + const num = std.fmt.parseInt(u14, val, 10) catch ui.die("Invalid number for --export-block-size: {s}.\n", .{val}); + if (num < 4 or num > 16000) ui.die("Invalid number for --export-block-size: {s}.\n", .{val}); + config.export_block_size = @as(usize, num) * 1024; } else if (opt.is("--confirm-quit")) config.confirm_quit = true else if (opt.is("--no-confirm-quit")) config.confirm_quit = false else if (opt.is("--confirm-delete")) config.confirm_delete = true