소스 검색

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>
Cory Snider 2 년 전
부모
커밋
51bcf5954f
2개의 변경된 파일24개의 추가작업 그리고 3개의 파일을 삭제
  1. 9 3
      libnetwork/drivers/overlay/overlayutils/utils.go
  2. 15 0
      libnetwork/drivers/overlay/overlayutils/utils_test.go

+ 9 - 3
libnetwork/drivers/overlay/overlayutils/utils.go

@@ -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
 }

+ 15 - 0
libnetwork/drivers/overlay/overlayutils/utils_test.go

@@ -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))
+	})
 }