diff --git a/netmap/netmap.go b/netmap/netmap.go index 7da41a86..e1a5f7d1 100644 --- a/netmap/netmap.go +++ b/netmap/netmap.go @@ -188,30 +188,16 @@ func (m NetMap) ContainerNodes(p PlacementPolicy, pivot []byte) ([][]NodeInfo, e for i := range p.replicas { sName := p.replicas[i].GetSelector() if sName == "" { - if len(p.selectors) == 0 { - var s netmap.Selector - s.SetCount(p.replicas[i].GetCount()) - s.SetFilter(mainFilterName) + var s netmap.Selector + s.SetCount(p.replicas[i].GetCount()) + s.SetFilter(mainFilterName) - nodes, err := c.getSelection(s) - if err != nil { - return nil, err - } - - result[i] = flattenNodes(nodes) + nodes, err := c.getSelection(s) + if err != nil { + return nil, err } - for i := range p.selectors { - if p.unique { - nodes, err := c.getSelection(p.selectors[i]) - if err != nil { - return nil, err - } - result[i] = append(result[i], flattenNodes(nodes)...) - } else { - result[i] = append(result[i], flattenNodes(c.selections[p.selectors[i].GetName()])...) - } - } + result[i] = append(result[i], flattenNodes(nodes)...) if p.unique { c.addUsedNodes(result[i]...) diff --git a/netmap/selector_test.go b/netmap/selector_test.go index a80d9223..ccb5eb2c 100644 --- a/netmap/selector_test.go +++ b/netmap/selector_test.go @@ -282,6 +282,73 @@ func TestPlacementPolicy_Unique(t *testing.T) { } } +func TestPlacementPolicy_MultiREP(t *testing.T) { + nodes := []NodeInfo{ + nodeInfoFromAttributes("ID", "1", "Country", "Russia", "City", "SPB"), + nodeInfoFromAttributes("ID", "2", "Country", "Germany", "City", "Berlin"), + nodeInfoFromAttributes("ID", "3", "Country", "Russia", "City", "Moscow"), + nodeInfoFromAttributes("ID", "4", "Country", "France", "City", "Paris"), + nodeInfoFromAttributes("ID", "5", "Country", "France", "City", "Lyon"), + nodeInfoFromAttributes("ID", "6", "Country", "Russia", "City", "SPB"), + nodeInfoFromAttributes("ID", "7", "Country", "Russia", "City", "Moscow"), + nodeInfoFromAttributes("ID", "8", "Country", "Germany", "City", "Darmstadt"), + nodeInfoFromAttributes("ID", "9", "Country", "Germany", "City", "Frankfurt"), + nodeInfoFromAttributes("ID", "10", "Country", "Russia", "City", "SPB"), + nodeInfoFromAttributes("ID", "11", "Country", "Russia", "City", "Moscow"), + nodeInfoFromAttributes("ID", "12", "Country", "Germany", "City", "London"), + } + for i := range nodes { + pub := make([]byte, 33) + rand.Read(pub) + nodes[i].SetPublicKey(pub) + } + + var nm NetMap + nm.SetNodes(nodes) + + ss := []Selector{newSelector("SameRU", "City", 2, "FromRU", (*Selector).SelectDistinct)} + fs := []Filter{newFilter("FromRU", "Country", "Russia", netmap.EQ)} + + for _, unique := range []bool{false, true} { + for _, additional := range []int{0, 1, 2} { + t.Run(fmt.Sprintf("unique=%t, additional=%d", unique, additional), func(t *testing.T) { + rs := []ReplicaDescriptor{newReplica(1, "SameRU")} + for i := 0; i < additional; i++ { + rs = append(rs, newReplica(1, "")) + } + + p := newPlacementPolicy(3, rs, ss, fs) + p.unique = unique + + v, err := nm.ContainerNodes(p, []byte{1}) + require.NoError(t, err) + require.Equal(t, 1+additional, len(v)) + require.Equal(t, 6, len(v[0])) + + for i := 1; i < additional; i++ { + require.Equal(t, 3, len(v[i])) + if !unique { + require.Equal(t, v[1], v[i]) + } + } + + if unique { + seen := make(map[string]bool) + for i := range v { + for j := range v[i] { + attr := v[i][j].Attribute("ID") + require.NotEmpty(t, attr) + require.False(t, seen[attr]) + + seen[attr] = true + } + } + } + }) + } + } +} + func TestPlacementPolicy_ProcessSelectorsExceptForNodes(t *testing.T) { p := newPlacementPolicy(1, nil, []Selector{