mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
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:
@@ -162,7 +162,10 @@ func execProcess(context *cli.Context) (int, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
}
|
}
|
||||||
bundle := utils.SearchLabels(state.Config.Labels, "bundle")
|
bundle, ok := utils.SearchLabels(state.Config.Labels, "bundle")
|
||||||
|
if !ok {
|
||||||
|
return -1, errors.New("bundle not found in labels")
|
||||||
|
}
|
||||||
p, err := getProcess(context, bundle)
|
p, err := getProcess(context, bundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, err
|
return -1, err
|
||||||
|
|||||||
@@ -132,19 +132,16 @@ func WithProcfd(root, unsafePath string, fn func(procfd string) error) error {
|
|||||||
return fn(procfd)
|
return fn(procfd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchLabels searches a list of key-value pairs for the provided key and
|
// SearchLabels searches through a list of key=value pairs for a given key,
|
||||||
// returns the corresponding value. The pairs must be separated with '='.
|
// returning its value, and the binary flag telling whether the key exist.
|
||||||
func SearchLabels(labels []string, query string) string {
|
func SearchLabels(labels []string, key string) (string, bool) {
|
||||||
for _, l := range labels {
|
key += "="
|
||||||
parts := strings.SplitN(l, "=", 2)
|
for _, s := range labels {
|
||||||
if len(parts) < 2 {
|
if strings.HasPrefix(s, key) {
|
||||||
continue
|
return s[len(key):], true
|
||||||
}
|
|
||||||
if parts[0] == query {
|
|
||||||
return parts[1]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Annotations returns the bundle path and user defined annotations from the
|
// Annotations returns the bundle path and user defined annotations from the
|
||||||
|
|||||||
@@ -8,22 +8,28 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var labelTest = []struct {
|
var labelTest = []struct {
|
||||||
labels []string
|
labels []string
|
||||||
query string
|
query string
|
||||||
expectedValue string
|
expVal string
|
||||||
|
expOk bool
|
||||||
}{
|
}{
|
||||||
{[]string{"bundle=/path/to/bundle"}, "bundle", "/path/to/bundle"},
|
{[]string{"bundle=/path/to/bundle"}, "bundle", "/path/to/bundle", true},
|
||||||
{[]string{"test=a", "test=b"}, "bundle", ""},
|
{[]string{"test=a", "test=b"}, "bundle", "", false},
|
||||||
{[]string{"bundle=a", "test=b", "bundle=c"}, "bundle", "a"},
|
{[]string{"bundle=a", "test=b", "bundle=c"}, "bundle", "a", true},
|
||||||
{[]string{"", "test=a", "bundle=b"}, "bundle", "b"},
|
{[]string{"", "test=a", "bundle=b"}, "bundle", "b", true},
|
||||||
{[]string{"test", "bundle=a"}, "bundle", "a"},
|
{[]string{"test", "bundle=a"}, "bundle", "a", true},
|
||||||
{[]string{"test=a", "bundle="}, "bundle", ""},
|
{[]string{"test=a", "bundle="}, "bundle", "", true},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSearchLabels(t *testing.T) {
|
func TestSearchLabels(t *testing.T) {
|
||||||
for _, tt := range labelTest {
|
for _, tt := range labelTest {
|
||||||
if v := SearchLabels(tt.labels, tt.query); v != tt.expectedValue {
|
v, ok := SearchLabels(tt.labels, tt.query)
|
||||||
t.Errorf("expected value '%s' for query '%s'; got '%s'", tt.expectedValue, tt.query, v)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user