frostfs-node/pkg/services/tree/heap/ordered_slice.go
Evgenii Stratonikov 77bdadde14 [#957] treesvc/heap: Cache FileName attribute
```
goos: linux
goarch: amd64
pkg: git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/tree
cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
                        │     new      │                cache                 │
                        │    sec/op    │    sec/op     vs base                │
GetSubTree/latency-8      4.059m ± 20%   2.350m ± 19%  -42.11% (p=0.000 n=10)
GetSubTree/total_time-8   78.82m ±  4%   70.62m ±  8%  -10.39% (p=0.001 n=10)
geomean                   17.89m         12.88m        -27.98%

                        │     new      │                cache                 │
                        │     B/op     │     B/op      vs base                │
GetSubTree/latency-8      32.81Mi ± 0%   43.87Mi ± 0%  +33.72% (p=0.000 n=10)
GetSubTree/total_time-8   32.81Mi ± 0%   43.87Mi ± 0%  +33.73% (p=0.000 n=10)
geomean                   32.81Mi        43.87Mi       +33.72%

                        │     new     │               cache                │
                        │  allocs/op  │  allocs/op   vs base               │
GetSubTree/latency-8      400.0k ± 0%   400.0k ± 0%  +0.01% (p=0.000 n=10)
GetSubTree/total_time-8   400.0k ± 0%   400.0k ± 0%  +0.01% (p=0.000 n=10)
geomean                   400.0k        400.0k       +0.01%
```

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
2024-02-06 10:15:28 +03:00

56 lines
1,002 B
Go

package heap
import (
"bytes"
"sort"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/pilorama"
)
type OrderedSlice struct {
nodes []node
sorted bool
}
type node struct {
filename []byte
info *pilorama.NodeInfo
}
func NewOrderedSlice() *OrderedSlice {
return new(OrderedSlice)
}
func (s *OrderedSlice) Insert(infos ...pilorama.NodeInfo) {
s.sorted = false
for i := range infos {
s.nodes = append(s.nodes, node{
filename: infos[i].Meta.GetAttr(pilorama.AttributeFilename),
info: &infos[i],
})
}
}
func (s *OrderedSlice) IsEmpty() bool {
return len(s.nodes) == 0
}
func (s *OrderedSlice) ExtractMin() pilorama.NodeInfo {
if !s.sorted {
sortByFilename(s.nodes)
s.sorted = true
}
node := s.nodes[0]
s.nodes = s.nodes[1:]
return *node.info
}
func sortByFilename(nodes []node) {
if len(nodes) == 0 {
return
}
less := func(i, j int) bool {
return bytes.Compare(nodes[i].filename, nodes[j].filename) < 0
}
sort.Slice(nodes, less)
}