From 2077b357363a0225f448663e4937ae1f242d7113 Mon Sep 17 00:00:00 2001 From: Anton Nikiforov Date: Mon, 24 Jun 2024 14:45:59 +0300 Subject: [PATCH] [#231] netmap: Add `LIKE` operation for `filter` Signed-off-by: Anton Nikiforov --- doc/policy.md | 7 ++ netmap/filter.go | 18 +++- netmap/parser/QueryLexer.g4 | 2 +- netmap/parser/QueryLexer.interp | Bin 7764 -> 7900 bytes netmap/parser/query_lexer.go | 184 ++++++++++++++++---------------- netmap/policy.go | 7 ++ netmap/policy_test.go | 5 + netmap/selector_test.go | 87 +++++++++++++++ netmap/yml_unmarshal.go | 19 ++-- 9 files changed, 227 insertions(+), 102 deletions(-) diff --git a/doc/policy.md b/doc/policy.md index 28744ef..0b87079 100644 --- a/doc/policy.md +++ b/doc/policy.md @@ -428,6 +428,13 @@ Comparison operators (all binary): - `LE`: less or equal - `LT`: less than +Pattern operator: +- `LIKE`: specifies pattern for an attribute. Uses as a wildcard symbol `*`. + - `... ATTR LIKE "VAL"` - the behaviour is equal to `EQ` + - `... ATTR LIKE "VAL*"` - matches all which starts with `VAL` + - `... ATTR LIKE "*VAL"` - matches all which ends with `VAL` + - `... ATTR LIKE "*VAL*"` - matches all which contains `VAL` + Logical operators: - `NOT`: negation (unary) - `AND`: conjunction (binary) diff --git a/netmap/filter.go b/netmap/filter.go index 71e101d..76d8545 100644 --- a/netmap/filter.go +++ b/netmap/filter.go @@ -3,6 +3,7 @@ package netmap import ( "fmt" "strconv" + "strings" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap" ) @@ -11,6 +12,8 @@ import ( // which points to the whole netmap. const mainFilterName = "*" +const likeWildcard = "*" + // processFilters processes filters and returns error is any of them is invalid. func (c *context) processFilters(p PlacementPolicy) error { for i := range p.filters { @@ -53,7 +56,7 @@ func (c *context) processFilter(f netmap.Filter, top bool) error { } switch op { - case netmap.EQ, netmap.NE: + case netmap.EQ, netmap.NE, netmap.LIKE: case netmap.GT, netmap.GE, netmap.LT, netmap.LE: val := f.GetValue() n, err := strconv.ParseUint(val, 10, 64) @@ -110,6 +113,19 @@ func (c *context) matchKeyValue(f *netmap.Filter, b NodeInfo) bool { switch op := f.GetOp(); op { case netmap.EQ: return b.Attribute(f.GetKey()) == f.GetValue() + case netmap.LIKE: + str, prefix := strings.CutPrefix(f.GetValue(), likeWildcard) + str, suffix := strings.CutSuffix(str, likeWildcard) + if prefix && suffix { + return strings.Contains(b.Attribute(f.GetKey()), str) + } + if prefix && !suffix { + return strings.HasSuffix(b.Attribute(f.GetKey()), str) + } + if !prefix && suffix { + return strings.HasPrefix(b.Attribute(f.GetKey()), str) + } + return b.Attribute(f.GetKey()) == f.GetValue() case netmap.NE: return b.Attribute(f.GetKey()) != f.GetValue() default: diff --git a/netmap/parser/QueryLexer.g4 b/netmap/parser/QueryLexer.g4 index 3e4e924..200fbb6 100644 --- a/netmap/parser/QueryLexer.g4 +++ b/netmap/parser/QueryLexer.g4 @@ -3,7 +3,7 @@ lexer grammar QueryLexer; NOT_OP : 'NOT'; AND_OP : 'AND'; OR_OP : 'OR'; -SIMPLE_OP : 'EQ' | 'NE' | 'GE' | 'GT' | 'LT' | 'LE'; +SIMPLE_OP : 'EQ' | 'NE' | 'GE' | 'GT' | 'LT' | 'LE' | 'LIKE' ; UNIQUE : 'UNIQUE'; REP : 'REP'; diff --git a/netmap/parser/QueryLexer.interp b/netmap/parser/QueryLexer.interp index c4d6296169c9c6597d93f91b4434f5f53d4bc303..c339bddff80ae73c2b316700003ce678c8773c9c 100644 GIT binary patch literal 7900 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 Jc8take*r@@g|q+w literal 7764 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 Z4%s#4H->`lN5YQ*ez4;b?HG+8{svh1Zi@f_ diff --git a/netmap/parser/query_lexer.go b/netmap/parser/query_lexer.go index 85a0336..43fc173 100644 --- a/netmap/parser/query_lexer.go +++ b/netmap/parser/query_lexer.go @@ -62,7 +62,7 @@ func querylexerLexerInit() { } staticData.PredictionContextCache = antlr.NewPredictionContextCache() staticData.serializedATN = []int32{ - 4, 0, 25, 222, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, + 4, 0, 25, 226, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, @@ -70,96 +70,98 @@ func querylexerLexerInit() { 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, - 1, 3, 3, 3, 89, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, - 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, - 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, - 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, - 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, - 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, - 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 5, 20, 161, 8, 20, 10, - 20, 12, 20, 164, 9, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 5, 23, - 172, 8, 23, 10, 23, 12, 23, 175, 9, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, - 25, 5, 25, 182, 8, 25, 10, 25, 12, 25, 185, 9, 25, 1, 25, 1, 25, 1, 25, - 1, 25, 5, 25, 191, 8, 25, 10, 25, 12, 25, 194, 9, 25, 1, 25, 3, 25, 197, - 8, 25, 1, 26, 1, 26, 1, 26, 3, 26, 202, 8, 26, 1, 27, 1, 27, 1, 27, 1, - 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 4, 31, - 217, 8, 31, 11, 31, 12, 31, 218, 1, 31, 1, 31, 0, 0, 32, 1, 1, 3, 2, 5, - 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, - 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, - 0, 45, 0, 47, 22, 49, 23, 51, 24, 53, 0, 55, 0, 57, 0, 59, 0, 61, 0, 63, - 25, 1, 0, 8, 1, 0, 48, 57, 3, 0, 65, 90, 95, 95, 97, 122, 1, 0, 49, 57, - 9, 0, 34, 34, 39, 39, 47, 47, 92, 92, 98, 98, 102, 102, 110, 110, 114, - 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 3, 0, 0, 31, 39, 39, 92, - 92, 3, 0, 0, 31, 34, 34, 92, 92, 3, 0, 9, 10, 13, 13, 32, 32, 229, 0, 1, - 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, - 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, - 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, - 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, - 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, - 0, 0, 0, 41, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, - 0, 0, 0, 0, 63, 1, 0, 0, 0, 1, 65, 1, 0, 0, 0, 3, 69, 1, 0, 0, 0, 5, 73, - 1, 0, 0, 0, 7, 88, 1, 0, 0, 0, 9, 90, 1, 0, 0, 0, 11, 97, 1, 0, 0, 0, 13, - 101, 1, 0, 0, 0, 15, 104, 1, 0, 0, 0, 17, 107, 1, 0, 0, 0, 19, 110, 1, - 0, 0, 0, 21, 114, 1, 0, 0, 0, 23, 121, 1, 0, 0, 0, 25, 126, 1, 0, 0, 0, - 27, 133, 1, 0, 0, 0, 29, 135, 1, 0, 0, 0, 31, 137, 1, 0, 0, 0, 33, 142, - 1, 0, 0, 0, 35, 151, 1, 0, 0, 0, 37, 153, 1, 0, 0, 0, 39, 155, 1, 0, 0, - 0, 41, 157, 1, 0, 0, 0, 43, 165, 1, 0, 0, 0, 45, 167, 1, 0, 0, 0, 47, 169, - 1, 0, 0, 0, 49, 176, 1, 0, 0, 0, 51, 196, 1, 0, 0, 0, 53, 198, 1, 0, 0, - 0, 55, 203, 1, 0, 0, 0, 57, 209, 1, 0, 0, 0, 59, 211, 1, 0, 0, 0, 61, 213, - 1, 0, 0, 0, 63, 216, 1, 0, 0, 0, 65, 66, 5, 78, 0, 0, 66, 67, 5, 79, 0, - 0, 67, 68, 5, 84, 0, 0, 68, 2, 1, 0, 0, 0, 69, 70, 5, 65, 0, 0, 70, 71, - 5, 78, 0, 0, 71, 72, 5, 68, 0, 0, 72, 4, 1, 0, 0, 0, 73, 74, 5, 79, 0, - 0, 74, 75, 5, 82, 0, 0, 75, 6, 1, 0, 0, 0, 76, 77, 5, 69, 0, 0, 77, 89, - 5, 81, 0, 0, 78, 79, 5, 78, 0, 0, 79, 89, 5, 69, 0, 0, 80, 81, 5, 71, 0, - 0, 81, 89, 5, 69, 0, 0, 82, 83, 5, 71, 0, 0, 83, 89, 5, 84, 0, 0, 84, 85, - 5, 76, 0, 0, 85, 89, 5, 84, 0, 0, 86, 87, 5, 76, 0, 0, 87, 89, 5, 69, 0, - 0, 88, 76, 1, 0, 0, 0, 88, 78, 1, 0, 0, 0, 88, 80, 1, 0, 0, 0, 88, 82, - 1, 0, 0, 0, 88, 84, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 89, 8, 1, 0, 0, 0, - 90, 91, 5, 85, 0, 0, 91, 92, 5, 78, 0, 0, 92, 93, 5, 73, 0, 0, 93, 94, - 5, 81, 0, 0, 94, 95, 5, 85, 0, 0, 95, 96, 5, 69, 0, 0, 96, 10, 1, 0, 0, - 0, 97, 98, 5, 82, 0, 0, 98, 99, 5, 69, 0, 0, 99, 100, 5, 80, 0, 0, 100, - 12, 1, 0, 0, 0, 101, 102, 5, 69, 0, 0, 102, 103, 5, 67, 0, 0, 103, 14, - 1, 0, 0, 0, 104, 105, 5, 73, 0, 0, 105, 106, 5, 78, 0, 0, 106, 16, 1, 0, - 0, 0, 107, 108, 5, 65, 0, 0, 108, 109, 5, 83, 0, 0, 109, 18, 1, 0, 0, 0, - 110, 111, 5, 67, 0, 0, 111, 112, 5, 66, 0, 0, 112, 113, 5, 70, 0, 0, 113, - 20, 1, 0, 0, 0, 114, 115, 5, 83, 0, 0, 115, 116, 5, 69, 0, 0, 116, 117, - 5, 76, 0, 0, 117, 118, 5, 69, 0, 0, 118, 119, 5, 67, 0, 0, 119, 120, 5, - 84, 0, 0, 120, 22, 1, 0, 0, 0, 121, 122, 5, 70, 0, 0, 122, 123, 5, 82, - 0, 0, 123, 124, 5, 79, 0, 0, 124, 125, 5, 77, 0, 0, 125, 24, 1, 0, 0, 0, - 126, 127, 5, 70, 0, 0, 127, 128, 5, 73, 0, 0, 128, 129, 5, 76, 0, 0, 129, - 130, 5, 84, 0, 0, 130, 131, 5, 69, 0, 0, 131, 132, 5, 82, 0, 0, 132, 26, - 1, 0, 0, 0, 133, 134, 5, 42, 0, 0, 134, 28, 1, 0, 0, 0, 135, 136, 5, 46, - 0, 0, 136, 30, 1, 0, 0, 0, 137, 138, 5, 83, 0, 0, 138, 139, 5, 65, 0, 0, - 139, 140, 5, 77, 0, 0, 140, 141, 5, 69, 0, 0, 141, 32, 1, 0, 0, 0, 142, - 143, 5, 68, 0, 0, 143, 144, 5, 73, 0, 0, 144, 145, 5, 83, 0, 0, 145, 146, - 5, 84, 0, 0, 146, 147, 5, 73, 0, 0, 147, 148, 5, 78, 0, 0, 148, 149, 5, - 67, 0, 0, 149, 150, 5, 84, 0, 0, 150, 34, 1, 0, 0, 0, 151, 152, 5, 40, - 0, 0, 152, 36, 1, 0, 0, 0, 153, 154, 5, 41, 0, 0, 154, 38, 1, 0, 0, 0, - 155, 156, 5, 64, 0, 0, 156, 40, 1, 0, 0, 0, 157, 162, 3, 45, 22, 0, 158, - 161, 3, 43, 21, 0, 159, 161, 3, 45, 22, 0, 160, 158, 1, 0, 0, 0, 160, 159, - 1, 0, 0, 0, 161, 164, 1, 0, 0, 0, 162, 160, 1, 0, 0, 0, 162, 163, 1, 0, - 0, 0, 163, 42, 1, 0, 0, 0, 164, 162, 1, 0, 0, 0, 165, 166, 7, 0, 0, 0, - 166, 44, 1, 0, 0, 0, 167, 168, 7, 1, 0, 0, 168, 46, 1, 0, 0, 0, 169, 173, - 7, 2, 0, 0, 170, 172, 3, 43, 21, 0, 171, 170, 1, 0, 0, 0, 172, 175, 1, - 0, 0, 0, 173, 171, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 48, 1, 0, 0, - 0, 175, 173, 1, 0, 0, 0, 176, 177, 5, 48, 0, 0, 177, 50, 1, 0, 0, 0, 178, - 183, 5, 34, 0, 0, 179, 182, 3, 53, 26, 0, 180, 182, 3, 61, 30, 0, 181, - 179, 1, 0, 0, 0, 181, 180, 1, 0, 0, 0, 182, 185, 1, 0, 0, 0, 183, 181, - 1, 0, 0, 0, 183, 184, 1, 0, 0, 0, 184, 186, 1, 0, 0, 0, 185, 183, 1, 0, - 0, 0, 186, 197, 5, 34, 0, 0, 187, 192, 5, 39, 0, 0, 188, 191, 3, 53, 26, - 0, 189, 191, 3, 59, 29, 0, 190, 188, 1, 0, 0, 0, 190, 189, 1, 0, 0, 0, - 191, 194, 1, 0, 0, 0, 192, 190, 1, 0, 0, 0, 192, 193, 1, 0, 0, 0, 193, - 195, 1, 0, 0, 0, 194, 192, 1, 0, 0, 0, 195, 197, 5, 39, 0, 0, 196, 178, - 1, 0, 0, 0, 196, 187, 1, 0, 0, 0, 197, 52, 1, 0, 0, 0, 198, 201, 5, 92, - 0, 0, 199, 202, 7, 3, 0, 0, 200, 202, 3, 55, 27, 0, 201, 199, 1, 0, 0, - 0, 201, 200, 1, 0, 0, 0, 202, 54, 1, 0, 0, 0, 203, 204, 5, 117, 0, 0, 204, - 205, 3, 57, 28, 0, 205, 206, 3, 57, 28, 0, 206, 207, 3, 57, 28, 0, 207, - 208, 3, 57, 28, 0, 208, 56, 1, 0, 0, 0, 209, 210, 7, 4, 0, 0, 210, 58, - 1, 0, 0, 0, 211, 212, 8, 5, 0, 0, 212, 60, 1, 0, 0, 0, 213, 214, 8, 6, - 0, 0, 214, 62, 1, 0, 0, 0, 215, 217, 7, 7, 0, 0, 216, 215, 1, 0, 0, 0, - 217, 218, 1, 0, 0, 0, 218, 216, 1, 0, 0, 0, 218, 219, 1, 0, 0, 0, 219, - 220, 1, 0, 0, 0, 220, 221, 6, 31, 0, 0, 221, 64, 1, 0, 0, 0, 12, 0, 88, - 160, 162, 173, 181, 183, 190, 192, 196, 201, 218, 1, 6, 0, 0, + 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 93, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, + 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, + 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, + 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, + 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, + 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, + 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, + 5, 20, 165, 8, 20, 10, 20, 12, 20, 168, 9, 20, 1, 21, 1, 21, 1, 22, 1, + 22, 1, 23, 1, 23, 5, 23, 176, 8, 23, 10, 23, 12, 23, 179, 9, 23, 1, 24, + 1, 24, 1, 25, 1, 25, 1, 25, 5, 25, 186, 8, 25, 10, 25, 12, 25, 189, 9, + 25, 1, 25, 1, 25, 1, 25, 1, 25, 5, 25, 195, 8, 25, 10, 25, 12, 25, 198, + 9, 25, 1, 25, 3, 25, 201, 8, 25, 1, 26, 1, 26, 1, 26, 3, 26, 206, 8, 26, + 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, + 30, 1, 30, 1, 31, 4, 31, 221, 8, 31, 11, 31, 12, 31, 222, 1, 31, 1, 31, + 0, 0, 32, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, + 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, + 19, 39, 20, 41, 21, 43, 0, 45, 0, 47, 22, 49, 23, 51, 24, 53, 0, 55, 0, + 57, 0, 59, 0, 61, 0, 63, 25, 1, 0, 8, 1, 0, 48, 57, 3, 0, 65, 90, 95, 95, + 97, 122, 1, 0, 49, 57, 9, 0, 34, 34, 39, 39, 47, 47, 92, 92, 98, 98, 102, + 102, 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 3, 0, + 0, 31, 39, 39, 92, 92, 3, 0, 0, 31, 34, 34, 92, 92, 3, 0, 9, 10, 13, 13, + 32, 32, 234, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, + 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, + 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, + 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, + 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, + 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, + 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 1, 65, 1, 0, 0, 0, 3, 69, + 1, 0, 0, 0, 5, 73, 1, 0, 0, 0, 7, 92, 1, 0, 0, 0, 9, 94, 1, 0, 0, 0, 11, + 101, 1, 0, 0, 0, 13, 105, 1, 0, 0, 0, 15, 108, 1, 0, 0, 0, 17, 111, 1, + 0, 0, 0, 19, 114, 1, 0, 0, 0, 21, 118, 1, 0, 0, 0, 23, 125, 1, 0, 0, 0, + 25, 130, 1, 0, 0, 0, 27, 137, 1, 0, 0, 0, 29, 139, 1, 0, 0, 0, 31, 141, + 1, 0, 0, 0, 33, 146, 1, 0, 0, 0, 35, 155, 1, 0, 0, 0, 37, 157, 1, 0, 0, + 0, 39, 159, 1, 0, 0, 0, 41, 161, 1, 0, 0, 0, 43, 169, 1, 0, 0, 0, 45, 171, + 1, 0, 0, 0, 47, 173, 1, 0, 0, 0, 49, 180, 1, 0, 0, 0, 51, 200, 1, 0, 0, + 0, 53, 202, 1, 0, 0, 0, 55, 207, 1, 0, 0, 0, 57, 213, 1, 0, 0, 0, 59, 215, + 1, 0, 0, 0, 61, 217, 1, 0, 0, 0, 63, 220, 1, 0, 0, 0, 65, 66, 5, 78, 0, + 0, 66, 67, 5, 79, 0, 0, 67, 68, 5, 84, 0, 0, 68, 2, 1, 0, 0, 0, 69, 70, + 5, 65, 0, 0, 70, 71, 5, 78, 0, 0, 71, 72, 5, 68, 0, 0, 72, 4, 1, 0, 0, + 0, 73, 74, 5, 79, 0, 0, 74, 75, 5, 82, 0, 0, 75, 6, 1, 0, 0, 0, 76, 77, + 5, 69, 0, 0, 77, 93, 5, 81, 0, 0, 78, 79, 5, 78, 0, 0, 79, 93, 5, 69, 0, + 0, 80, 81, 5, 71, 0, 0, 81, 93, 5, 69, 0, 0, 82, 83, 5, 71, 0, 0, 83, 93, + 5, 84, 0, 0, 84, 85, 5, 76, 0, 0, 85, 93, 5, 84, 0, 0, 86, 87, 5, 76, 0, + 0, 87, 93, 5, 69, 0, 0, 88, 89, 5, 76, 0, 0, 89, 90, 5, 73, 0, 0, 90, 91, + 5, 75, 0, 0, 91, 93, 5, 69, 0, 0, 92, 76, 1, 0, 0, 0, 92, 78, 1, 0, 0, + 0, 92, 80, 1, 0, 0, 0, 92, 82, 1, 0, 0, 0, 92, 84, 1, 0, 0, 0, 92, 86, + 1, 0, 0, 0, 92, 88, 1, 0, 0, 0, 93, 8, 1, 0, 0, 0, 94, 95, 5, 85, 0, 0, + 95, 96, 5, 78, 0, 0, 96, 97, 5, 73, 0, 0, 97, 98, 5, 81, 0, 0, 98, 99, + 5, 85, 0, 0, 99, 100, 5, 69, 0, 0, 100, 10, 1, 0, 0, 0, 101, 102, 5, 82, + 0, 0, 102, 103, 5, 69, 0, 0, 103, 104, 5, 80, 0, 0, 104, 12, 1, 0, 0, 0, + 105, 106, 5, 69, 0, 0, 106, 107, 5, 67, 0, 0, 107, 14, 1, 0, 0, 0, 108, + 109, 5, 73, 0, 0, 109, 110, 5, 78, 0, 0, 110, 16, 1, 0, 0, 0, 111, 112, + 5, 65, 0, 0, 112, 113, 5, 83, 0, 0, 113, 18, 1, 0, 0, 0, 114, 115, 5, 67, + 0, 0, 115, 116, 5, 66, 0, 0, 116, 117, 5, 70, 0, 0, 117, 20, 1, 0, 0, 0, + 118, 119, 5, 83, 0, 0, 119, 120, 5, 69, 0, 0, 120, 121, 5, 76, 0, 0, 121, + 122, 5, 69, 0, 0, 122, 123, 5, 67, 0, 0, 123, 124, 5, 84, 0, 0, 124, 22, + 1, 0, 0, 0, 125, 126, 5, 70, 0, 0, 126, 127, 5, 82, 0, 0, 127, 128, 5, + 79, 0, 0, 128, 129, 5, 77, 0, 0, 129, 24, 1, 0, 0, 0, 130, 131, 5, 70, + 0, 0, 131, 132, 5, 73, 0, 0, 132, 133, 5, 76, 0, 0, 133, 134, 5, 84, 0, + 0, 134, 135, 5, 69, 0, 0, 135, 136, 5, 82, 0, 0, 136, 26, 1, 0, 0, 0, 137, + 138, 5, 42, 0, 0, 138, 28, 1, 0, 0, 0, 139, 140, 5, 46, 0, 0, 140, 30, + 1, 0, 0, 0, 141, 142, 5, 83, 0, 0, 142, 143, 5, 65, 0, 0, 143, 144, 5, + 77, 0, 0, 144, 145, 5, 69, 0, 0, 145, 32, 1, 0, 0, 0, 146, 147, 5, 68, + 0, 0, 147, 148, 5, 73, 0, 0, 148, 149, 5, 83, 0, 0, 149, 150, 5, 84, 0, + 0, 150, 151, 5, 73, 0, 0, 151, 152, 5, 78, 0, 0, 152, 153, 5, 67, 0, 0, + 153, 154, 5, 84, 0, 0, 154, 34, 1, 0, 0, 0, 155, 156, 5, 40, 0, 0, 156, + 36, 1, 0, 0, 0, 157, 158, 5, 41, 0, 0, 158, 38, 1, 0, 0, 0, 159, 160, 5, + 64, 0, 0, 160, 40, 1, 0, 0, 0, 161, 166, 3, 45, 22, 0, 162, 165, 3, 43, + 21, 0, 163, 165, 3, 45, 22, 0, 164, 162, 1, 0, 0, 0, 164, 163, 1, 0, 0, + 0, 165, 168, 1, 0, 0, 0, 166, 164, 1, 0, 0, 0, 166, 167, 1, 0, 0, 0, 167, + 42, 1, 0, 0, 0, 168, 166, 1, 0, 0, 0, 169, 170, 7, 0, 0, 0, 170, 44, 1, + 0, 0, 0, 171, 172, 7, 1, 0, 0, 172, 46, 1, 0, 0, 0, 173, 177, 7, 2, 0, + 0, 174, 176, 3, 43, 21, 0, 175, 174, 1, 0, 0, 0, 176, 179, 1, 0, 0, 0, + 177, 175, 1, 0, 0, 0, 177, 178, 1, 0, 0, 0, 178, 48, 1, 0, 0, 0, 179, 177, + 1, 0, 0, 0, 180, 181, 5, 48, 0, 0, 181, 50, 1, 0, 0, 0, 182, 187, 5, 34, + 0, 0, 183, 186, 3, 53, 26, 0, 184, 186, 3, 61, 30, 0, 185, 183, 1, 0, 0, + 0, 185, 184, 1, 0, 0, 0, 186, 189, 1, 0, 0, 0, 187, 185, 1, 0, 0, 0, 187, + 188, 1, 0, 0, 0, 188, 190, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 190, 201, + 5, 34, 0, 0, 191, 196, 5, 39, 0, 0, 192, 195, 3, 53, 26, 0, 193, 195, 3, + 59, 29, 0, 194, 192, 1, 0, 0, 0, 194, 193, 1, 0, 0, 0, 195, 198, 1, 0, + 0, 0, 196, 194, 1, 0, 0, 0, 196, 197, 1, 0, 0, 0, 197, 199, 1, 0, 0, 0, + 198, 196, 1, 0, 0, 0, 199, 201, 5, 39, 0, 0, 200, 182, 1, 0, 0, 0, 200, + 191, 1, 0, 0, 0, 201, 52, 1, 0, 0, 0, 202, 205, 5, 92, 0, 0, 203, 206, + 7, 3, 0, 0, 204, 206, 3, 55, 27, 0, 205, 203, 1, 0, 0, 0, 205, 204, 1, + 0, 0, 0, 206, 54, 1, 0, 0, 0, 207, 208, 5, 117, 0, 0, 208, 209, 3, 57, + 28, 0, 209, 210, 3, 57, 28, 0, 210, 211, 3, 57, 28, 0, 211, 212, 3, 57, + 28, 0, 212, 56, 1, 0, 0, 0, 213, 214, 7, 4, 0, 0, 214, 58, 1, 0, 0, 0, + 215, 216, 8, 5, 0, 0, 216, 60, 1, 0, 0, 0, 217, 218, 8, 6, 0, 0, 218, 62, + 1, 0, 0, 0, 219, 221, 7, 7, 0, 0, 220, 219, 1, 0, 0, 0, 221, 222, 1, 0, + 0, 0, 222, 220, 1, 0, 0, 0, 222, 223, 1, 0, 0, 0, 223, 224, 1, 0, 0, 0, + 224, 225, 6, 31, 0, 0, 225, 64, 1, 0, 0, 0, 12, 0, 92, 164, 166, 177, 185, + 187, 194, 196, 200, 205, 222, 1, 6, 0, 0, } deserializer := antlr.NewATNDeserializer(nil) staticData.atn = deserializer.Deserialize(staticData.serializedATN) diff --git a/netmap/policy.go b/netmap/policy.go index 545fb5c..48ca364 100644 --- a/netmap/policy.go +++ b/netmap/policy.go @@ -324,6 +324,13 @@ func (x *Filter) setAttribute(key string, op netmap.Operation, val string) { x.m.SetValue(val) } +// Like applies the rule to accept only nodes with attribute like value. +// +// Method SHOULD NOT be called along with other similar methods. +func (x *Filter) Like(key, value string) { + x.setAttribute(key, netmap.LIKE, value) +} + // Equal applies the rule to accept only nodes with the same attribute value. // // Method SHOULD NOT be called along with other similar methods. diff --git a/netmap/policy_test.go b/netmap/policy_test.go index 1d5487b..7c639c6 100644 --- a/netmap/policy_test.go +++ b/netmap/policy_test.go @@ -122,6 +122,11 @@ func TestDecodeSelectFilterExpr(t *testing.T) { FILTER Color EQ 'Red' AS RedNode FILTER @RedNode AND Shape EQ 'Cirle' AS RedCircleNode `, + ` + CBF 1 + SELECT 1 FROM R + FILTER Color LIKE 'R' AS R + `, } { _, err := DecodeSelectFilterString(s) require.NoError(t, err) diff --git a/netmap/selector_test.go b/netmap/selector_test.go index 0f0dd24..797ccfc 100644 --- a/netmap/selector_test.go +++ b/netmap/selector_test.go @@ -8,6 +8,7 @@ import ( mrand "math/rand" "slices" "strconv" + "strings" "testing" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/netmap" @@ -251,6 +252,92 @@ func TestPlacementPolicy_ProcessSelectors(t *testing.T) { } } +func TestPlacementPolicy_Like(t *testing.T) { + nodes := []NodeInfo{ + nodeInfoFromAttributes("Country", "Russia"), + nodeInfoFromAttributes("Country", "Germany"), + nodeInfoFromAttributes("Country", "Belarus"), + } + + var nm NetMap + nm.SetNodes(nodes) + + t.Run("LIKE all", func(t *testing.T) { + ssNamed := []Selector{newSelector("X", "Country", 4, "FromRU", (*Selector).SelectDistinct)} + fsNamed := []Filter{newFilter("FromRU", "Country", "*", netmap.LIKE)} + rsNamed := []ReplicaDescriptor{newReplica(4, "X")} + pNamed := newPlacementPolicy(0, rsNamed, ssNamed, fsNamed) + + n, err := nm.ContainerNodes(pNamed, []byte{1}) + require.NoError(t, err) + + require.Equal(t, 3, len(n[0])) + for _, n := range n[0] { + require.True(t, strings.Contains("GermanyRussiaBelarus", n.Attribute("Country"))) + } + }) + + t.Run("LIKE no wildcard", func(t *testing.T) { + ssNamed := []Selector{newSelector("X", "Country", 1, "FromRU", (*Selector).SelectDistinct)} + fsNamed := []Filter{newFilter("FromRU", "Country", "Russia", netmap.LIKE)} + rsNamed := []ReplicaDescriptor{newReplica(1, "X")} + pNamed := newPlacementPolicy(0, rsNamed, ssNamed, fsNamed) + + n, err := nm.ContainerNodes(pNamed, []byte{1}) + require.NoError(t, err) + + require.Equal(t, 1, len(n[0])) + for _, n := range n[0] { + require.True(t, n.Attribute("Country") == "Russia") + } + }) + + t.Run("LIKE prefix", func(t *testing.T) { + ssNamed := []Selector{newSelector("X", "Country", 1, "FromRU", (*Selector).SelectDistinct)} + fsNamed := []Filter{newFilter("FromRU", "Country", "Ge*", netmap.LIKE)} + rsNamed := []ReplicaDescriptor{newReplica(1, "X")} + pNamed := newPlacementPolicy(0, rsNamed, ssNamed, fsNamed) + + n, err := nm.ContainerNodes(pNamed, []byte{1}) + require.NoError(t, err) + + require.Equal(t, 1, len(n[0])) + for _, n := range n[0] { + require.True(t, n.Attribute("Country") == "Germany") + } + }) + + t.Run("LIKE suffix", func(t *testing.T) { + ssNamed := []Selector{newSelector("X", "Country", 1, "FromRU", (*Selector).SelectDistinct)} + fsNamed := []Filter{newFilter("FromRU", "Country", "*sia", netmap.LIKE)} + rsNamed := []ReplicaDescriptor{newReplica(1, "X")} + pNamed := newPlacementPolicy(0, rsNamed, ssNamed, fsNamed) + + n, err := nm.ContainerNodes(pNamed, []byte{1}) + require.NoError(t, err) + + require.Equal(t, 1, len(n[0])) + for _, n := range n[0] { + require.True(t, n.Attribute("Country") == "Russia") + } + }) + + t.Run("LIKE middle", func(t *testing.T) { + ssNamed := []Selector{newSelector("X", "Country", 2, "FromRU", (*Selector).SelectDistinct)} + fsNamed := []Filter{newFilter("FromRU", "Country", "*us*", netmap.LIKE)} + rsNamed := []ReplicaDescriptor{newReplica(2, "X")} + pNamed := newPlacementPolicy(0, rsNamed, ssNamed, fsNamed) + + n, err := nm.ContainerNodes(pNamed, []byte{1}) + require.NoError(t, err) + + require.Equal(t, 2, len(n[0])) + for _, n := range n[0] { + require.True(t, strings.Contains("RussiaBelarus", n.Attribute("Country"))) + } + }) +} + func TestPlacementPolicy_Unique(t *testing.T) { p := newPlacementPolicy(2, []ReplicaDescriptor{ diff --git a/netmap/yml_unmarshal.go b/netmap/yml_unmarshal.go index fa94586..7c38b2c 100644 --- a/netmap/yml_unmarshal.go +++ b/netmap/yml_unmarshal.go @@ -44,15 +44,16 @@ func convertNFilters(temp []tempFilter) []netmap.Filter { } var stringToOperationMap = map[string]netmap.Operation{ - "EQ": netmap.EQ, - "NE": netmap.NE, - "GT": netmap.GT, - "GE": netmap.GE, - "LT": netmap.LT, - "LE": netmap.LE, - "OR": netmap.OR, - "AND": netmap.AND, - "NOT": netmap.NOT, + "EQ": netmap.EQ, + "NE": netmap.NE, + "GT": netmap.GT, + "GE": netmap.GE, + "LT": netmap.LT, + "LE": netmap.LE, + "OR": netmap.OR, + "AND": netmap.AND, + "NOT": netmap.NOT, + "LIKE": netmap.LIKE, } func convertStringToOperation(opStr string) netmap.Operation {