From ec9343ebd625cc97a0dd8b09f030f84b142b7ca4 Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 11 Jan 2026 04:16:00 +0900 Subject: [PATCH] container/check: intern absolute pathnames This improves performance in heavy users like internal/pkg. Signed-off-by: Ophestra --- container/check/absolute.go | 49 ++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/container/check/absolute.go b/container/check/absolute.go index fcb260c..26f0def 100644 --- a/container/check/absolute.go +++ b/container/check/absolute.go @@ -9,6 +9,7 @@ import ( "slices" "strings" "syscall" + "unique" ) // AbsoluteError is returned by [NewAbs] and holds the invalid pathname. @@ -24,25 +25,35 @@ func (e *AbsoluteError) Is(target error) bool { } // Absolute holds a pathname checked to be absolute. -type Absolute struct{ pathname string } +type Absolute struct{ pathname unique.Handle[string] } + +// ok returns whether [Absolute] is not the zero value. +func (a *Absolute) ok() bool { return a != nil && *a != (Absolute{}) } // unsafeAbs returns [check.Absolute] on any string value. -func unsafeAbs(pathname string) *Absolute { return &Absolute{pathname} } +func unsafeAbs(pathname string) *Absolute { + return &Absolute{unique.Make(pathname)} +} +// String returns the checked pathname. func (a *Absolute) String() string { - if a.pathname == "" { + if !a.ok() { panic("attempted use of zero Absolute") } + return a.pathname.Value() +} + +// Handle returns the underlying [unique.Handle]. +func (a *Absolute) Handle() unique.Handle[string] { return a.pathname } +// Is efficiently compares the underlying pathname. func (a *Absolute) Is(v *Absolute) bool { if a == nil && v == nil { return true } - return a != nil && v != nil && - a.pathname != "" && v.pathname != "" && - a.pathname == v.pathname + return a.ok() && v.ok() && a.pathname == v.pathname } // NewAbs checks pathname and returns a new [Absolute] if pathname is absolute. @@ -70,17 +81,27 @@ func (a *Absolute) Append(elem ...string) *Absolute { // Dir calls [path.Dir] with [Absolute] as its argument. func (a *Absolute) Dir() *Absolute { return unsafeAbs(path.Dir(a.String())) } -func (a *Absolute) GobEncode() ([]byte, error) { return []byte(a.String()), nil } +// GobEncode returns the checked pathname. +func (a *Absolute) GobEncode() ([]byte, error) { + return []byte(a.String()), nil +} + +// GobDecode stores data if it represents an absolute pathname. func (a *Absolute) GobDecode(data []byte) error { pathname := string(data) if !path.IsAbs(pathname) { return &AbsoluteError{pathname} } - a.pathname = pathname + a.pathname = unique.Make(pathname) return nil } -func (a *Absolute) MarshalJSON() ([]byte, error) { return json.Marshal(a.String()) } +// MarshalJSON returns a JSON representation of the checked pathname. +func (a *Absolute) MarshalJSON() ([]byte, error) { + return json.Marshal(a.String()) +} + +// UnmarshalJSON stores data if it represents an absolute pathname. func (a *Absolute) UnmarshalJSON(data []byte) error { var pathname string if err := json.Unmarshal(data, &pathname); err != nil { @@ -89,16 +110,20 @@ func (a *Absolute) UnmarshalJSON(data []byte) error { if !path.IsAbs(pathname) { return &AbsoluteError{pathname} } - a.pathname = pathname + a.pathname = unique.Make(pathname) return nil } // SortAbs calls [slices.SortFunc] for a slice of [Absolute]. func SortAbs(x []*Absolute) { - slices.SortFunc(x, func(a, b *Absolute) int { return strings.Compare(a.String(), b.String()) }) + slices.SortFunc(x, func(a, b *Absolute) int { + return strings.Compare(a.String(), b.String()) + }) } // CompactAbs calls [slices.CompactFunc] for a slice of [Absolute]. func CompactAbs(s []*Absolute) []*Absolute { - return slices.CompactFunc(s, func(a *Absolute, b *Absolute) bool { return a.String() == b.String() }) + return slices.CompactFunc(s, func(a *Absolute, b *Absolute) bool { + return a.Is(b) + }) }