Update go version
This commit is contained in:
96
vendor/honnef.co/go/tools/internal/xtools-internal/graph/index.go
vendored
Normal file
96
vendor/honnef.co/go/tools/internal/xtools-internal/graph/index.go
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright 2026 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package graph
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"iter"
|
||||
"slices"
|
||||
)
|
||||
|
||||
// An Index is an immutable, bijective map between [0, N) and an ordered list of keys.
|
||||
type Index[Key comparable] struct {
|
||||
// There are three Index representations:
|
||||
//
|
||||
// - If identN > 0, an identity map of [0, identN).
|
||||
// - If index == nil, a sorted integer index in values.
|
||||
// - Otherwise, a full index in values and index.
|
||||
|
||||
identN int
|
||||
values []Key
|
||||
index map[Key]int
|
||||
}
|
||||
|
||||
// NewIndex returns an index for the specified list of values.
|
||||
func NewIndex[Key comparable](values iter.Seq[Key]) *Index[Key] {
|
||||
vs := slices.Collect(values)
|
||||
if len(vs) == 0 {
|
||||
return new(Index[Key])
|
||||
}
|
||||
|
||||
// Fast path: a naturally sorted list needs no index. (Sadly, there's no way
|
||||
// to ask "is Key ordered?")
|
||||
if vi, ok := any(vs).([]int); ok && slices.IsSorted(vi) {
|
||||
return &Index[Key]{values: vs}
|
||||
}
|
||||
|
||||
index := make(map[Key]int, len(vs))
|
||||
for i, v := range vs {
|
||||
index[v] = i
|
||||
}
|
||||
return &Index[Key]{values: vs, index: index}
|
||||
}
|
||||
|
||||
// NewIdentityIndex returns an index that maps [0, n) to [0, n).
|
||||
func NewIdentityIndex(n int) *Index[int] {
|
||||
if n < 0 {
|
||||
panic("n < 0")
|
||||
}
|
||||
// If n == 0, this is actually a "sorted integer index", but it doesn't
|
||||
// matter because everything is out of bounds either way.
|
||||
return &Index[int]{identN: n}
|
||||
}
|
||||
|
||||
// Value maps an index to a key.
|
||||
func (ix *Index[Key]) Value(index int) Key {
|
||||
if ix.identN > 0 {
|
||||
if index < 0 || index >= ix.identN {
|
||||
panic(fmt.Sprintf("index %d out of range [0, %d)", index, ix.identN))
|
||||
}
|
||||
return any(index).(Key)
|
||||
}
|
||||
if index < 0 || index >= len(ix.values) {
|
||||
panic(fmt.Sprintf("index %d out of range [0, %d)", index, ix.identN))
|
||||
}
|
||||
return ix.values[index]
|
||||
}
|
||||
|
||||
// Index maps a key to an index.
|
||||
func (ix *Index[Key]) Index(key Key) int {
|
||||
if key, ok := any(key).(int); ok {
|
||||
// Integer-only optimizations.
|
||||
switch {
|
||||
case ix.identN > 0:
|
||||
// Identity.
|
||||
if 0 <= key && key < ix.identN {
|
||||
return key
|
||||
}
|
||||
goto oob
|
||||
|
||||
case ix.index == nil:
|
||||
// Sorted integers.
|
||||
if i, ok := slices.BinarySearch(any(ix.values).([]int), key); ok {
|
||||
return i
|
||||
}
|
||||
goto oob
|
||||
}
|
||||
}
|
||||
if i, ok := ix.index[key]; ok {
|
||||
return i
|
||||
}
|
||||
|
||||
oob:
|
||||
panic(fmt.Sprintf("key %v not in index", key))
|
||||
}
|
||||
Reference in New Issue
Block a user