GetIndex returns the encoder index for the given node. On the first call the sortedIdx array is built (O(n log n) sort on a flat []uint32), then subsequent calls use binary search (O(log n)). This turns out to be much faster than building a map[*ast.Node]uint32 and not significantly slower for looku
(node *ast.Node)
| 315 | // then subsequent calls use binary search (O(log n)). This turns out to be much faster than |
| 316 | // building a map[*ast.Node]uint32 and not significantly slower for lookups. |
| 317 | func (t *NodeIndexTable) GetIndex(node *ast.Node) uint32 { |
| 318 | t.sortedOnce.Do(func() { |
| 319 | idx := make([]uint32, 0, len(t.Nodes)) |
| 320 | for i, n := range t.Nodes { |
| 321 | if n != nil { |
| 322 | idx = append(idx, uint32(i)) |
| 323 | } |
| 324 | } |
| 325 | nodes := t.Nodes |
| 326 | slices.SortFunc(idx, func(a, b uint32) int { |
| 327 | return cmp.Compare(ast.GetNodeId(nodes[a]), ast.GetNodeId(nodes[b])) |
| 328 | }) |
| 329 | t.sortedIdx = idx |
| 330 | }) |
| 331 | target := ast.GetNodeId(node) |
| 332 | i, found := core.BinarySearchUniqueFunc(t.sortedIdx, func(_ int, el uint32) int { |
| 333 | return cmp.Compare(ast.GetNodeId(t.Nodes[el]), target) |
| 334 | }) |
| 335 | if found { |
| 336 | return t.sortedIdx[i] |
| 337 | } |
| 338 | return 0 |
| 339 | } |
| 340 | |
| 341 | // BuildNodeIndexTable walks the AST in the same order as encodeTree and builds |
| 342 | // a NodeIndexTable without performing the full binary encoding. This is used to |