aboutsummaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorArne H Juul <arnej@yahooinc.com>2022-11-27 22:12:58 +0100
committerArne Juul <arnej@yahooinc.com>2022-12-06 15:50:49 +0100
commite46ae35f556f370c63639b280324ebc315f62782 (patch)
tree44c1bb848a753da0b7afea4214bc8639fe87a714 /client
parent3d4d7645221a7ca7ddba0191a8e11a97924736dc (diff)
add and use util.Array
Diffstat (limited to 'client')
-rw-r--r--client/go/jvm/container.go7
-rw-r--r--client/go/jvm/options.go8
-rw-r--r--client/go/script-utils/configserver/runserver.go6
-rw-r--r--client/go/script-utils/startcbinary/numactl.go18
-rw-r--r--client/go/script-utils/startcbinary/valgrind.go16
-rw-r--r--client/go/util/array.go89
-rw-r--r--client/go/util/array_test.go110
7 files changed, 220 insertions, 34 deletions
diff --git a/client/go/jvm/container.go b/client/go/jvm/container.go
index fd65602e573..5e37e402593 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.ArrayOf(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..6588a365bbd 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.Array[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..29bd4476ae1 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.Array[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(argv)
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..e60612ccf24 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.NewArray[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..301b8b3986a 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.NewArray[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.go b/client/go/util/array.go
new file mode 100644
index 00000000000..d88f7481b5f
--- /dev/null
+++ b/client/go/util/array.go
@@ -0,0 +1,89 @@
+// 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 Array[E comparable] []E
+
+func NewArray[E comparable](initialCapacity int) Array[E] {
+ return make([]E, 0, initialCapacity)
+}
+
+func ArrayOf[E comparable](elems []E) Array[E] {
+ return Array[E](elems)
+}
+
+func (arrayP *Array[E]) Append(elem E) {
+ *arrayP = append(*arrayP, elem)
+}
+
+func (arrayP *Array[E]) AppendElements(elems ...E) {
+ arrayP.AppendAll(elems)
+}
+
+func (arrayP *Array[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 *Array[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 *Array[E]) InsertElements(index int, elems ...E) {
+ arrayP.InsertAll(index, elems)
+}
+
+func (arrayP *Array[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 *Array[E]) Contains(elem E) bool {
+ for _, old := range *arrayP {
+ if elem == old {
+ return true
+ }
+ }
+ return false
+}
+
+func (arrayP *Array[E]) ForEach(f func(E)) {
+ for _, elem := range *arrayP {
+ f(elem)
+ }
+}
diff --git a/client/go/util/array_test.go b/client/go/util/array_test.go
new file mode 100644
index 00000000000..1bf7910ce92
--- /dev/null
+++ b/client/go/util/array_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 := Array[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 := NewArray[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 := Array[string]{
+ "foo", "bar",
+ "baz", "qux",
+ }
+ assert.Equal(t, 4, len(v))
+ v.InsertElements(0, "a", "b")
+ assert.Equal(t, 6, len(v))
+ v.AppendAll(tmp)
+ assert.Equal(t, 9, len(v))
+ v.AppendElements("x", "y")
+ assert.Equal(t, 11, len(v))
+ v.InsertElements(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 := NewArray[string](12)
+ arr := v[0:10]
+ v.InsertAll(0, []string{"a", "b", "e"})
+ v.InsertAll(3, []string{"f", "g", "o"})
+ v.InsertAll(2, []string{"c", "d"})
+ v.InsertAll(7, []string{"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])
+}