forked from TrueCloudLab/frostfs-sdk-go
[#168] netmap: Replace pointer slices with non-pointer slices
- []*Replica => []Replica - []*Selector => []Selector - []*Filter => []Filter - []*NetworkParameter => []NetworkParameter - []*Node => []Node Also introduces `filter.id()`` function to store filters in numCache map. Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
e70bf05fb9
commit
cdcbaa1677
15 changed files with 114 additions and 127 deletions
|
@ -18,7 +18,7 @@ type Context struct {
|
||||||
Selections map[string][]Nodes
|
Selections map[string][]Nodes
|
||||||
|
|
||||||
// numCache stores parsed numeric values.
|
// numCache stores parsed numeric values.
|
||||||
numCache map[*Filter]uint64
|
numCache map[string]uint64
|
||||||
// pivot is a seed for HRW.
|
// pivot is a seed for HRW.
|
||||||
pivot []byte
|
pivot []byte
|
||||||
// pivotHash is a saved HRW hash of pivot
|
// pivotHash is a saved HRW hash of pivot
|
||||||
|
@ -56,7 +56,7 @@ func NewContext(nm *Netmap) *Context {
|
||||||
Selectors: make(map[string]*Selector),
|
Selectors: make(map[string]*Selector),
|
||||||
Selections: make(map[string][]Nodes),
|
Selections: make(map[string][]Nodes),
|
||||||
|
|
||||||
numCache: make(map[*Filter]uint64),
|
numCache: make(map[string]uint64),
|
||||||
aggregator: newMeanIQRAgg,
|
aggregator: newMeanIQRAgg,
|
||||||
weightFunc: GetDefaultWeightFunc(nm.Nodes),
|
weightFunc: GetDefaultWeightFunc(nm.Nodes),
|
||||||
cbf: defaultCBF,
|
cbf: defaultCBF,
|
||||||
|
|
|
@ -21,8 +21,9 @@ func (c *Context) applyFilter(name string, b *Node) bool {
|
||||||
|
|
||||||
// processFilters processes filters and returns error is any of them is invalid.
|
// processFilters processes filters and returns error is any of them is invalid.
|
||||||
func (c *Context) processFilters(p *PlacementPolicy) error {
|
func (c *Context) processFilters(p *PlacementPolicy) error {
|
||||||
for _, f := range p.Filters() {
|
filters := p.Filters()
|
||||||
if err := c.processFilter(f, true); err != nil {
|
for i := range filters {
|
||||||
|
if err := c.processFilter(&filters[i], true); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +51,7 @@ func (c *Context) processFilter(f *Filter, top bool) error {
|
||||||
switch f.Operation() {
|
switch f.Operation() {
|
||||||
case OpAND, OpOR:
|
case OpAND, OpOR:
|
||||||
for _, flt := range f.InnerFilters() {
|
for _, flt := range f.InnerFilters() {
|
||||||
if err := c.processFilter(flt, false); err != nil {
|
if err := c.processFilter(&flt, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +70,7 @@ func (c *Context) processFilter(f *Filter, top bool) error {
|
||||||
return fmt.Errorf("%w: '%s'", ErrInvalidNumber, f.Value())
|
return fmt.Errorf("%w: '%s'", ErrInvalidNumber, f.Value())
|
||||||
}
|
}
|
||||||
|
|
||||||
c.numCache[f] = n
|
c.numCache[f.Value()] = n
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("%w: %s", ErrInvalidFilterOp, f.Operation())
|
return fmt.Errorf("%w: %s", ErrInvalidFilterOp, f.Operation())
|
||||||
}
|
}
|
||||||
|
@ -90,10 +91,10 @@ func (c *Context) match(f *Filter, b *Node) bool {
|
||||||
case OpAND, OpOR:
|
case OpAND, OpOR:
|
||||||
for _, lf := range f.InnerFilters() {
|
for _, lf := range f.InnerFilters() {
|
||||||
if lf.Name() != "" {
|
if lf.Name() != "" {
|
||||||
lf = c.Filters[lf.Name()]
|
lf = *c.Filters[lf.Name()]
|
||||||
}
|
}
|
||||||
|
|
||||||
ok := c.match(lf, b)
|
ok := c.match(&lf, b)
|
||||||
if ok == (f.Operation() == OpOR) {
|
if ok == (f.Operation() == OpOR) {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
@ -132,13 +133,13 @@ func (c *Context) matchKeyValue(f *Filter, b *Node) bool {
|
||||||
|
|
||||||
switch f.Operation() {
|
switch f.Operation() {
|
||||||
case OpGT:
|
case OpGT:
|
||||||
return attr > c.numCache[f]
|
return attr > c.numCache[f.Value()]
|
||||||
case OpGE:
|
case OpGE:
|
||||||
return attr >= c.numCache[f]
|
return attr >= c.numCache[f.Value()]
|
||||||
case OpLT:
|
case OpLT:
|
||||||
return attr < c.numCache[f]
|
return attr < c.numCache[f.Value()]
|
||||||
case OpLE:
|
case OpLE:
|
||||||
return attr <= c.numCache[f]
|
return attr <= c.numCache[f.Value()]
|
||||||
default:
|
default:
|
||||||
// do nothing and return false
|
// do nothing and return false
|
||||||
}
|
}
|
||||||
|
@ -214,31 +215,31 @@ func (f *Filter) SetOperation(op Operation) {
|
||||||
(*netmap.Filter)(f).SetOp(op.ToV2())
|
(*netmap.Filter)(f).SetOp(op.ToV2())
|
||||||
}
|
}
|
||||||
|
|
||||||
func filtersFromV2(fs []*netmap.Filter) []*Filter {
|
func filtersFromV2(fs []netmap.Filter) []Filter {
|
||||||
if fs == nil {
|
if fs == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make([]*Filter, 0, len(fs))
|
res := make([]Filter, len(fs))
|
||||||
|
|
||||||
for i := range fs {
|
for i := range fs {
|
||||||
res = append(res, NewFilterFromV2(fs[i]))
|
res[i] = *NewFilterFromV2(&fs[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// InnerFilters returns list of inner filters.
|
// InnerFilters returns list of inner filters.
|
||||||
func (f *Filter) InnerFilters() []*Filter {
|
func (f *Filter) InnerFilters() []Filter {
|
||||||
return filtersFromV2((*netmap.Filter)(f).GetFilters())
|
return filtersFromV2((*netmap.Filter)(f).GetFilters())
|
||||||
}
|
}
|
||||||
|
|
||||||
func filtersToV2(fs []*Filter) (fsV2 []*netmap.Filter) {
|
func filtersToV2(fs []Filter) (fsV2 []netmap.Filter) {
|
||||||
if fs != nil {
|
if fs != nil {
|
||||||
fsV2 = make([]*netmap.Filter, 0, len(fs))
|
fsV2 = make([]netmap.Filter, len(fs))
|
||||||
|
|
||||||
for i := range fs {
|
for i := range fs {
|
||||||
fsV2 = append(fsV2, fs[i].ToV2())
|
fsV2[i] = *fs[i].ToV2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +247,7 @@ func filtersToV2(fs []*Filter) (fsV2 []*netmap.Filter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetInnerFilters sets list of inner filters.
|
// SetInnerFilters sets list of inner filters.
|
||||||
func (f *Filter) SetInnerFilters(fs ...*Filter) {
|
func (f *Filter) SetInnerFilters(fs ...Filter) {
|
||||||
(*netmap.Filter)(f).
|
(*netmap.Filter)(f).
|
||||||
SetFilters(filtersToV2(fs))
|
SetFilters(filtersToV2(fs))
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestContext_ProcessFilters(t *testing.T) {
|
func TestContext_ProcessFilters(t *testing.T) {
|
||||||
fs := []*Filter{
|
fs := []Filter{
|
||||||
newFilter("StorageSSD", "Storage", "SSD", OpEQ),
|
newFilter("StorageSSD", "Storage", "SSD", OpEQ),
|
||||||
newFilter("GoodRating", "Rating", "4", OpGE),
|
newFilter("GoodRating", "Rating", "4", OpGE),
|
||||||
newFilter("Main", "", "", OpAND,
|
newFilter("Main", "", "", OpAND,
|
||||||
|
@ -24,17 +24,17 @@ func TestContext_ProcessFilters(t *testing.T) {
|
||||||
require.NoError(t, c.processFilters(p))
|
require.NoError(t, c.processFilters(p))
|
||||||
require.Equal(t, 3, len(c.Filters))
|
require.Equal(t, 3, len(c.Filters))
|
||||||
for _, f := range fs {
|
for _, f := range fs {
|
||||||
require.Equal(t, f, c.Filters[f.Name()])
|
require.Equal(t, f, *c.Filters[f.Name()])
|
||||||
}
|
}
|
||||||
|
|
||||||
require.Equal(t, uint64(4), c.numCache[fs[1]])
|
require.Equal(t, uint64(4), c.numCache[fs[1].Value()])
|
||||||
require.Equal(t, uint64(123), c.numCache[fs[2].InnerFilters()[1]])
|
require.Equal(t, uint64(123), c.numCache[fs[2].InnerFilters()[1].Value()])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext_ProcessFiltersInvalid(t *testing.T) {
|
func TestContext_ProcessFiltersInvalid(t *testing.T) {
|
||||||
errTestCases := []struct {
|
errTestCases := []struct {
|
||||||
name string
|
name string
|
||||||
filter *Filter
|
filter Filter
|
||||||
err error
|
err error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
@ -69,16 +69,11 @@ func TestContext_ProcessFiltersInvalid(t *testing.T) {
|
||||||
newFilter("*", "Rating", "3", OpGE),
|
newFilter("*", "Rating", "3", OpGE),
|
||||||
ErrInvalidFilterName,
|
ErrInvalidFilterName,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"MissingFilter",
|
|
||||||
nil,
|
|
||||||
ErrMissingField,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for _, tc := range errTestCases {
|
for _, tc := range errTestCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
c := NewContext(new(Netmap))
|
c := NewContext(new(Netmap))
|
||||||
p := newPlacementPolicy(1, nil, nil, []*Filter{tc.filter})
|
p := newPlacementPolicy(1, nil, nil, []Filter{tc.filter})
|
||||||
err := c.processFilters(p)
|
err := c.processFilters(p)
|
||||||
require.True(t, errors.Is(err, tc.err), "got: %v", err)
|
require.True(t, errors.Is(err, tc.err), "got: %v", err)
|
||||||
})
|
})
|
||||||
|
@ -93,12 +88,12 @@ func TestFilter_MatchSimple_InvalidOp(t *testing.T) {
|
||||||
|
|
||||||
f := newFilter("Main", "Rating", "5", OpEQ)
|
f := newFilter("Main", "Rating", "5", OpEQ)
|
||||||
c := NewContext(new(Netmap))
|
c := NewContext(new(Netmap))
|
||||||
p := newPlacementPolicy(1, nil, nil, []*Filter{f})
|
p := newPlacementPolicy(1, nil, nil, []Filter{f})
|
||||||
require.NoError(t, c.processFilters(p))
|
require.NoError(t, c.processFilters(p))
|
||||||
|
|
||||||
// just for the coverage
|
// just for the coverage
|
||||||
f.SetOperation(0)
|
f.SetOperation(0)
|
||||||
require.False(t, c.match(f, b))
|
require.False(t, c.match(&f, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testFilter() *Filter {
|
func testFilter() *Filter {
|
||||||
|
@ -174,11 +169,11 @@ func TestFilter_Operation(t *testing.T) {
|
||||||
func TestFilter_InnerFilters(t *testing.T) {
|
func TestFilter_InnerFilters(t *testing.T) {
|
||||||
f := NewFilter()
|
f := NewFilter()
|
||||||
|
|
||||||
f1, f2 := testFilter(), testFilter()
|
f1, f2 := *testFilter(), *testFilter()
|
||||||
|
|
||||||
f.SetInnerFilters(f1, f2)
|
f.SetInnerFilters(f1, f2)
|
||||||
|
|
||||||
require.Equal(t, []*Filter{f1, f2}, f.InnerFilters())
|
require.Equal(t, []Filter{f1, f2}, f.InnerFilters())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFilterEncoding(t *testing.T) {
|
func TestFilterEncoding(t *testing.T) {
|
||||||
|
@ -190,7 +185,7 @@ func TestFilterEncoding(t *testing.T) {
|
||||||
data, err := f.Marshal()
|
data, err := f.Marshal()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
f2 := NewFilter()
|
f2 := *NewFilter()
|
||||||
require.NoError(t, f2.Unmarshal(data))
|
require.NoError(t, f2.Unmarshal(data))
|
||||||
|
|
||||||
require.Equal(t, f, f2)
|
require.Equal(t, f, f2)
|
||||||
|
@ -200,7 +195,7 @@ func TestFilterEncoding(t *testing.T) {
|
||||||
data, err := f.MarshalJSON()
|
data, err := f.MarshalJSON()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
f2 := NewFilter()
|
f2 := *NewFilter()
|
||||||
require.NoError(t, f2.UnmarshalJSON(data))
|
require.NoError(t, f2.UnmarshalJSON(data))
|
||||||
|
|
||||||
require.Equal(t, f, f2)
|
require.Equal(t, f, f2)
|
||||||
|
|
|
@ -6,8 +6,7 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newFilter(name string, k, v string, op Operation, fs ...*Filter) *Filter {
|
func newFilter(name string, k, v string, op Operation, fs ...Filter) (f Filter) {
|
||||||
f := NewFilter()
|
|
||||||
f.SetName(name)
|
f.SetName(name)
|
||||||
f.SetKey(k)
|
f.SetKey(k)
|
||||||
f.SetOperation(op)
|
f.SetOperation(op)
|
||||||
|
@ -16,8 +15,7 @@ func newFilter(name string, k, v string, op Operation, fs ...*Filter) *Filter {
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSelector(name string, attr string, c Clause, count uint32, filter string) *Selector {
|
func newSelector(name string, attr string, c Clause, count uint32, filter string) (s Selector) {
|
||||||
s := NewSelector()
|
|
||||||
s.SetName(name)
|
s.SetName(name)
|
||||||
s.SetAttribute(attr)
|
s.SetAttribute(attr)
|
||||||
s.SetCount(count)
|
s.SetCount(count)
|
||||||
|
@ -26,7 +24,7 @@ func newSelector(name string, attr string, c Clause, count uint32, filter string
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPlacementPolicy(bf uint32, rs []*Replica, ss []*Selector, fs []*Filter) *PlacementPolicy {
|
func newPlacementPolicy(bf uint32, rs []Replica, ss []Selector, fs []Filter) *PlacementPolicy {
|
||||||
p := NewPlacementPolicy()
|
p := NewPlacementPolicy()
|
||||||
p.SetContainerBackupFactor(bf)
|
p.SetContainerBackupFactor(bf)
|
||||||
p.SetReplicas(rs...)
|
p.SetReplicas(rs...)
|
||||||
|
@ -35,17 +33,15 @@ func newPlacementPolicy(bf uint32, rs []*Replica, ss []*Selector, fs []*Filter)
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func newReplica(c uint32, s string) *Replica {
|
func newReplica(c uint32, s string) (r Replica) {
|
||||||
r := NewReplica()
|
|
||||||
r.SetCount(c)
|
r.SetCount(c)
|
||||||
r.SetSelector(s)
|
r.SetSelector(s)
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodeInfoFromAttributes(props ...string) NodeInfo {
|
func nodeInfoFromAttributes(props ...string) NodeInfo {
|
||||||
attrs := make([]*NodeAttribute, len(props)/2)
|
attrs := make([]NodeAttribute, len(props)/2)
|
||||||
for i := range attrs {
|
for i := range attrs {
|
||||||
attrs[i] = NewNodeAttribute()
|
|
||||||
attrs[i].SetKey(props[i*2])
|
attrs[i].SetKey(props[i*2])
|
||||||
attrs[i].SetValue(props[i*2+1])
|
attrs[i].SetValue(props[i*2+1])
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,6 @@ func (m *Netmap) GetContainerNodes(p *PlacementPolicy, pivot []byte) (ContainerN
|
||||||
result := make([]Nodes, len(p.Replicas()))
|
result := make([]Nodes, len(p.Replicas()))
|
||||||
|
|
||||||
for i, r := range p.Replicas() {
|
for i, r := range p.Replicas() {
|
||||||
if r == nil {
|
|
||||||
return nil, fmt.Errorf("%w: REPLICA", ErrMissingField)
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Selector() == "" {
|
if r.Selector() == "" {
|
||||||
if len(p.Selectors()) == 0 {
|
if len(p.Selectors()) == 0 {
|
||||||
s := new(Selector)
|
s := new(Selector)
|
||||||
|
|
|
@ -187,16 +187,16 @@ func (x *NetworkConfig) IterateParameters(f func(*NetworkParameter) bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Value returns value of the network parameter.
|
// Value returns value of the network parameter.
|
||||||
func (x *NetworkConfig) SetParameters(ps ...*NetworkParameter) {
|
func (x *NetworkConfig) SetParameters(ps ...NetworkParameter) {
|
||||||
var psV2 []*netmap.NetworkParameter
|
var psV2 []netmap.NetworkParameter
|
||||||
|
|
||||||
if ps != nil {
|
if ps != nil {
|
||||||
ln := len(ps)
|
ln := len(ps)
|
||||||
|
|
||||||
psV2 = make([]*netmap.NetworkParameter, 0, ln)
|
psV2 = make([]netmap.NetworkParameter, ln)
|
||||||
|
|
||||||
for i := 0; i < ln; i++ {
|
for i := 0; i < ln; i++ {
|
||||||
psV2 = append(psV2, ps[i].ToV2())
|
psV2[i] = *ps[i].ToV2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,19 +72,19 @@ func TestNetworkConfig_SetParameters(t *testing.T) {
|
||||||
|
|
||||||
require.Zero(t, called)
|
require.Zero(t, called)
|
||||||
|
|
||||||
pps := []*NetworkParameter{
|
pps := []NetworkParameter{
|
||||||
netmaptest.NetworkParameter(),
|
*netmaptest.NetworkParameter(),
|
||||||
netmaptest.NetworkParameter(),
|
*netmaptest.NetworkParameter(),
|
||||||
}
|
}
|
||||||
|
|
||||||
x.SetParameters(pps...)
|
x.SetParameters(pps...)
|
||||||
|
|
||||||
require.EqualValues(t, len(pps), x.NumberOfParameters())
|
require.EqualValues(t, len(pps), x.NumberOfParameters())
|
||||||
|
|
||||||
var dst []*NetworkParameter
|
var dst []NetworkParameter
|
||||||
|
|
||||||
x.IterateParameters(func(p *NetworkParameter) bool {
|
x.IterateParameters(func(p *NetworkParameter) bool {
|
||||||
dst = append(dst, p)
|
dst = append(dst, *p)
|
||||||
called++
|
called++
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,7 +20,7 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nodes represents slice of graph leafs.
|
// Nodes represents slice of graph leafs.
|
||||||
Nodes []*Node
|
Nodes []Node
|
||||||
)
|
)
|
||||||
|
|
||||||
// NodeState is an enumeration of various states of the NeoFS node.
|
// NodeState is an enumeration of various states of the NeoFS node.
|
||||||
|
@ -110,7 +110,7 @@ func (n Nodes) Hash() uint64 {
|
||||||
func NodesFromInfo(infos []NodeInfo) Nodes {
|
func NodesFromInfo(infos []NodeInfo) Nodes {
|
||||||
nodes := make(Nodes, len(infos))
|
nodes := make(Nodes, len(infos))
|
||||||
for i := range infos {
|
for i := range infos {
|
||||||
nodes[i] = newNodeV2(i, &infos[i])
|
nodes[i] = *newNodeV2(i, &infos[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes
|
return nodes
|
||||||
|
@ -142,7 +142,7 @@ func newNodeV2(index int, ni *NodeInfo) *Node {
|
||||||
func (n Nodes) Weights(wf weightFunc) []float64 {
|
func (n Nodes) Weights(wf weightFunc) []float64 {
|
||||||
w := make([]float64, 0, len(n))
|
w := make([]float64, 0, len(n))
|
||||||
for i := range n {
|
for i := range n {
|
||||||
w = append(w, wf(n[i]))
|
w = append(w, wf(&n[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return w
|
return w
|
||||||
|
@ -156,7 +156,7 @@ func (n *Node) Attribute(k string) string {
|
||||||
// GetBucketWeight computes weight for a Bucket.
|
// GetBucketWeight computes weight for a Bucket.
|
||||||
func GetBucketWeight(ns Nodes, a aggregator, wf weightFunc) float64 {
|
func GetBucketWeight(ns Nodes, a aggregator, wf weightFunc) float64 {
|
||||||
for i := range ns {
|
for i := range ns {
|
||||||
a.Add(wf(ns[i]))
|
a.Add(wf(&ns[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return a.Compute()
|
return a.Compute()
|
||||||
|
@ -355,7 +355,7 @@ func (i *NodeInfo) SetAddresses(v ...string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attributes returns list of the node attributes.
|
// Attributes returns list of the node attributes.
|
||||||
func (i *NodeInfo) Attributes() []*NodeAttribute {
|
func (i *NodeInfo) Attributes() []NodeAttribute {
|
||||||
if i == nil {
|
if i == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -366,21 +366,21 @@ func (i *NodeInfo) Attributes() []*NodeAttribute {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make([]*NodeAttribute, 0, len(as))
|
res := make([]NodeAttribute, len(as))
|
||||||
|
|
||||||
for i := range as {
|
for ind := range as {
|
||||||
res = append(res, NewNodeAttributeFromV2(as[i]))
|
res[ind] = *NewNodeAttributeFromV2(&as[ind])
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAttributes sets list of the node attributes.
|
// SetAttributes sets list of the node attributes.
|
||||||
func (i *NodeInfo) SetAttributes(as ...*NodeAttribute) {
|
func (i *NodeInfo) SetAttributes(as ...NodeAttribute) {
|
||||||
asV2 := make([]*netmap.Attribute, 0, len(as))
|
asV2 := make([]netmap.Attribute, len(as))
|
||||||
|
|
||||||
for i := range as {
|
for ind := range as {
|
||||||
asV2 = append(asV2, as[i].ToV2())
|
asV2[ind] = *as[ind].ToV2()
|
||||||
}
|
}
|
||||||
|
|
||||||
(*netmap.NodeInfo)(i).
|
(*netmap.NodeInfo)(i).
|
||||||
|
|
|
@ -152,7 +152,7 @@ func TestNodeInfo_State(t *testing.T) {
|
||||||
|
|
||||||
func TestNodeInfo_Attributes(t *testing.T) {
|
func TestNodeInfo_Attributes(t *testing.T) {
|
||||||
i := new(NodeInfo)
|
i := new(NodeInfo)
|
||||||
as := []*NodeAttribute{testNodeAttribute(), testNodeAttribute()}
|
as := []NodeAttribute{*testNodeAttribute(), *testNodeAttribute()}
|
||||||
|
|
||||||
i.SetAttributes(as...)
|
i.SetAttributes(as...)
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ func TestNodeInfoEncoding(t *testing.T) {
|
||||||
i.SetPublicKey([]byte{1, 2, 3})
|
i.SetPublicKey([]byte{1, 2, 3})
|
||||||
i.SetAddresses("192.168.0.1", "192.168.0.2")
|
i.SetAddresses("192.168.0.1", "192.168.0.2")
|
||||||
i.SetState(NodeStateOnline)
|
i.SetState(NodeStateOnline)
|
||||||
i.SetAttributes(testNodeAttribute())
|
i.SetAttributes(*testNodeAttribute())
|
||||||
|
|
||||||
t.Run("binary", func(t *testing.T) {
|
t.Run("binary", func(t *testing.T) {
|
||||||
data, err := i.Marshal()
|
data, err := i.Marshal()
|
||||||
|
|
|
@ -46,7 +46,7 @@ func (p *PlacementPolicy) SetSubnetID(subnet *subnetid.ID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replicas returns list of object replica descriptors.
|
// Replicas returns list of object replica descriptors.
|
||||||
func (p *PlacementPolicy) Replicas() []*Replica {
|
func (p *PlacementPolicy) Replicas() []Replica {
|
||||||
rs := (*netmap.PlacementPolicy)(p).
|
rs := (*netmap.PlacementPolicy)(p).
|
||||||
GetReplicas()
|
GetReplicas()
|
||||||
|
|
||||||
|
@ -54,24 +54,24 @@ func (p *PlacementPolicy) Replicas() []*Replica {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make([]*Replica, 0, len(rs))
|
res := make([]Replica, len(rs))
|
||||||
|
|
||||||
for i := range rs {
|
for i := range rs {
|
||||||
res = append(res, NewReplicaFromV2(rs[i]))
|
res[i] = *NewReplicaFromV2(&rs[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetReplicas sets list of object replica descriptors.
|
// SetReplicas sets list of object replica descriptors.
|
||||||
func (p *PlacementPolicy) SetReplicas(rs ...*Replica) {
|
func (p *PlacementPolicy) SetReplicas(rs ...Replica) {
|
||||||
var rsV2 []*netmap.Replica
|
var rsV2 []netmap.Replica
|
||||||
|
|
||||||
if rs != nil {
|
if rs != nil {
|
||||||
rsV2 = make([]*netmap.Replica, 0, len(rs))
|
rsV2 = make([]netmap.Replica, len(rs))
|
||||||
|
|
||||||
for i := range rs {
|
for i := range rs {
|
||||||
rsV2 = append(rsV2, rs[i].ToV2())
|
rsV2[i] = *rs[i].ToV2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ func (p *PlacementPolicy) SetContainerBackupFactor(f uint32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selector returns set of selectors to form the container's nodes subset.
|
// Selector returns set of selectors to form the container's nodes subset.
|
||||||
func (p *PlacementPolicy) Selectors() []*Selector {
|
func (p *PlacementPolicy) Selectors() []Selector {
|
||||||
rs := (*netmap.PlacementPolicy)(p).
|
rs := (*netmap.PlacementPolicy)(p).
|
||||||
GetSelectors()
|
GetSelectors()
|
||||||
|
|
||||||
|
@ -99,24 +99,24 @@ func (p *PlacementPolicy) Selectors() []*Selector {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res := make([]*Selector, 0, len(rs))
|
res := make([]Selector, len(rs))
|
||||||
|
|
||||||
for i := range rs {
|
for i := range rs {
|
||||||
res = append(res, NewSelectorFromV2(rs[i]))
|
res[i] = *NewSelectorFromV2(&rs[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSelectors sets set of selectors to form the container's nodes subset.
|
// SetSelectors sets set of selectors to form the container's nodes subset.
|
||||||
func (p *PlacementPolicy) SetSelectors(ss ...*Selector) {
|
func (p *PlacementPolicy) SetSelectors(ss ...Selector) {
|
||||||
var ssV2 []*netmap.Selector
|
var ssV2 []netmap.Selector
|
||||||
|
|
||||||
if ss != nil {
|
if ss != nil {
|
||||||
ssV2 = make([]*netmap.Selector, 0, len(ss))
|
ssV2 = make([]netmap.Selector, len(ss))
|
||||||
|
|
||||||
for i := range ss {
|
for i := range ss {
|
||||||
ssV2 = append(ssV2, ss[i].ToV2())
|
ssV2[i] = *ss[i].ToV2()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ func (p *PlacementPolicy) SetSelectors(ss ...*Selector) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filters returns list of named filters to reference in selectors.
|
// Filters returns list of named filters to reference in selectors.
|
||||||
func (p *PlacementPolicy) Filters() []*Filter {
|
func (p *PlacementPolicy) Filters() []Filter {
|
||||||
return filtersFromV2(
|
return filtersFromV2(
|
||||||
(*netmap.PlacementPolicy)(p).
|
(*netmap.PlacementPolicy)(p).
|
||||||
GetFilters(),
|
GetFilters(),
|
||||||
|
@ -132,7 +132,7 @@ func (p *PlacementPolicy) Filters() []*Filter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFilters sets list of named filters to reference in selectors.
|
// SetFilters sets list of named filters to reference in selectors.
|
||||||
func (p *PlacementPolicy) SetFilters(fs ...*Filter) {
|
func (p *PlacementPolicy) SetFilters(fs ...Filter) {
|
||||||
(*netmap.PlacementPolicy)(p).
|
(*netmap.PlacementPolicy)(p).
|
||||||
SetFilters(filtersToV2(fs))
|
SetFilters(filtersToV2(fs))
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,21 +10,21 @@ import (
|
||||||
func TestPlacementPolicyFromV2(t *testing.T) {
|
func TestPlacementPolicyFromV2(t *testing.T) {
|
||||||
pV2 := new(netmap.PlacementPolicy)
|
pV2 := new(netmap.PlacementPolicy)
|
||||||
|
|
||||||
pV2.SetReplicas([]*netmap.Replica{
|
pV2.SetReplicas([]netmap.Replica{
|
||||||
testReplica().ToV2(),
|
*testReplica().ToV2(),
|
||||||
testReplica().ToV2(),
|
*testReplica().ToV2(),
|
||||||
})
|
})
|
||||||
|
|
||||||
pV2.SetContainerBackupFactor(3)
|
pV2.SetContainerBackupFactor(3)
|
||||||
|
|
||||||
pV2.SetSelectors([]*netmap.Selector{
|
pV2.SetSelectors([]netmap.Selector{
|
||||||
testSelector().ToV2(),
|
*testSelector().ToV2(),
|
||||||
testSelector().ToV2(),
|
*testSelector().ToV2(),
|
||||||
})
|
})
|
||||||
|
|
||||||
pV2.SetFilters([]*netmap.Filter{
|
pV2.SetFilters([]netmap.Filter{
|
||||||
testFilter().ToV2(),
|
*testFilter().ToV2(),
|
||||||
testFilter().ToV2(),
|
*testFilter().ToV2(),
|
||||||
})
|
})
|
||||||
|
|
||||||
p := NewPlacementPolicyFromV2(pV2)
|
p := NewPlacementPolicyFromV2(pV2)
|
||||||
|
@ -34,7 +34,7 @@ func TestPlacementPolicyFromV2(t *testing.T) {
|
||||||
|
|
||||||
func TestPlacementPolicy_Replicas(t *testing.T) {
|
func TestPlacementPolicy_Replicas(t *testing.T) {
|
||||||
p := NewPlacementPolicy()
|
p := NewPlacementPolicy()
|
||||||
rs := []*Replica{testReplica(), testReplica()}
|
rs := []Replica{*testReplica(), *testReplica()}
|
||||||
|
|
||||||
p.SetReplicas(rs...)
|
p.SetReplicas(rs...)
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ func TestPlacementPolicy_ContainerBackupFactor(t *testing.T) {
|
||||||
|
|
||||||
func TestPlacementPolicy_Selectors(t *testing.T) {
|
func TestPlacementPolicy_Selectors(t *testing.T) {
|
||||||
p := NewPlacementPolicy()
|
p := NewPlacementPolicy()
|
||||||
ss := []*Selector{testSelector(), testSelector()}
|
ss := []Selector{*testSelector(), *testSelector()}
|
||||||
|
|
||||||
p.SetSelectors(ss...)
|
p.SetSelectors(ss...)
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ func TestPlacementPolicy_Selectors(t *testing.T) {
|
||||||
|
|
||||||
func TestPlacementPolicy_Filters(t *testing.T) {
|
func TestPlacementPolicy_Filters(t *testing.T) {
|
||||||
p := NewPlacementPolicy()
|
p := NewPlacementPolicy()
|
||||||
fs := []*Filter{testFilter(), testFilter()}
|
fs := []Filter{*testFilter(), *testFilter()}
|
||||||
|
|
||||||
p.SetFilters(fs...)
|
p.SetFilters(fs...)
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ func TestReplicaEncoding(t *testing.T) {
|
||||||
data, err := r.Marshal()
|
data, err := r.Marshal()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
r2 := NewReplica()
|
r2 := *NewReplica()
|
||||||
require.NoError(t, r2.Unmarshal(data))
|
require.NoError(t, r2.Unmarshal(data))
|
||||||
|
|
||||||
require.Equal(t, r, r2)
|
require.Equal(t, r, r2)
|
||||||
|
@ -67,7 +67,7 @@ func TestReplicaEncoding(t *testing.T) {
|
||||||
data, err := r.MarshalJSON()
|
data, err := r.MarshalJSON()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
r2 := NewReplica()
|
r2 := *NewReplica()
|
||||||
require.NoError(t, r2.UnmarshalJSON(data))
|
require.NoError(t, r2.UnmarshalJSON(data))
|
||||||
|
|
||||||
require.Equal(t, r, r2)
|
require.Equal(t, r, r2)
|
||||||
|
|
|
@ -14,19 +14,18 @@ type Selector netmap.Selector
|
||||||
|
|
||||||
// processSelectors processes selectors and returns error is any of them is invalid.
|
// processSelectors processes selectors and returns error is any of them is invalid.
|
||||||
func (c *Context) processSelectors(p *PlacementPolicy) error {
|
func (c *Context) processSelectors(p *PlacementPolicy) error {
|
||||||
for _, s := range p.Selectors() {
|
selectors := p.Selectors()
|
||||||
if s == nil {
|
for i, s := range selectors {
|
||||||
return fmt.Errorf("%w: SELECT", ErrMissingField)
|
if s.Filter() != MainFilterName {
|
||||||
} else if s.Filter() != MainFilterName {
|
|
||||||
_, ok := c.Filters[s.Filter()]
|
_, ok := c.Filters[s.Filter()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("%w: SELECT FROM '%s'", ErrFilterNotFound, s.Filter())
|
return fmt.Errorf("%w: SELECT FROM '%s'", ErrFilterNotFound, s.Filter())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Selectors[s.Name()] = s
|
c.Selectors[s.Name()] = &selectors[i]
|
||||||
|
|
||||||
result, err := c.getSelection(p, s)
|
result, err := c.getSelection(p, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -141,7 +140,7 @@ func (c *Context) getSelectionBase(subnetID *subnetid.ID, s *Selector) []nodeAtt
|
||||||
if !BelongsToSubnet(c.Netmap.Nodes[i].NodeInfo, sid) {
|
if !BelongsToSubnet(c.Netmap.Nodes[i].NodeInfo, sid) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if isMain || c.match(f, c.Netmap.Nodes[i]) {
|
if isMain || c.match(f, &c.Netmap.Nodes[i]) {
|
||||||
if attr == "" {
|
if attr == "" {
|
||||||
// Default attribute is transparent identifier which is different for every node.
|
// Default attribute is transparent identifier which is different for every node.
|
||||||
result = append(result, nodeAttrPair{attr: "", nodes: Nodes{c.Netmap.Nodes[i]}})
|
result = append(result, nodeAttrPair{attr: "", nodes: Nodes{c.Netmap.Nodes[i]}})
|
||||||
|
|
|
@ -94,13 +94,13 @@ func BenchmarkPolicyHRWType(b *testing.B) {
|
||||||
const netmapSize = 100
|
const netmapSize = 100
|
||||||
|
|
||||||
p := newPlacementPolicy(1,
|
p := newPlacementPolicy(1,
|
||||||
[]*Replica{
|
[]Replica{
|
||||||
newReplica(1, "loc1"),
|
newReplica(1, "loc1"),
|
||||||
newReplica(1, "loc2")},
|
newReplica(1, "loc2")},
|
||||||
[]*Selector{
|
[]Selector{
|
||||||
newSelector("loc1", "Location", ClauseSame, 1, "loc1"),
|
newSelector("loc1", "Location", ClauseSame, 1, "loc1"),
|
||||||
newSelector("loc2", "Location", ClauseSame, 1, "loc2")},
|
newSelector("loc2", "Location", ClauseSame, 1, "loc2")},
|
||||||
[]*Filter{
|
[]Filter{
|
||||||
newFilter("loc1", "Location", "Shanghai", OpEQ),
|
newFilter("loc1", "Location", "Shanghai", OpEQ),
|
||||||
newFilter("loc2", "Location", "Shanghai", OpNE),
|
newFilter("loc2", "Location", "Shanghai", OpNE),
|
||||||
})
|
})
|
||||||
|
@ -139,13 +139,13 @@ func TestPlacementPolicy_DeterministicOrder(t *testing.T) {
|
||||||
const netmapSize = 100
|
const netmapSize = 100
|
||||||
|
|
||||||
p := newPlacementPolicy(1,
|
p := newPlacementPolicy(1,
|
||||||
[]*Replica{
|
[]Replica{
|
||||||
newReplica(1, "loc1"),
|
newReplica(1, "loc1"),
|
||||||
newReplica(1, "loc2")},
|
newReplica(1, "loc2")},
|
||||||
[]*Selector{
|
[]Selector{
|
||||||
newSelector("loc1", "Location", ClauseSame, 1, "loc1"),
|
newSelector("loc1", "Location", ClauseSame, 1, "loc1"),
|
||||||
newSelector("loc2", "Location", ClauseSame, 1, "loc2")},
|
newSelector("loc2", "Location", ClauseSame, 1, "loc2")},
|
||||||
[]*Filter{
|
[]Filter{
|
||||||
newFilter("loc1", "Location", "Shanghai", OpEQ),
|
newFilter("loc1", "Location", "Shanghai", OpEQ),
|
||||||
newFilter("loc2", "Location", "Shanghai", OpNE),
|
newFilter("loc2", "Location", "Shanghai", OpNE),
|
||||||
})
|
})
|
||||||
|
@ -188,13 +188,13 @@ func TestPlacementPolicy_DeterministicOrder(t *testing.T) {
|
||||||
|
|
||||||
func TestPlacementPolicy_ProcessSelectors(t *testing.T) {
|
func TestPlacementPolicy_ProcessSelectors(t *testing.T) {
|
||||||
p := newPlacementPolicy(2, nil,
|
p := newPlacementPolicy(2, nil,
|
||||||
[]*Selector{
|
[]Selector{
|
||||||
newSelector("SameRU", "City", ClauseSame, 2, "FromRU"),
|
newSelector("SameRU", "City", ClauseSame, 2, "FromRU"),
|
||||||
newSelector("DistinctRU", "City", ClauseDistinct, 2, "FromRU"),
|
newSelector("DistinctRU", "City", ClauseDistinct, 2, "FromRU"),
|
||||||
newSelector("Good", "Country", ClauseDistinct, 2, "Good"),
|
newSelector("Good", "Country", ClauseDistinct, 2, "Good"),
|
||||||
newSelector("Main", "Country", ClauseDistinct, 3, "*"),
|
newSelector("Main", "Country", ClauseDistinct, 3, "*"),
|
||||||
},
|
},
|
||||||
[]*Filter{
|
[]Filter{
|
||||||
newFilter("FromRU", "Country", "Russia", OpEQ),
|
newFilter("FromRU", "Country", "Russia", OpEQ),
|
||||||
newFilter("Good", "Rating", "4", OpGE),
|
newFilter("Good", "Rating", "4", OpGE),
|
||||||
})
|
})
|
||||||
|
@ -229,7 +229,7 @@ func TestPlacementPolicy_ProcessSelectors(t *testing.T) {
|
||||||
for _, res := range sel {
|
for _, res := range sel {
|
||||||
require.Equal(t, nodesInBucket, len(res), targ)
|
require.Equal(t, nodesInBucket, len(res), targ)
|
||||||
for j := range res {
|
for j := range res {
|
||||||
require.True(t, c.applyFilter(s.Filter(), res[j]), targ)
|
require.True(t, c.applyFilter(s.Filter(), &res[j]), targ)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ func TestSelectorEncoding(t *testing.T) {
|
||||||
data, err := s.Marshal()
|
data, err := s.Marshal()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
s2 := NewSelector()
|
s2 := *NewSelector()
|
||||||
require.NoError(t, s2.Unmarshal(data))
|
require.NoError(t, s2.Unmarshal(data))
|
||||||
|
|
||||||
require.Equal(t, s, s2)
|
require.Equal(t, s, s2)
|
||||||
|
@ -308,7 +308,7 @@ func TestSelectorEncoding(t *testing.T) {
|
||||||
data, err := s.MarshalJSON()
|
data, err := s.MarshalJSON()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
s2 := NewSelector()
|
s2 := *NewSelector()
|
||||||
require.NoError(t, s2.UnmarshalJSON(data))
|
require.NoError(t, s2.UnmarshalJSON(data))
|
||||||
|
|
||||||
require.Equal(t, s, s2)
|
require.Equal(t, s, s2)
|
||||||
|
|
|
@ -11,7 +11,7 @@ func filter(withInner bool) *netmap.Filter {
|
||||||
x.SetOperation(netmap.OpAND)
|
x.SetOperation(netmap.OpAND)
|
||||||
|
|
||||||
if withInner {
|
if withInner {
|
||||||
x.SetInnerFilters(filter(false), filter(false))
|
x.SetInnerFilters(*filter(false), *filter(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
return x
|
return x
|
||||||
|
@ -50,9 +50,9 @@ func PlacementPolicy() *netmap.PlacementPolicy {
|
||||||
x := netmap.NewPlacementPolicy()
|
x := netmap.NewPlacementPolicy()
|
||||||
|
|
||||||
x.SetContainerBackupFactor(9)
|
x.SetContainerBackupFactor(9)
|
||||||
x.SetFilters(Filter(), Filter())
|
x.SetFilters(*Filter(), *Filter())
|
||||||
x.SetReplicas(Replica(), Replica())
|
x.SetReplicas(*Replica(), *Replica())
|
||||||
x.SetSelectors(Selector(), Selector())
|
x.SetSelectors(*Selector(), *Selector())
|
||||||
|
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
@ -72,8 +72,8 @@ func NetworkConfig() *netmap.NetworkConfig {
|
||||||
x := netmap.NewNetworkConfig()
|
x := netmap.NewNetworkConfig()
|
||||||
|
|
||||||
x.SetParameters(
|
x.SetParameters(
|
||||||
NetworkParameter(),
|
*NetworkParameter(),
|
||||||
NetworkParameter(),
|
*NetworkParameter(),
|
||||||
)
|
)
|
||||||
|
|
||||||
return x
|
return x
|
||||||
|
|
Loading…
Reference in a new issue