frostfs-node/pkg/services/tree/container.go
Alexander Chuprov 9b113c3156
Some checks failed
DCO action / DCO (pull_request) Successful in 59s
Vulncheck / Vulncheck (pull_request) Successful in 1m4s
Pre-commit hooks / Pre-commit (pull_request) Successful in 1m55s
Build / Build Components (pull_request) Successful in 2m4s
Tests and linters / Staticcheck (pull_request) Successful in 2m38s
Tests and linters / Lint (pull_request) Successful in 3m16s
Tests and linters / Run gofumpt (pull_request) Successful in 3m54s
Tests and linters / Tests (pull_request) Successful in 4m12s
Tests and linters / gopls check (pull_request) Successful in 4m31s
Tests and linters / Tests with -race (pull_request) Successful in 4m38s
OCI image / Build container images (push) Failing after 18s
Vulncheck / Vulncheck (push) Successful in 1m2s
Pre-commit hooks / Pre-commit (push) Successful in 1m39s
Build / Build Components (push) Successful in 1m45s
Tests and linters / Staticcheck (push) Successful in 2m18s
Tests and linters / Run gofumpt (push) Successful in 2m46s
Tests and linters / Lint (push) Successful in 3m5s
Tests and linters / Tests with -race (push) Successful in 3m23s
Tests and linters / Tests (push) Successful in 3m52s
Tests and linters / gopls check (push) Successful in 4m18s
[#1613] morph: Add tracing for morph queries to neo-go
Signed-off-by: Alexander Chuprov <a.chuprov@yadro.com>
2025-02-05 16:38:20 +03:00

90 lines
2.1 KiB
Go

package tree
import (
"bytes"
"context"
"crypto/sha256"
"fmt"
"sync"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object_manager/placement"
cidSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
netmapSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
"github.com/hashicorp/golang-lru/v2/simplelru"
)
type containerCache struct {
sync.Mutex
nm *netmapSDK.NetMap
lru *simplelru.LRU[string, containerCacheItem]
}
func (c *containerCache) init(size int) {
c.lru, _ = simplelru.NewLRU[string, containerCacheItem](size, nil) // no error, size is positive
}
type containerCacheItem struct {
cnr *container.Container
local int
nodes []netmapSDK.NodeInfo
}
const defaultContainerCacheSize = 10
// getContainerNodes returns nodes in the container and a position of local key in the list.
func (s *Service) getContainerNodes(ctx context.Context, cid cidSDK.ID) ([]netmapSDK.NodeInfo, int, error) {
nm, err := s.nmSource.GetNetMap(ctx, 0)
if err != nil {
return nil, -1, fmt.Errorf("can't get netmap: %w", err)
}
cnr, err := s.cnrSource.Get(ctx, cid)
if err != nil {
return nil, -1, fmt.Errorf("can't get container: %w", err)
}
cidStr := cid.String()
s.containerCache.Lock()
if s.containerCache.nm != nm {
s.containerCache.lru.Purge()
} else if item, ok := s.containerCache.lru.Get(cidStr); ok {
if item.cnr == cnr {
s.containerCache.Unlock()
return item.nodes, item.local, nil
}
}
s.containerCache.Unlock()
policy := cnr.Value.PlacementPolicy()
rawCID := make([]byte, sha256.Size)
cid.Encode(rawCID)
cntNodes, err := nm.ContainerNodes(policy, rawCID)
if err != nil {
return nil, -1, err
}
nodes := placement.FlattenNodes(cntNodes)
localPos := -1
for i := range nodes {
if bytes.Equal(nodes[i].PublicKey(), s.rawPub) {
localPos = i
break
}
}
s.containerCache.Lock()
s.containerCache.nm = nm
s.containerCache.lru.Add(cidStr, containerCacheItem{
cnr: cnr,
local: localPos,
nodes: nodes,
})
s.containerCache.Unlock()
return nodes, localPos, err
}