diff options
author | Martin Polden <mpolden@mpolden.no> | 2022-12-08 16:46:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-08 16:46:15 +0100 |
commit | 38671ad78423723788bf8d7bb9107d74c23ea5a5 (patch) | |
tree | 7a365f11eec9fb5e87fc6811095204c776f2308b | |
parent | f3140c5361d3492df2d227c468e9e80744732da3 (diff) | |
parent | f05e920ef523a10cc3531286b0a4135676e9fa2a (diff) |
Merge pull request #25151 from vespa-engine/arnej/generic-go-arraylist-2
Arnej/generic go arraylist 2
-rw-r--r-- | client/go/jvm/container.go | 7 | ||||
-rw-r--r-- | client/go/jvm/options.go | 8 | ||||
-rw-r--r-- | client/go/script-utils/configserver/runserver.go | 6 | ||||
-rw-r--r-- | client/go/script-utils/startcbinary/numactl.go | 18 | ||||
-rw-r--r-- | client/go/script-utils/startcbinary/valgrind.go | 16 | ||||
-rw-r--r-- | client/go/util/array_list.go | 81 | ||||
-rw-r--r-- | client/go/util/array_list_test.go | 110 |
7 files changed, 212 insertions, 34 deletions
diff --git a/client/go/jvm/container.go b/client/go/jvm/container.go index fd65602e573..c755672da86 100644 --- a/client/go/jvm/container.go +++ b/client/go/jvm/container.go @@ -60,11 +60,8 @@ func readableEnv(env map[string]string) string { } func (cb *containerBase) Exec() { - argv := make([]string, 0, 100) - argv = append(argv, "java") - for _, x := range cb.JvmOptions().Args() { - argv = append(argv, x) - } + argv := util.ArrayListOf(cb.JvmOptions().Args()) + argv.Insert(0, "java") p := prog.NewSpec(argv) p.ConfigureNumaCtl() cb.JvmOptions().exportEnvSettings(p) diff --git a/client/go/jvm/options.go b/client/go/jvm/options.go index deb842936ba..55749e86709 100644 --- a/client/go/jvm/options.go +++ b/client/go/jvm/options.go @@ -17,7 +17,7 @@ import ( type Options struct { container Container classPath []string - jvmArgs []string + jvmArgs util.ArrayList[string] mainClass string fixSpec util.FixSpec } @@ -40,10 +40,8 @@ func NewOptions(c Container) *Options { } func (opts *Options) AddOption(arg string) { - for _, old := range opts.jvmArgs { - if arg == old { - return - } + if opts.jvmArgs.Contains(arg) { + return } opts.AppendOption(arg) } diff --git a/client/go/script-utils/configserver/runserver.go b/client/go/script-utils/configserver/runserver.go index 3f49285d036..9afa154cc06 100644 --- a/client/go/script-utils/configserver/runserver.go +++ b/client/go/script-utils/configserver/runserver.go @@ -45,7 +45,7 @@ func (rs *RunServer) WouldRun() bool { } func (rs *RunServer) Exec(prog string) { - argv := []string{ + argv := util.ArrayList[string]{ PROG_NAME, "-s", rs.ServiceName, "-r", "30", @@ -53,9 +53,7 @@ func (rs *RunServer) Exec(prog string) { "--", prog, } - for _, arg := range rs.Args { - argv = append(argv, arg) - } + argv.AppendAll(rs.Args...) err := util.Execvp(rs.ProgPath(), argv) util.JustExitWith(err) } diff --git a/client/go/script-utils/startcbinary/numactl.go b/client/go/script-utils/startcbinary/numactl.go index 89d9c144649..1585d8ddf81 100644 --- a/client/go/script-utils/startcbinary/numactl.go +++ b/client/go/script-utils/startcbinary/numactl.go @@ -58,17 +58,15 @@ func (p *ProgSpec) numaCtlBinary() string { } func (p *ProgSpec) prependNumaCtl(args []string) []string { - result := make([]string, 0, 5+len(args)) - result = append(result, "numactl") + v := util.NewArrayList[string](5 + len(args)) + v.Append("numactl") if p.numaSocket >= 0 { - result = append(result, fmt.Sprintf("--cpunodebind=%d", p.numaSocket)) - result = append(result, fmt.Sprintf("--membind=%d", p.numaSocket)) + v.Append(fmt.Sprintf("--cpunodebind=%d", p.numaSocket)) + v.Append(fmt.Sprintf("--membind=%d", p.numaSocket)) } else { - result = append(result, "--interleave") - result = append(result, "all") + v.Append("--interleave") + v.Append("all") } - for _, arg := range args { - result = append(result, arg) - } - return result + v.AppendAll(args...) + return v } diff --git a/client/go/script-utils/startcbinary/valgrind.go b/client/go/script-utils/startcbinary/valgrind.go index ecbca36e823..ffbbd8cca8d 100644 --- a/client/go/script-utils/startcbinary/valgrind.go +++ b/client/go/script-utils/startcbinary/valgrind.go @@ -73,14 +73,10 @@ func (p *ProgSpec) valgrindLogOption() string { } func (p *ProgSpec) prependValgrind(args []string) []string { - result := make([]string, 0, 15+len(args)) - result = append(result, p.valgrindBinary()) - for _, arg := range p.valgrindOptions() { - result = append(result, arg) - } - result = append(result, p.valgrindLogOption()) - for _, arg := range args { - result = append(result, arg) - } - return result + v := util.NewArrayList[string](15 + len(args)) + v.Append(p.valgrindBinary()) + v.AppendAll(p.valgrindOptions()...) + v.Append(p.valgrindLogOption()) + v.AppendAll(args...) + return v } diff --git a/client/go/util/array_list.go b/client/go/util/array_list.go new file mode 100644 index 00000000000..2e74d30fcec --- /dev/null +++ b/client/go/util/array_list.go @@ -0,0 +1,81 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Author: arnej + +// generic utilities +package util + +type ArrayList[E comparable] []E + +func NewArrayList[E comparable](initialCapacity int) ArrayList[E] { + return make([]E, 0, initialCapacity) +} + +func ArrayListOf[E comparable](elems []E) ArrayList[E] { + return ArrayList[E](elems) +} + +func (arrayP *ArrayList[E]) Append(elem E) { + *arrayP = append(*arrayP, elem) +} + +func (arrayP *ArrayList[E]) AppendAll(elemsToAppend ...E) { + firstLen := len(*arrayP) + secondLen := len(elemsToAppend) + totLen := firstLen + secondLen + if totLen > cap(*arrayP) { + res := make([]E, totLen, cap(*arrayP)+cap(elemsToAppend)) + copy(res, *arrayP) + copy(res[firstLen:], elemsToAppend) + *arrayP = res + } else { + res := (*arrayP)[0:totLen] + copy(res[firstLen:], elemsToAppend) + *arrayP = res + } +} + +func (arrayP *ArrayList[E]) Insert(index int, elem E) { + cur := *arrayP + oldLen := len(cur) + result := append(cur, elem) + if index != oldLen { + copy(result[index+1:], cur[index:]) + result[index] = elem + } + *arrayP = result +} + +func (arrayP *ArrayList[E]) InsertAll(index int, elemsToInsert ...E) { + firstLen := len(*arrayP) + secondLen := len(elemsToInsert) + totLen := firstLen + secondLen + var res []E + if totLen > cap(*arrayP) { + res = make([]E, totLen, cap(*arrayP)+cap(elemsToInsert)) + firstPart := (*arrayP)[:index] + copy(res, firstPart) + } else { + res = (*arrayP)[0:totLen] + } + thirdPart := (*arrayP)[index:] + dst := res[index+secondLen:] + copy(dst, thirdPart) + dst = res[index:] + copy(dst, elemsToInsert) + *arrayP = res +} + +func (arrayP *ArrayList[E]) Contains(elem E) bool { + for _, old := range *arrayP { + if elem == old { + return true + } + } + return false +} + +func (arrayP *ArrayList[E]) Each(f func(E)) { + for _, elem := range *arrayP { + f(elem) + } +} diff --git a/client/go/util/array_list_test.go b/client/go/util/array_list_test.go new file mode 100644 index 00000000000..79eab4f8ef2 --- /dev/null +++ b/client/go/util/array_list_test.go @@ -0,0 +1,110 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package util + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestArrayApi1(t *testing.T) { + v := ArrayList[string]{"x", "y", "z"} + assert.Equal(t, 3, len(v)) + v.Append("a") + assert.Equal(t, 4, len(v)) + v.Insert(2, "b") + assert.Equal(t, 5, len(v)) + v.Insert(0, "c") + assert.Equal(t, 6, len(v)) + assert.Equal(t, "c", v[0]) + assert.Equal(t, "x", v[1]) + assert.Equal(t, "y", v[2]) + assert.Equal(t, "b", v[3]) + assert.Equal(t, "z", v[4]) + assert.Equal(t, "a", v[5]) +} + +func TestArrayApi2(t *testing.T) { + tmp := []string{"i", "j", "k"} + v := NewArrayList[string](10) + assert.Equal(t, 0, len(v)) + assert.Equal(t, 10, cap(v)) + v.AppendAll(tmp...) + assert.Equal(t, 3, len(v)) + assert.Equal(t, 10, cap(v)) + v.AppendAll(tmp...) + assert.Equal(t, 6, len(v)) + assert.Equal(t, 10, cap(v)) + v.AppendAll(tmp...) + assert.Equal(t, 9, len(v)) + assert.Equal(t, 10, cap(v)) + v.AppendAll(tmp...) + assert.Equal(t, 12, len(v)) + assert.Less(t, 11, cap(v)) +} + +func TestArrayApi3(t *testing.T) { + tmp := []string{"i", "j", "k"} + v := ArrayList[string]{ + "foo", "bar", + "baz", "qux", + } + assert.Equal(t, 4, len(v)) + v.InsertAll(0, "a", "b") + assert.Equal(t, 6, len(v)) + v.AppendAll(tmp...) + assert.Equal(t, 9, len(v)) + v.AppendAll("x", "y") + assert.Equal(t, 11, len(v)) + v.InsertAll(4, "foobar", "barfoo") + assert.Equal(t, 13, len(v)) + assert.Equal(t, "a", v[0]) + assert.Equal(t, "b", v[1]) + assert.Equal(t, "foo", v[2]) + assert.Equal(t, "bar", v[3]) + assert.Equal(t, "foobar", v[4]) + assert.Equal(t, "barfoo", v[5]) + assert.Equal(t, "baz", v[6]) + assert.Equal(t, "qux", v[7]) + assert.Equal(t, "i", v[8]) + assert.Equal(t, "j", v[9]) + assert.Equal(t, "k", v[10]) + assert.Equal(t, "x", v[11]) + assert.Equal(t, "y", v[12]) +} + +func TestArrayApi4(t *testing.T) { + v := NewArrayList[string](12) + arr := v[0:10] + v.InsertAll(0, "a", "b", "e") + v.InsertAll(3, "f", "g", "o") + v.InsertAll(2, "c", "d") + v.InsertAll(7, "h", "i", "j", "k", "l", "m", "n") + assert.Equal(t, 15, len(v)) + assert.Equal(t, "a", v[0]) + assert.Equal(t, "b", v[1]) + assert.Equal(t, "c", v[2]) + assert.Equal(t, "d", v[3]) + assert.Equal(t, "e", v[4]) + assert.Equal(t, "f", v[5]) + assert.Equal(t, "g", v[6]) + assert.Equal(t, "h", v[7]) + assert.Equal(t, "i", v[8]) + assert.Equal(t, "j", v[9]) + assert.Equal(t, "k", v[10]) + assert.Equal(t, "l", v[11]) + assert.Equal(t, "m", v[12]) + assert.Equal(t, "n", v[13]) + assert.Equal(t, "o", v[14]) + assert.Equal(t, 10, len(arr)) + assert.Equal(t, "a", arr[0]) + assert.Equal(t, "b", arr[1]) + assert.Equal(t, "c", arr[2]) + assert.Equal(t, "d", arr[3]) + assert.Equal(t, "e", arr[4]) + assert.Equal(t, "f", arr[5]) + assert.Equal(t, "g", arr[6]) + assert.Equal(t, "o", arr[7]) + assert.Equal(t, "", arr[8]) + assert.Equal(t, "", arr[9]) +} |