satellite/metainfo/metabase: add NodeAliasMap
We need to keep an inmemory cache to avoid lookups into aliases table. This adds the inmemory state of the cache. Change-Id: Ief2b9bb19e10b46839b9208472dfc3035eb49af3
This commit is contained in:
parent
322c3a167b
commit
0260966de4
61
satellite/metainfo/metabase/aliascache.go
Normal file
61
satellite/metainfo/metabase/aliascache.go
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package metabase
|
||||
|
||||
import (
|
||||
"storj.io/common/storj"
|
||||
)
|
||||
|
||||
// NodeAliasMap contains bidirectional mapping between node ID and a NodeAlias.
|
||||
type NodeAliasMap struct {
|
||||
node map[NodeAlias]storj.NodeID
|
||||
alias map[storj.NodeID]NodeAlias
|
||||
}
|
||||
|
||||
// NewNodeAliasMap creates a new alias map from the given entries.
|
||||
func NewNodeAliasMap(entries []NodeAliasEntry) *NodeAliasMap {
|
||||
m := &NodeAliasMap{
|
||||
node: make(map[NodeAlias]storj.NodeID, len(entries)),
|
||||
alias: make(map[storj.NodeID]NodeAlias, len(entries)),
|
||||
}
|
||||
for _, e := range entries {
|
||||
m.node[e.Alias] = e.ID
|
||||
m.alias[e.ID] = e.Alias
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Nodes returns NodeID-s for the given aliases and aliases that are not in this map.
|
||||
func (m *NodeAliasMap) Nodes(aliases []NodeAlias) (xs []storj.NodeID, missing []NodeAlias) {
|
||||
xs = make([]storj.NodeID, 0, len(aliases))
|
||||
for _, p := range aliases {
|
||||
if x, ok := m.node[p]; ok {
|
||||
xs = append(xs, x)
|
||||
} else {
|
||||
missing = append(missing, p)
|
||||
}
|
||||
}
|
||||
return xs, missing
|
||||
}
|
||||
|
||||
// Aliases returns alises-s for the given node ID-s and node ID-s that are not in this map.
|
||||
func (m *NodeAliasMap) Aliases(nodes []storj.NodeID) (xs []NodeAlias, missing []storj.NodeID) {
|
||||
xs = make([]NodeAlias, 0, len(nodes))
|
||||
for _, n := range nodes {
|
||||
if x, ok := m.alias[n]; ok {
|
||||
xs = append(xs, x)
|
||||
} else {
|
||||
missing = append(missing, n)
|
||||
}
|
||||
}
|
||||
return xs, missing
|
||||
}
|
||||
|
||||
// Size returns the number of entries in this map.
|
||||
func (m *NodeAliasMap) Size() int {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
return len(m.node)
|
||||
}
|
114
satellite/metainfo/metabase/aliascache_test.go
Normal file
114
satellite/metainfo/metabase/aliascache_test.go
Normal file
@ -0,0 +1,114 @@
|
||||
// Copyright (C) 2021 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package metabase_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"storj.io/common/storj"
|
||||
"storj.io/common/testcontext"
|
||||
"storj.io/common/testrand"
|
||||
"storj.io/storj/satellite/metainfo/metabase"
|
||||
)
|
||||
|
||||
func TestNodeAliasMap(t *testing.T) {
|
||||
defer testcontext.New(t).Cleanup()
|
||||
|
||||
n1 := testrand.NodeID()
|
||||
n2 := testrand.NodeID()
|
||||
n3 := testrand.NodeID()
|
||||
|
||||
nx1 := testrand.NodeID()
|
||||
nx2 := testrand.NodeID()
|
||||
|
||||
{
|
||||
emptyMap := metabase.NewNodeAliasMap(nil)
|
||||
nodes, missing := emptyMap.Nodes([]metabase.NodeAlias{0, 1, 2})
|
||||
require.Empty(t, nodes)
|
||||
require.Equal(t, []metabase.NodeAlias{0, 1, 2}, missing)
|
||||
}
|
||||
{
|
||||
emptyMap := metabase.NewNodeAliasMap(nil)
|
||||
aliases, missing := emptyMap.Aliases([]storj.NodeID{n1, n2, n3})
|
||||
require.Empty(t, aliases)
|
||||
require.Equal(t, []storj.NodeID{n1, n2, n3}, missing)
|
||||
}
|
||||
|
||||
m := metabase.NewNodeAliasMap([]metabase.NodeAliasEntry{
|
||||
{n1, 1},
|
||||
{n2, 2},
|
||||
{n3, 3},
|
||||
})
|
||||
require.NotNil(t, m)
|
||||
require.Equal(t, 3, m.Size())
|
||||
|
||||
testNodes := []struct {
|
||||
in []metabase.NodeAlias
|
||||
out []storj.NodeID
|
||||
missing []metabase.NodeAlias
|
||||
}{
|
||||
{
|
||||
in: nil,
|
||||
},
|
||||
{
|
||||
in: []metabase.NodeAlias{1, 3, 2},
|
||||
out: []storj.NodeID{n1, n3, n2},
|
||||
},
|
||||
{
|
||||
in: []metabase.NodeAlias{5, 4},
|
||||
missing: []metabase.NodeAlias{5, 4},
|
||||
},
|
||||
}
|
||||
for _, test := range testNodes {
|
||||
out, missing := m.Nodes(test.in)
|
||||
|
||||
if len(out) == 0 {
|
||||
out = nil
|
||||
}
|
||||
if len(missing) == 0 {
|
||||
missing = nil
|
||||
}
|
||||
|
||||
require.EqualValues(t, test.out, out)
|
||||
require.EqualValues(t, test.missing, missing)
|
||||
}
|
||||
|
||||
testAliases := []struct {
|
||||
in []storj.NodeID
|
||||
out []metabase.NodeAlias
|
||||
missing []storj.NodeID
|
||||
}{
|
||||
{
|
||||
in: nil,
|
||||
},
|
||||
{
|
||||
in: []storj.NodeID{n1, n3, n2},
|
||||
out: []metabase.NodeAlias{1, 3, 2},
|
||||
},
|
||||
{
|
||||
in: []storj.NodeID{nx2, nx1},
|
||||
missing: []storj.NodeID{nx2, nx1},
|
||||
},
|
||||
{
|
||||
in: []storj.NodeID{n1, nx2, n3, nx1, n2},
|
||||
out: []metabase.NodeAlias{1, 3, 2},
|
||||
missing: []storj.NodeID{nx2, nx1},
|
||||
},
|
||||
}
|
||||
for _, test := range testAliases {
|
||||
out, missing := m.Aliases(test.in)
|
||||
|
||||
if len(out) == 0 {
|
||||
out = nil
|
||||
}
|
||||
if len(missing) == 0 {
|
||||
missing = nil
|
||||
}
|
||||
|
||||
require.EqualValues(t, test.out, out)
|
||||
require.EqualValues(t, test.missing, missing)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user