Bound repair feedback construction

This commit is contained in:
2026-11-05 14:07:34 +00:00
parent e834e7d806
commit 7c435032b6
3 changed files with 46 additions and 11 deletions

View File

@@ -516,6 +516,13 @@ many entries, heavily escaped and invalid strings, valid JSON, and omission
semantics. Repeat the roadmap's three formatter workloads and record real semantics. Repeat the roadmap's three formatter workloads and record real
allocation results; aggregate allocation is not a peak-heap guarantee. allocation results; aggregate allocation is not a peak-heap guarantee.
Completion: repair feedback uses bounded prefixes for both complete and
omission forms. Focused tests pass on Go 1.27.3. The documented 20-iteration,
three-run workloads measured 398 B/op for 64 ASCII bytes (68 output bytes),
767,634 B/op for 1 MiB ASCII (65,536 output bytes), and about 12,125,700 B/op
for 1 MiB escaped content (65,531 output bytes). These aggregate allocations
do not establish a peak-heap guarantee.
## Stage 20: Select Namespace Ranges Before Copying Inventories ## Stage 20: Select Namespace Ranges Before Copying Inventories
**Catalog:** 20. **Files:** configuration/engine inventory interfaces and listing tests. **Catalog:** 20. **Files:** configuration/engine inventory interfaces and listing tests.

View File

@@ -117,27 +117,38 @@ func repairGuidance(mode domain.ValidationMode) (string, error) {
} }
func formatRepairDiagnostics(errors []string) string { func formatRepairDiagnostics(errors []string) string {
diagnostics := make([]string, len(errors)) complete := []byte{'['}
for index, diagnostic := range errors { fits := true
diagnostics[index] = strings.ToValidUTF8(diagnostic, "\uFFFD") for _, diagnostic := range errors {
separator := 0
if len(complete) > 1 {
separator = 1
}
entry, whole := boundedDiagnosticJSON(diagnostic, maxRepairDiagnosticBytes-len(complete)-separator-1)
if !whole {
fits = false
break
}
if separator != 0 {
complete = append(complete, ',')
}
complete = append(complete, entry...)
} }
if fits {
complete, _ := json.Marshal(diagnostics) return string(append(complete, ']'))
if len(complete) <= maxRepairDiagnosticBytes {
return string(complete)
} }
omission, _ := json.Marshal(omittedRepairDiagnostics) omission, _ := json.Marshal(omittedRepairDiagnostics)
encoded := make([]byte, 0, maxRepairDiagnosticBytes) encoded := make([]byte, 0, maxRepairDiagnosticBytes)
encoded = append(encoded, '[') encoded = append(encoded, '[')
for _, diagnostic := range diagnostics { for _, diagnostic := range errors {
entry, _ := json.Marshal(diagnostic)
separator := 0 separator := 0
if len(encoded) > 1 { if len(encoded) > 1 {
separator = 1 separator = 1
} }
available := maxRepairDiagnosticBytes - len(encoded) - separator - 1 - len(omission) - 1 available := maxRepairDiagnosticBytes - len(encoded) - separator - 1 - len(omission) - 1
if len(entry) <= available { entry, whole := boundedDiagnosticJSON(diagnostic, available)
if whole {
if separator != 0 { if separator != 0 {
encoded = append(encoded, ',') encoded = append(encoded, ',')
} }
@@ -151,7 +162,7 @@ func formatRepairDiagnostics(errors []string) string {
if separator != 0 { if separator != 0 {
encoded = append(encoded, ',') encoded = append(encoded, ',')
} }
encoded = append(encoded, truncateDiagnosticJSONValue(diagnostic, available)...) encoded = append(encoded, entry...)
break break
} }
if len(encoded) > 1 { if len(encoded) > 1 {

View File

@@ -298,6 +298,23 @@ func TestFormatRepairDiagnosticsBoundsAndPreservesData(t *testing.T) {
} }
} }
func TestFormatRepairDiagnosticsEmptyAndEscapedOversize(t *testing.T) {
for _, values := range [][]string{nil, {}} {
if got := formatRepairDiagnostics(values); got != "[]" {
t.Fatalf("empty diagnostics = %q", got)
}
}
value := strings.Repeat("<&>\x00\xff\xfe", maxRepairDiagnosticBytes)
encoded := formatRepairDiagnostics([]string{value})
var got []string
if err := json.Unmarshal([]byte(encoded), &got); err != nil {
t.Fatal(err)
}
if len(encoded) > maxRepairDiagnosticBytes || len(got) != 2 || got[1] != omittedRepairDiagnostics || !strings.HasPrefix(strings.ToValidUTF8(value, "\uFFFD"), got[0]) {
t.Fatalf("oversize diagnostics length=%d, values=%d", len(encoded), len(got))
}
}
func manyRepairDiagnostics() []string { func manyRepairDiagnostics() []string {
diagnostics := make([]string, 1_000) diagnostics := make([]string, 1_000)
for index := range diagnostics { for index := range diagnostics {