Document record-structure dictionary counts and the encoding they measure - #633
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the 'describe_table' API documentation to detail the new record-structure dictionary fields in the response. The reviewer suggested adding a version badge to indicate this behavior change, as per the repository's documentation guidelines.
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-633 This preview will update automatically when you push new commits. |
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-633 This preview will update automatically when you push new commits. |
The describe_table structure counts were a reader's first encounter with storage.randomAccessFields, which had no documentation anywhere: not in the configuration option list, not on the @table directive, and nowhere explaining what the encoding buys or which tables it suits. Add a Record Encoding section to Storage Tuning covering the layout difference between the classic and typed encodings, what each buys, when to enable it and when to leave it off, the runtime-toggle and per-table pinning semantics, and the structure bound. Add the config option and the @table argument to their reference lists, and point the describe_table passage at the new material. Refs #633 Co-Authored-By: Claude Opus <noreply@anthropic.com>
- A structure keys on each field's encoded type as well as its width, so a field written as an integer in one record and a string in the next mints a new one. The shape definition and the shape-stabilization advice both said "width class" only. - "Safe to toggle at runtime" read as "takes effect at runtime". A table reads the setting when its store opens, so like every other config change it lands on restart; say that instead. - State the typed bound as the reported typed_structure_limit rather than a literal 256 per encoder, which conflicted with describe_table presenting one count per table. - Give classic_structure_count an interpretation: it keys on field names alone and stops at 32, which is why the response carries no limit field for it. - Note that pinning a table's encoding also means a fleet-wide change to the global setting will not move it. - Cross-link Storage Algorithm to the new section, and the @table argument row to its explanation. Refs #633 Co-Authored-By: Claude Opus <noreply@anthropic.com>
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-633 This preview will update automatically when you push new commits. |
Companion to harper core's observability change for HarperFast/harper#2220. Explains what a record structure is, why the dictionary only grows, what reaching the bound means, and how to keep the dictionary small. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Repo convention (AGENTS.md): behavior changes to an existing surface carry `<VersionBadge type="changed" version="vX.Y.0" />`. Patch-level badges have precedent in reference/ (v5.1.5, v5.1.13, v5.1.15), and main is at 5.2.4. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The describe_table structure counts were a reader's first encounter with storage.randomAccessFields, which had no documentation anywhere: not in the configuration option list, not on the @table directive, and nowhere explaining what the encoding buys or which tables it suits. Add a Record Encoding section to Storage Tuning covering the layout difference between the classic and typed encodings, what each buys, when to enable it and when to leave it off, the runtime-toggle and per-table pinning semantics, and the structure bound. Add the config option and the @table argument to their reference lists, and point the describe_table passage at the new material. Refs #633 Co-Authored-By: Claude Opus <noreply@anthropic.com>
- A structure keys on each field's encoded type as well as its width, so a field written as an integer in one record and a string in the next mints a new one. The shape definition and the shape-stabilization advice both said "width class" only. - "Safe to toggle at runtime" read as "takes effect at runtime". A table reads the setting when its store opens, so like every other config change it lands on restart; say that instead. - State the typed bound as the reported typed_structure_limit rather than a literal 256 per encoder, which conflicted with describe_table presenting one count per table. - Give classic_structure_count an interpretation: it keys on field names alone and stops at 32, which is why the response carries no limit field for it. - Note that pinning a table's encoding also means a fleet-wide change to the global setting will not move it. - Cross-link Storage Algorithm to the new section, and the @table argument row to its explanation. Refs #633 Co-Authored-By: Claude Opus <noreply@anthropic.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Co-Authored-By: GPT-5 Codex <noreply@openai.com>
458332b to
cecf65b
Compare
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-633 This preview will update automatically when you push new commits. |
🧹 Preview CleanupThe preview deployment for this PR has been removed. |
Companion to the core change for HarperFast/harper#2220 — Per-table msgpackr structure dictionaries grow unbounded and unobservably, which adds four fields to
describe_table:typed_structures_enabled,typed_structure_count,typed_structure_limit,classic_structure_count.Documents what a record structure is, why the dictionary only ever grows, what reaching the bound means, and how an application keeps it small — and, in response to review, documents the feature those counts describe.
storage.randomAccessFieldshad shipped in v5.1.0 with no documentation anywhere: not in the configuration option list, not on the@tabledirective, and nothing explaining what the encoding buys or which tables it suits. Thedescribe_tablepassage was a reader's first encounter with it. So the PR now adds a Record Encoding section to Storage Tuning covering the layout difference, what each encoding buys, when to enable it and when not to, plus the config option and the@tableargument in their reference lists.For the human reviewer
{a, b}and{b, a}are different shapes, and so are{v: 1},{v: 70000}, and{v: "ok"}. This is measured against the installed deps, not inferred: 4 key orders → 4 structures; one two-field shape across 11 value kinds → 5 structures. The issue that prompted this attributed growth to realized field subsets alone, which understates it.classic_structure_countstops at 32 because msgpackr's shared named-record list defaults tomaxSharedStructures: 32(msgpackr/pack.js:43). Verified empirically — aPackrwithgetStructures/saveStructuresfed 200 distinct field-name sets saturates the shared list at exactly 32 — and it matches the core PR's live measurement (typed 256/256,classic 32). That is whydescribe_tablereports noclassic_structure_limit: there is a bound, it is just not configurable.OpenDBIObjectreadsstorage.randomAccessFieldswhen the primary DBI is constructed, so an already-open table keeps the encoding it opened with. An operator who runsset_configurationand immediately pollsdescribe_tablewould otherwise conclude the feature is broken.typed_structures_enabledneeds the surrounding sentence.storage.randomAccessFieldsdefaults off, so most tables showtyped_structure_count: 0against a limit of 256. Without the explanation an operator reads that as spare headroom rather than the feature being disabled, so the paragraph saying so is load-bearing.typed_structure_countagainsttyped_structure_limit, 256 by default) rather than as a literal "256 per encoder", which read as conflicting withdescribe_tablepresenting one count per table.storage.randomAccessFieldsand the@table(randomAccessFields:)directive are v5.1.0 surface with no entry inrelease-notes/v5-lincoln/5.1.md. Backfilling a shipped release-notes file felt like a separate call rather than something to fold in here.table-sizemetric; that metric turns out to have no RocksDB emitter at all (The table-size analytics metric is never emitted on RocksDB harper#2249), so documenting it here would point operators at a series that never appears.Verification
npm run format:checkclean;npm run buildsucceeds with no new broken links or anchors (the two it reports —/reference/v5/backups/overviewand/release-notes/v5-lincoln/5.1— are pre-existing and on untouched pages).Packrwith shared structures over 200 distinct field-name sets against Harper's installedmsgpackr.typed 256/256,classic 32).Refs HarperFast/harper#2220
Review-Coverage: authored=codex; ran=gemini,claude; declined=cursor-grok,cursor-composer,domain; rounds=4 @ cecf65b
Human-Review-Need: 2 @ cecf65b