libnet/d/overlay: parse VNI list w/o allocating

Parse in O(1) memory by using strings.Cut to split the string
iteratively.

Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
Cory Snider 2023-07-05 17:17:21 -04:00
parent 96ca669fa4
commit 51bcf5954f
2 changed files with 24 additions and 3 deletions

View file

@ -45,14 +45,20 @@ func VXLANUDPPort() uint32 {
// AppendVNIList appends the VNI values encoded as a CSV string to slice.
func AppendVNIList(vnis []uint32, csv string) ([]uint32, error) {
vniStrings := strings.Split(csv, ",")
for _, vniStr := range vniStrings {
for {
var (
vniStr string
found bool
)
vniStr, csv, found = strings.Cut(csv, ",")
vni, err := strconv.Atoi(vniStr)
if err != nil {
return vnis, fmt.Errorf("invalid vxlan id value %q passed", vniStr)
}
vnis = append(vnis, uint32(vni))
if !found {
return vnis, nil
}
}
return vnis, nil
}

View file

@ -64,4 +64,19 @@ func TestAppendVNIList(t *testing.T) {
}
})
}
t.Run("DoesNotAllocate", func(t *testing.T) {
slice := make([]uint32, 0, 10)
csv := "1,2,3,4,5,6,7,8,9,10"
want := []uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
allocs := testing.AllocsPerRun(10, func() {
var err error
slice, err = AppendVNIList(slice[:0], csv)
if err != nil {
t.Fatal(err)
}
})
assert.Check(t, is.DeepEqual(slice, want))
assert.Check(t, is.Equal(int(allocs), 0))
})
}