]> git.hungrycats.org Git - bees/commitdiff
docs: document ${NPROC}/${THREAD_FACTOR}, ceil(), and the thread expressions
authorZygo Blaxell <bees@furryterror.org>
Mon, 8 Jun 2026 22:59:43 +0000 (18:59 -0400)
committerZygo Blaxell <bees@furryterror.org>
Sat, 5 Sep 2026 04:03:57 +0000 (00:03 -0400)
Rewrite the [thread] section of config-file.md for the expression model:
thread-min/thread-max/loadavg-target are size values; thread-max means
exactly what it evaluates to and is no longer silently capped by
thread-factor; thread-factor feeds the default expression via
${THREAD_FACTOR}; loadavg-target keeps fractional values.  The legacy -c N
option still sets an exact, possibly oversubscribed count (its released
behaviour), overriding the expression.

In config-format.md, document the real size-expression grammar (arithmetic
operators, parentheses, % suffix, min()/max()/ceil(), interpolated
variables) -- it previously described only suffixes and a single +/-
adjustment -- and add the missing ${RAM_BYTES}, ${FS_BYTES}, ${NPROC}, and
${THREAD_FACTOR} interpolation entries.

Update the options.md -c/-C descriptions to match: -c is an exact count that
overrides the factor, -C feeds ${THREAD_FACTOR} in the default thread-max.

Assisted-by: Claude-Code:claude-opus-4-8
Signed-off-by: Zygo Blaxell <bees@furryterror.org>
docs/config-file.md
docs/config-format.md
docs/options.md

index 1ff3fc5113c4cbe55ea89f9e1e5d5b14818435f6..871298ffcb8786db490272d20f5416214ae0d135 100644 (file)
@@ -651,25 +651,28 @@ The `[hash.fast]` domain (priority 200) outranks the built-in `[hash.crc64]`
 
 The `[thread]` section sets how many worker threads bees runs and how aggressively it ramps up under system load.
 
+`thread-min`, `thread-max`, and `loadavg-target` are [size values](config-format.md#size-values): they accept arithmetic expressions, `min()`/`max()`/`ceil()`, and the substitution variables `${NPROC}` (the number of logical CPUs) and `${THREAD_FACTOR}` (the `thread-factor` value below).  This is what puts the CPU-relative arithmetic in your control — for example `thread-max = min(8, ${NPROC})` or `loadavg-target = ${NPROC}`.  `thread-min` and `thread-max` are rounded to integers; `loadavg-target` keeps its fractional value (e.g. `0.5`).
+
 * **`thread-min`** *(legacy `-G`)*
   Minimum number of worker threads bees keeps active, regardless of load-based throttling.
   Default: `0`.
 
 * **`thread-max`** *(legacy `-c`)*
-  Hard cap on worker threads. Leave **blank** to remove this explicit cap; the count then depends only on `thread-factor` (and `thread-min`).
-  If both `thread-factor` and `thread-max` are set, the result is **limited** to `thread-max`.
+  Number of worker threads to run.  It means exactly what the expression evaluates to; it is **not** silently combined with `thread-factor`.
+  Default: `max(1, ceil(${NPROC} * ${THREAD_FACTOR}))` — i.e. one thread per CPU scaled by `thread-factor`, rounded up, never below 1.
+  To cap a CPU-relative count, write the `min()` yourself, e.g. `min(8, ceil(${NPROC} * ${THREAD_FACTOR}))`.  The legacy `-c N` option overrides this with an exact count of `N` threads — its historical behaviour: `thread-factor` is ignored and values above the CPU count are honoured (oversubscription).
 
 * **`thread-factor`** *(legacy `-C`)*
-  Ratio (multiplier) applied to detected CPU threads (logical CPUs). The result is **rounded up**.
-  Accepts any ratio format (see [Configuration File Format Reference](config-format.md)).
+  Threads per logical CPU.  It is not consumed directly; it is exposed to the expressions above as `${THREAD_FACTOR}` (the default `thread-max` multiplies it by `${NPROC}` and rounds up with `ceil()`).
+  Accepts any ratio format (see [Configuration File Format Reference](config-format.md)); the value is normalised to a number before substitution.
 
   Default: `1.0`.
 
 * **`loadavg-target`** *(legacy `-g`)*
   Controls load-based ramping.
 
-  * `0` disables loadavg throttling (bees uses only the static count from `thread-min`/`thread-factor`/`thread-max`).
-  * `>0` makes bees start with the `thread-min` number of workers and then add more until either the 1-minute load average approaches the target or the limit from `thread-factor`/`thread-max` is reached.
+  * `0` disables loadavg throttling (bees uses only the static count from `thread-min`/`thread-max`).
+  * `>0` makes bees start with the `thread-min` number of workers and then add more until either the 1-minute load average approaches the target or the `thread-max` limit is reached.
 
 * **`task-queue-max`**
   Maximum number of extent-scan tasks the crawler will queue at once before backpressuring itself, expressed as a count of in-flight `Task` objects.  Larger values increase parallelism and memory use; smaller values reduce wasted work after a restart by keeping fewer extents in flight.
index bca659ad75bfc4bb521ce6b02d7c7cbe70fb7252..eef189a74db081598098798eb7d23a22ff064039 100644 (file)
@@ -253,8 +253,12 @@ _Some_ strings support interpolated variables:
 | -------- | ------------- |
 | `$$` | literal `$` character. |
 | `${BASENAME}` | last path component of `${ROOT}`. |
+| `${FS_BYTES}` | total capacity of the target filesystem, in bytes. |
 | `${LABEL}` | the label of the target filesystem. |
+| `${NPROC}` | the number of logical CPUs (at least 1). |
+| `${RAM_BYTES}` | total installed physical RAM, in bytes. |
 | `${ROOT}` | the canonical (`realpath`) path to the root of the target filesystem. |
+| `${THREAD_FACTOR}` | the `[thread]` `thread-factor` value, normalised to a number. |
 | `${UUID}` | the target filesystem's UUID in `aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee` notation. |
 
 Any `/` characters in `LABEL` are replaced with `_`.
@@ -291,6 +295,19 @@ The adjustment operand accepts the same suffixes as the base value.
 Whitespace around the operator is optional (`128K+1` and `128K + 1`
 are equivalent).  The `-` operator rejects values that would underflow.
 
+Size values are full arithmetic expressions, evaluated in `double` and
+returned as a non-negative integer:
+
+  * operators `+`, `-`, `*`, `/` with the usual precedence, and `(` `)` grouping
+  * a `%` suffix divides by 100 (e.g. `${RAM_BYTES} * 5%`)
+  * functions `min(a, b)`, `max(a, b)`, and `ceil(a)`
+  * [interpolated variables](#value-string-interpolations) such as
+    `${RAM_BYTES}`, `${FS_BYTES}`, `${NPROC}`, and `${THREAD_FACTOR}`
+
+For example, the default hash-table size is
+`min(${RAM_BYTES} / 16, ${FS_BYTES} / 16384)` and the default worker count is
+`max(1, ceil(${NPROC} * ${THREAD_FACTOR}))`.
+
 ### Duration values
 
 A duration value is one or more whitespace-separated or adjacent
index 5cc7df5c9de2af85f65b481bee44f676e1b514ad..48c18a344aca6063824676a21c6be44a741fee7c 100644 (file)
@@ -4,13 +4,16 @@
 
 * `--thread-count COUNT` or `-c`
 
- Specify maximum number of worker threads.  Overrides `--thread-factor`
- (`-C`), default/autodetected values, and the hardcoded thread limit.
+ Set the number of worker threads to exactly `COUNT`, overriding the default
+ `thread.thread-max` expression (and therefore `--thread-factor`).  Values
+ larger than the CPU count are honoured, so this can oversubscribe CPUs.
 
 * `--thread-factor FACTOR` or `-C`
 
- Specify ratio of worker threads to detected CPU cores.  Overridden by
- `--thread-count` (`-c`).
+ Specify ratio of worker threads to detected CPU cores.  This is the
+ `${THREAD_FACTOR}` substitution used by the default `thread.thread-max`
+ expression, `max(1, ceil(${NPROC} * ${THREAD_FACTOR}))`.  It has no effect
+ when `--thread-count` (`-c`) sets an explicit count.
 
  Default is 1.0, i.e. 1 worker thread per detected CPU.  Use values
  below 1.0 to leave some cores idle, or above 1.0 if there are more