libct/utils: SearchLabels: optimize

Using strings.Split generates temporary strings for GC to collect.
Rewrite the function to not do that.

Also, add a second return value, so that the caller can distinguish
between an empty value found and no key found cases.

Fix the test accordingly.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2021-11-30 12:15:08 -08:00
parent 403cda19e4
commit 3d86d31b9f
3 changed files with 29 additions and 23 deletions
+8 -11
View File
@@ -132,19 +132,16 @@ func WithProcfd(root, unsafePath string, fn func(procfd string) error) error {
return fn(procfd)
}
// SearchLabels searches a list of key-value pairs for the provided key and
// returns the corresponding value. The pairs must be separated with '='.
func SearchLabels(labels []string, query string) string {
for _, l := range labels {
parts := strings.SplitN(l, "=", 2)
if len(parts) < 2 {
continue
}
if parts[0] == query {
return parts[1]
// SearchLabels searches through a list of key=value pairs for a given key,
// returning its value, and the binary flag telling whether the key exist.
func SearchLabels(labels []string, key string) (string, bool) {
key += "="
for _, s := range labels {
if strings.HasPrefix(s, key) {
return s[len(key):], true
}
}
return ""
return "", false
}
// Annotations returns the bundle path and user defined annotations from the
+17 -11
View File
@@ -8,22 +8,28 @@ import (
)
var labelTest = []struct {
labels []string
query string
expectedValue string
labels []string
query string
expVal string
expOk bool
}{
{[]string{"bundle=/path/to/bundle"}, "bundle", "/path/to/bundle"},
{[]string{"test=a", "test=b"}, "bundle", ""},
{[]string{"bundle=a", "test=b", "bundle=c"}, "bundle", "a"},
{[]string{"", "test=a", "bundle=b"}, "bundle", "b"},
{[]string{"test", "bundle=a"}, "bundle", "a"},
{[]string{"test=a", "bundle="}, "bundle", ""},
{[]string{"bundle=/path/to/bundle"}, "bundle", "/path/to/bundle", true},
{[]string{"test=a", "test=b"}, "bundle", "", false},
{[]string{"bundle=a", "test=b", "bundle=c"}, "bundle", "a", true},
{[]string{"", "test=a", "bundle=b"}, "bundle", "b", true},
{[]string{"test", "bundle=a"}, "bundle", "a", true},
{[]string{"test=a", "bundle="}, "bundle", "", true},
}
func TestSearchLabels(t *testing.T) {
for _, tt := range labelTest {
if v := SearchLabels(tt.labels, tt.query); v != tt.expectedValue {
t.Errorf("expected value '%s' for query '%s'; got '%s'", tt.expectedValue, tt.query, v)
v, ok := SearchLabels(tt.labels, tt.query)
if ok != tt.expOk {
t.Errorf("expected ok: %v, got %v", tt.expOk, ok)
continue
}
if v != tt.expVal {
t.Errorf("expected value '%s' for query '%s'; got '%s'", tt.expVal, tt.query, v)
}
}
}