[#78] netmap: Add new keywords NOT and UNIQUE

* Add the rule for NOT operation to the policy parser grammar
* Regenerate query parse
* Implement NOT in filter
* Add unit-tests

Signed-off-by: Airat Arifullin a.arifullin@yadro.com
This commit is contained in:
Airat Arifullin 2023-05-24 12:50:13 +03:00
parent ec59ebfd88
commit 4f48f6c9e0
17 changed files with 468 additions and 376 deletions

View file

@ -244,6 +244,57 @@ func TestPlacementPolicy_ProcessSelectors(t *testing.T) {
}
}
func TestPlacementPolicy_ProcessSelectorsExceptForNodes(t *testing.T) {
p := newPlacementPolicy(1, nil,
[]Selector{
newSelector("ExceptRU", "City", 2, "ExceptRU", (*Selector).SelectSame),
},
[]Filter{
newFilter("ExceptRU", "", "", netmap.NOT,
newFilter("", "", "", netmap.AND,
newFilter("", "City", "Lyon", netmap.EQ),
newFilter("", "Rating", "10", netmap.LE),
),
),
})
nodes := []NodeInfo{
nodeInfoFromAttributes("Country", "Germany", "Rating", "1", "City", "Berlin"),
nodeInfoFromAttributes("Country", "Germany", "Rating", "5", "City", "Berlin"),
nodeInfoFromAttributes("Country", "Russia", "Rating", "6", "City", "Moscow"),
nodeInfoFromAttributes("Country", "France", "Rating", "4", "City", "Paris"),
nodeInfoFromAttributes("Country", "France", "Rating", "1", "City", "Lyon"),
nodeInfoFromAttributes("Country", "France", "Rating", "5", "City", "Lyon"),
nodeInfoFromAttributes("Country", "Russia", "Rating", "7", "City", "Moscow"),
nodeInfoFromAttributes("Country", "Germany", "Rating", "3", "City", "Darmstadt"),
nodeInfoFromAttributes("Country", "Germany", "Rating", "7", "City", "Frankfurt"),
nodeInfoFromAttributes("Country", "Russia", "Rating", "9", "City", "SPB"),
nodeInfoFromAttributes("Country", "Russia", "Rating", "9", "City", "SPB"),
}
var nm NetMap
nm.SetNodes(nodes)
c := newContext(nm)
c.setCBF(p.backupFactor)
require.NoError(t, c.processFilters(p))
require.NoError(t, c.processSelectors(p))
for _, s := range p.selectors {
sel := c.selections[s.GetName()]
s := c.processedSelectors[s.GetName()]
bucketCount, nodesInBucket := calcNodesCount(*s)
nodesInBucket *= int(c.cbf)
targ := fmt.Sprintf("selector '%s'", s.GetName())
require.Equal(t, bucketCount, len(sel), targ)
fName := s.GetFilter()
for _, res := range sel {
require.Equal(t, nodesInBucket, len(res), targ)
for j := range res {
require.True(t, fName == mainFilterName || c.match(c.processedFilters[fName], res[j]), targ)
}
}
}
}
func TestSelector_SetName(t *testing.T) {
const name = "some name"
var s Selector