Add private canonical path prefix index

This commit is contained in:
2026-10-09 03:30:01 +00:00
parent d34a98d34b
commit db2d8ed217
3 changed files with 220 additions and 1 deletions

View File

@@ -0,0 +1,81 @@
package engine
import (
"slices"
"strings"
"testing"
)
func TestPathPrefixIndexMatchesPointerScans(t *testing.T) {
entries := []struct {
pointer string
id int
}{
{pointer: "", id: 12},
{pointer: "/", id: 9},
{pointer: "/a", id: 6},
{pointer: "/a", id: 2},
{pointer: "/a/b", id: 4},
{pointer: "/a/b/c", id: 0},
{pointer: "/a/bc", id: 10},
{pointer: "/a~1b", id: 3},
{pointer: "/a~0b", id: 1},
{pointer: "/a~01b", id: 5},
{pointer: "/items/0", id: 8},
{pointer: "/items/01", id: 7},
{pointer: "/items/+1", id: 11},
}
var index pathPrefixIndex
for _, entry := range entries {
index.insert(entry.pointer, entry.id)
}
queries := []string{
"", "/", "/a", "/a/b", "/a/b/c", "/a/b/c/d", "/a/bc", "/a/bc/d",
"/a~1b", "/a~0b", "/a~01b", "/items", "/items/0", "/items/01", "/items/1", "/missing",
}
for _, query := range queries {
gotAncestors := make([]int, 0)
index.visitAncestors(query, func(id int) { gotAncestors = append(gotAncestors, id) })
wantAncestors := make([]int, 0)
gotDescendants := make([]int, 0)
wantDescendants := make([]int, 0)
wantEarliest, foundEarliest := 0, false
for _, entry := range entries {
if pointerContainsByString(entry.pointer, query) {
wantAncestors = append(wantAncestors, entry.id)
}
if pointerContainsByString(query, entry.pointer) {
wantDescendants = append(wantDescendants, entry.id)
}
if pointerContainsByString(entry.pointer, query) || pointerContainsByString(query, entry.pointer) {
if !foundEarliest || entry.id < wantEarliest {
wantEarliest, foundEarliest = entry.id, true
}
}
}
index.visitDescendants(query, func(id int) { gotDescendants = append(gotDescendants, id) })
if !slices.Equal(sortedPrefixIDs(gotAncestors), sortedPrefixIDs(wantAncestors)) {
t.Errorf("ancestors(%q) = %v, want %v", query, sortedPrefixIDs(gotAncestors), sortedPrefixIDs(wantAncestors))
}
if !slices.Equal(sortedPrefixIDs(gotDescendants), sortedPrefixIDs(wantDescendants)) {
t.Errorf("descendants(%q) = %v, want %v", query, sortedPrefixIDs(gotDescendants), sortedPrefixIDs(wantDescendants))
}
gotEarliest, gotFound := index.earliestIntersectingID(query)
if gotEarliest != wantEarliest || gotFound != foundEarliest {
t.Errorf("earliestIntersectingID(%q) = %d, %v, want %d, %v", query, gotEarliest, gotFound, wantEarliest, foundEarliest)
}
}
}
func pointerContainsByString(container, descendant string) bool {
if container == "" {
return true
}
return descendant == container || strings.HasPrefix(descendant, container+"/")
}
func sortedPrefixIDs(ids []int) []int {
result := slices.Clone(ids)
slices.Sort(result)
return result
}