You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by zh...@apache.org on 2023/05/16 03:48:34 UTC

[apisix-ingress-controller] branch master updated: chore: StringToByte without mem-allocation supports v1.20 (#1750)

This is an automated email from the ASF dual-hosted git repository.

zhangjintao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git


The following commit(s) were added to refs/heads/master by this push:
     new 7b81a8b0 chore: StringToByte without mem-allocation supports v1.20 (#1750)
7b81a8b0 is described below

commit 7b81a8b0dc785217adab3377db428564f6e64726
Author: tyltr <ty...@126.com>
AuthorDate: Tue May 16 11:48:29 2023 +0800

    chore: StringToByte without mem-allocation supports v1.20 (#1750)
---
 .gitignore                             |  1 +
 pkg/id/idgen.go                        | 11 +++-------
 pkg/{id/idgen.go => utils/s2b_new.go}  | 27 ++++++-----------------
 pkg/{id/idgen.go => utils/s2b_old.go}  | 32 +++++++++++++--------------
 pkg/{id/idgen.go => utils/s2b_test.go} | 40 ++++++++++++++++++++--------------
 5 files changed, 51 insertions(+), 60 deletions(-)

diff --git a/.gitignore b/.gitignore
index be473d69..9d9280ab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ release
 
 .vscode
 .idea
+vendor/
 .DS_Store
 coverage.txt
 test/e2e/coverage.txt
diff --git a/pkg/id/idgen.go b/pkg/id/idgen.go
index 19990647..c08efe25 100644
--- a/pkg/id/idgen.go
+++ b/pkg/id/idgen.go
@@ -18,8 +18,8 @@ package id
 import (
 	"fmt"
 	"hash/crc32"
-	"reflect"
-	"unsafe"
+
+	"github.com/apache/apisix-ingress-controller/pkg/utils"
 )
 
 // GenID generates an ID according to the raw material.
@@ -27,12 +27,7 @@ func GenID(raw string) string {
 	if raw == "" {
 		return ""
 	}
-	sh := &reflect.SliceHeader{
-		Data: (*reflect.StringHeader)(unsafe.Pointer(&raw)).Data,
-		Len:  len(raw),
-		Cap:  len(raw),
-	}
-	p := *(*[]byte)(unsafe.Pointer(sh))
+	p := utils.String2Byte(raw)
 
 	res := crc32.ChecksumIEEE(p)
 	return fmt.Sprintf("%x", res)
diff --git a/pkg/id/idgen.go b/pkg/utils/s2b_new.go
similarity index 66%
copy from pkg/id/idgen.go
copy to pkg/utils/s2b_new.go
index 19990647..209069a8 100644
--- a/pkg/id/idgen.go
+++ b/pkg/utils/s2b_new.go
@@ -13,27 +13,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package id
+//go:build go1.20
+// +build go1.20
 
-import (
-	"fmt"
-	"hash/crc32"
-	"reflect"
-	"unsafe"
-)
+package utils
 
-// GenID generates an ID according to the raw material.
-func GenID(raw string) string {
-	if raw == "" {
-		return ""
-	}
-	sh := &reflect.SliceHeader{
-		Data: (*reflect.StringHeader)(unsafe.Pointer(&raw)).Data,
-		Len:  len(raw),
-		Cap:  len(raw),
-	}
-	p := *(*[]byte)(unsafe.Pointer(sh))
+import "unsafe"
 
-	res := crc32.ChecksumIEEE(p)
-	return fmt.Sprintf("%x", res)
+// s2b converts string to a byte slice without memory allocation.
+func String2Byte(s string) []byte {
+	return unsafe.Slice(unsafe.StringData(s), len(s))
 }
diff --git a/pkg/id/idgen.go b/pkg/utils/s2b_old.go
similarity index 61%
copy from pkg/id/idgen.go
copy to pkg/utils/s2b_old.go
index 19990647..ba045b89 100644
--- a/pkg/id/idgen.go
+++ b/pkg/utils/s2b_old.go
@@ -13,27 +13,27 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package id
+//go:build !go1.20
+// +build !go1.20
+
+package utils
 
 import (
-	"fmt"
-	"hash/crc32"
 	"reflect"
 	"unsafe"
 )
 
-// GenID generates an ID according to the raw material.
-func GenID(raw string) string {
-	if raw == "" {
-		return ""
-	}
-	sh := &reflect.SliceHeader{
-		Data: (*reflect.StringHeader)(unsafe.Pointer(&raw)).Data,
-		Len:  len(raw),
-		Cap:  len(raw),
-	}
-	p := *(*[]byte)(unsafe.Pointer(sh))
+// String2Byte converts a string to a byte slice without memory allocation.
+//
+// Note since Go 1.20, the reflect.StringHeader and reflect.SliceHeader types
+// will be depreciated and not recommended to be used.
+func String2Byte(raw string) (b []byte) {
+
+	strHeader := (*reflect.StringHeader)(unsafe.Pointer(&raw))
+	bHeader := (*reflect.SliceHeader)(unsafe.Pointer(&b))
 
-	res := crc32.ChecksumIEEE(p)
-	return fmt.Sprintf("%x", res)
+	bHeader.Data = strHeader.Data
+	bHeader.Cap = strHeader.Len
+	bHeader.Len = strHeader.Len
+	return b
 }
diff --git a/pkg/id/idgen.go b/pkg/utils/s2b_test.go
similarity index 64%
copy from pkg/id/idgen.go
copy to pkg/utils/s2b_test.go
index 19990647..b177c7f6 100644
--- a/pkg/id/idgen.go
+++ b/pkg/utils/s2b_test.go
@@ -13,27 +13,35 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package id
+package utils
 
 import (
-	"fmt"
-	"hash/crc32"
 	"reflect"
-	"unsafe"
+	"testing"
 )
 
-// GenID generates an ID according to the raw material.
-func GenID(raw string) string {
-	if raw == "" {
-		return ""
+func TestString2Byte(t *testing.T) {
+	type args struct {
+		raw string
 	}
-	sh := &reflect.SliceHeader{
-		Data: (*reflect.StringHeader)(unsafe.Pointer(&raw)).Data,
-		Len:  len(raw),
-		Cap:  len(raw),
+	tests := []struct {
+		name  string
+		args  args
+		wantB []byte
+	}{
+		{
+			name: "test-1",
+			args: args{
+				raw: "a",
+			},
+			wantB: []byte{'a'},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if gotB := String2Byte(tt.args.raw); !reflect.DeepEqual(gotB, tt.wantB) {
+				t.Errorf("String2byte() = %v, want %v", gotB, tt.wantB)
+			}
+		})
 	}
-	p := *(*[]byte)(unsafe.Pointer(sh))
-
-	res := crc32.ChecksumIEEE(p)
-	return fmt.Sprintf("%x", res)
 }