verbs/put/put.js appendAndAssign is O(N^2) + re-rolls ulog tsbe put a b c … lowers each path arg to its own handler call, and each call's
commitOps invokes appendAndAssign, which DRAINS the whole wtlog, concatenates
the new rows, and rewrites the entire file (temp + fsync + rename) — once per
arg. A wide arg list is quadratic plus N temp-file cycles. It also HAND-ROLLS
ulog's monotonic-stamp policy (nowAfter(tail) then +1 per row) instead of
calling the shared writer, so any future ts-policy change diverges silently.
ulog.appendInPlace/feedRows exist for exactly this. Output is correct today
(put rows carry no per-row ts in the tree), so the divergence is latent. Method:
Issues.
verbs/put/put.js:152 commitOps calls appendAndAssign(repo.bePath, rows,
floorTs) per non-silent arg-batch.:170-174 appendAndAssign re-reads ALL old rows via ulog.each into
old[] every call (the O(N) drain).:175-184 re-derives tail, ulog.nowAfter(tail), the floorTs floor,
and the per-row ts = ts + 1n bump — a copy of ulog.feedRows/append.:185 ulog.write(bePath, old.concat(fresh)) rewrites the whole ULOG
(temp _stage + io.rename) — the O(N) write, paid once per arg → O(N^2).shared/ulog.js:181 appendInPlace(path, rows, ts) books ONE container and
feeds at the watermark (no whole-file drain); :190 feedRows owns the
nowAfter+floor++1 stamp policy appendAndAssign re-implements.ulog (feedRows/appendInPlace), not a
second hand-rolled copy in put.js.:159-160 reads it).verbs/put/put.js + maybe a small shared/ulog.js helper; keep the row
shapes (put <path> / put <path>#<dst>) and floorTs cohort behaviour.be put a b c.ulog.appendInPlace once for the whole batch and re-read
the tail to recover assigned ts, or (b) add an ulog helper that feeds and
RETURNS the assigned ts array (the one bit appendAndAssign needs that
feedRows does not expose) — preferred, kills the duplication outright.appendAndAssign then becomes a thin wrapper over the shared helper.test/js/put/*: multi-arg put a b c asserts each file's
restamp mtime == its staged row ts, and the wtlog is byte-identical to
native; instrument to confirm ONE write, not N.ulog.feedRowsAssign (feed + return assigned ts) or reuse
appendInPlace; route appendAndAssign through it.appendInPlace does not currently return assigned ts — needs the small
helper or a tail re-read; pick one.928aaad5
RETIRED ulog.appendInPlace/feedRows with core/job.js (shared/ulog.js:246 note).
verbs/put/put.js:198 appendAndAssign still drains all rows (ulog.each:200) + rewrites
the whole file (ulog.write:213), called per arg-batch (:449,:502,:660,:681). The fix
must re-introduce a streaming append helper (they no longer exist) or add one to ulog.js.