You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by vi...@apache.org on 2020/12/18 08:51:23 UTC

[dubbo-go] branch develop updated: Optimize the memory usage (#916)

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

victory pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git


The following commit(s) were added to refs/heads/develop by this push:
     new ce90b4b  Optimize the memory usage (#916)
ce90b4b is described below

commit ce90b4b3a30cb5956e03d9d1031aa1d4066f8b88
Author: cvictory <sh...@gmail.com>
AuthorDate: Fri Dec 18 16:51:08 2020 +0800

    Optimize the memory usage (#916)
    
    * #901 Optimize the memory usage.
---
 common/url.go      | 45 +++++++++++++++++++++++++++++----------------
 common/url_test.go | 10 ++++++++++
 2 files changed, 39 insertions(+), 16 deletions(-)

diff --git a/common/url.go b/common/url.go
index efb4dfc..8019173 100644
--- a/common/url.go
+++ b/common/url.go
@@ -427,6 +427,14 @@ func (c *URL) SetParam(key string, value string) {
 	c.params.Set(key, value)
 }
 
+// ReplaceParams will replace the URL.params
+// usually it should only be invoked when you want to modify an url, such as MergeURL
+func (c *URL) ReplaceParams(param url.Values) {
+	c.paramsLock.Lock()
+	defer c.paramsLock.Unlock()
+	c.params = param
+}
+
 // RangeParams will iterate the params
 func (c *URL) RangeParams(f func(key, value string) bool) {
 	c.paramsLock.RLock()
@@ -559,10 +567,10 @@ func (c *URL) GetMethodParamBool(method string, key string, d bool) bool {
 	return r
 }
 
-// SetParams will put all key-value pair into url.
-// 1. if there already has same key, the value will be override
-// 2. it's not thread safe
-// 3. think twice when you want to invoke this method
+//SetParams will put all key-value pair into url.
+//1. if there already has same key, the value will be override
+//2. it's not thread safe
+//3. think twice when you want to invoke this method
 func (c *URL) SetParams(m url.Values) {
 	for k := range m {
 		c.SetParam(k, m.Get(k))
@@ -621,22 +629,26 @@ func (c *URL) ToMap() map[string]string {
 // You should notice that the value of b1 is v2, not v4.
 // due to URL is not thread-safe, so this method is not thread-safe
 func MergeUrl(serviceUrl *URL, referenceUrl *URL) *URL {
+	// After Clone, it is a new url that there is no thread safe issue.
 	mergedUrl := serviceUrl.Clone()
-
+	params := mergedUrl.GetParams()
 	// iterator the referenceUrl if serviceUrl not have the key ,merge in
-	referenceUrl.RangeParams(func(key, value string) bool {
+	// referenceUrl usually will not changed. so change RangeParams to GetParams to avoid the string value copy.
+	for key, value := range referenceUrl.GetParams() {
 		if v := mergedUrl.GetParam(key, ""); len(v) == 0 {
-			mergedUrl.SetParam(key, value)
+			if len(value) > 0 {
+				params[key] = value
+			}
 		}
-		return true
-	})
+	}
+
 	// loadBalance,cluster,retries strategy config
-	methodConfigMergeFcn := mergeNormalParam(mergedUrl, referenceUrl, []string{constant.LOADBALANCE_KEY, constant.CLUSTER_KEY, constant.RETRIES_KEY, constant.TIMEOUT_KEY})
+	methodConfigMergeFcn := mergeNormalParam(params, referenceUrl, []string{constant.LOADBALANCE_KEY, constant.CLUSTER_KEY, constant.RETRIES_KEY, constant.TIMEOUT_KEY})
 
 	// remote timestamp
 	if v := serviceUrl.GetParam(constant.TIMESTAMP_KEY, ""); len(v) > 0 {
-		mergedUrl.SetParam(constant.REMOTE_TIMESTAMP_KEY, v)
-		mergedUrl.SetParam(constant.TIMESTAMP_KEY, referenceUrl.GetParam(constant.TIMESTAMP_KEY, ""))
+		params[constant.REMOTE_TIMESTAMP_KEY] = []string{v}
+		params[constant.TIMESTAMP_KEY] = []string{referenceUrl.GetParam(constant.TIMESTAMP_KEY, "")}
 	}
 
 	// finally execute methodConfigMergeFcn
@@ -645,7 +657,8 @@ func MergeUrl(serviceUrl *URL, referenceUrl *URL) *URL {
 			fcn("methods." + method)
 		}
 	}
-
+	// In this way, we will raise some performance.
+	mergedUrl.ReplaceParams(params)
 	return mergedUrl
 }
 
@@ -737,15 +750,15 @@ func IsEquals(left *URL, right *URL, excludes ...string) bool {
 	return true
 }
 
-func mergeNormalParam(mergedUrl *URL, referenceUrl *URL, paramKeys []string) []func(method string) {
+func mergeNormalParam(params url.Values, referenceUrl *URL, paramKeys []string) []func(method string) {
 	methodConfigMergeFcn := make([]func(method string), 0, len(paramKeys))
 	for _, paramKey := range paramKeys {
 		if v := referenceUrl.GetParam(paramKey, ""); len(v) > 0 {
-			mergedUrl.SetParam(paramKey, v)
+			params[paramKey] = []string{v}
 		}
 		methodConfigMergeFcn = append(methodConfigMergeFcn, func(method string) {
 			if v := referenceUrl.GetParam(method+"."+paramKey, ""); len(v) > 0 {
-				mergedUrl.SetParam(method+"."+paramKey, v)
+				params[method+"."+paramKey] = []string{v}
 			}
 		})
 	}
diff --git a/common/url_test.go b/common/url_test.go
index 05377c1..056e067 100644
--- a/common/url_test.go
+++ b/common/url_test.go
@@ -307,6 +307,16 @@ func TestURLSetParams(t *testing.T) {
 	assert.Equal(t, "2.6.0", u1.GetParam("version", ""))
 }
 
+func TestURLReplaceParams(t *testing.T) {
+	u1, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&configVersion=1.0")
+	assert.NoError(t, err)
+	params := url.Values{}
+	params.Set("key", "3")
+	u1.ReplaceParams(params)
+	assert.Equal(t, "3", u1.GetParam("key", ""))
+	assert.Equal(t, "", u1.GetParam("version", ""))
+}
+
 func TestClone(t *testing.T) {
 	u1, err := NewURL("dubbo://127.0.0.1:20000/com.ikurento.user.UserProvider?interface=com.ikurento.user.UserProvider&group=&version=2.6.0&configVersion=1.0")
 	assert.NoError(t, err)