Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: common utils. 包括Md5, PK, PK2, UUID, SortedTags, DictedTagstring等函数 #393

Merged
merged 1 commit into from
Mar 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 50 additions & 6 deletions common/utils/func.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,69 @@
package utils

import (
"fmt"
"bytes"
"strconv"
)

func PK(endpoint, metric string, tags map[string]string) string {
ret := bufferPool.Get().(*bytes.Buffer)
ret.Reset()
defer bufferPool.Put(ret)

if tags == nil || len(tags) == 0 {
return fmt.Sprintf("%s/%s", endpoint, metric)
ret.WriteString(endpoint)
ret.WriteString("/")
ret.WriteString(metric)

return ret.String()
}
return fmt.Sprintf("%s/%s/%s", endpoint, metric, SortedTags(tags))
ret.WriteString(endpoint)
ret.WriteString("/")
ret.WriteString(metric)
ret.WriteString("/")
ret.WriteString(SortedTags(tags))
return ret.String()
}

func PK2(endpoint, counter string) string {
return fmt.Sprintf("%s/%s", endpoint, counter)
ret := bufferPool.Get().(*bytes.Buffer)
ret.Reset()
defer bufferPool.Put(ret)

ret.WriteString(endpoint)
ret.WriteString("/")
ret.WriteString(counter)

return ret.String()
}

func UUID(endpoint, metric string, tags map[string]string, dstype string, step int) string {
ret := bufferPool.Get().(*bytes.Buffer)
ret.Reset()
defer bufferPool.Put(ret)

if tags == nil || len(tags) == 0 {
return fmt.Sprintf("%s/%s/%s/%d", endpoint, metric, dstype, step)
ret.WriteString(endpoint)
ret.WriteString("/")
ret.WriteString(metric)
ret.WriteString("/")
ret.WriteString(dstype)
ret.WriteString("/")
ret.WriteString(strconv.Itoa(step))

return ret.String()
}
return fmt.Sprintf("%s/%s/%s/%s/%d", endpoint, metric, SortedTags(tags), dstype, step)
ret.WriteString(endpoint)
ret.WriteString("/")
ret.WriteString(metric)
ret.WriteString("/")
ret.WriteString(SortedTags(tags))
ret.WriteString("/")
ret.WriteString(dstype)
ret.WriteString("/")
ret.WriteString(strconv.Itoa(step))

return ret.String()
}

func Checksum(endpoint string, metric string, tags map[string]string) string {
Expand Down
123 changes: 123 additions & 0 deletions common/utils/func_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package utils

import (
"fmt"
"testing"
)

func origPK(endpoint, metric string, tags map[string]string) string {
if tags == nil || len(tags) == 0 {
return fmt.Sprintf("%s/%s", endpoint, metric)
}
return fmt.Sprintf("%s/%s/%s", endpoint, metric, SortedTags(tags))
}

func origPK2(endpoint, counter string) string {
return fmt.Sprintf("%s/%s", endpoint, counter)
}

func origUUID(endpoint, metric string, tags map[string]string, dstype string, step int) string {
if tags == nil || len(tags) == 0 {
return fmt.Sprintf("%s/%s/%s/%d", endpoint, metric, dstype, step)
}
return fmt.Sprintf("%s/%s/%s/%s/%d", endpoint, metric, SortedTags(tags), dstype, step)
}

var pkCase = []struct {
endpoint string
metric string
tags map[string]string
except string
}{
{"endpoint1", "metric1", nil, "endpoint1/metric1"},
{"endpoint1", "metric1", map[string]string{}, "endpoint1/metric1"},
{"endpoint1", "metric1", map[string]string{"k1": "v1", "k2": "v2"}, "endpoint1/metric1/k1=v1,k2=v2"},
{"endpoint1", "metric1", map[string]string{"k2": "v2", "k1": "v1"}, "endpoint1/metric1/k1=v1,k2=v2"},
}

var pk2Case = []struct {
endpoint string
counter string
except string
}{
{"endpoint1", "counter1", "endpoint1/counter1"},
}

var uuidCase = []struct {
endpoint string
metric string
tags map[string]string
dstype string
step int
except string
}{
{"endpoint1", "metric1", nil, "ds", 10, "endpoint1/metric1/ds/10"},
{"endpoint1", "metric1", map[string]string{}, "ds", 10, "endpoint1/metric1/ds/10"},
{"endpoint1", "metric1", map[string]string{"k1": "v1", "k2": "v2"}, "ds", 10, "endpoint1/metric1/k1=v1,k2=v2/ds/10"},
{"endpoint1", "metric1", map[string]string{"k2": "v2", "k1": "v1"}, "ds", 10, "endpoint1/metric1/k1=v1,k2=v2/ds/10"},
}

func Test_PK(t *testing.T) {
for _, pk := range pkCase {
if PK(pk.endpoint, pk.metric, pk.tags) != origPK(pk.endpoint, pk.metric, pk.tags) || PK(pk.endpoint, pk.metric, pk.tags) != pk.except {
t.Error("not except")
}
}
}

func Test_PK2(t *testing.T) {
for _, pk2 := range pk2Case {
if PK2(pk2.endpoint, pk2.counter) != origPK2(pk2.endpoint, pk2.counter) || PK2(pk2.endpoint, pk2.counter) != pk2.except {
t.Error("not except")
}
}
}

func Test_UUID(t *testing.T) {
for _, uuid := range uuidCase {
if UUID(uuid.endpoint, uuid.metric, uuid.tags, uuid.dstype, uuid.step) != origUUID(uuid.endpoint, uuid.metric, uuid.tags, uuid.dstype, uuid.step) ||
UUID(uuid.endpoint, uuid.metric, uuid.tags, uuid.dstype, uuid.step) != uuid.except {
t.Error("not except")
}
}
}

var (
testTags = map[string]string{"k1": "v1", "k2": "v2"}
)

func Benchmark_PK(b *testing.B) {
for i := 0; i < b.N; i++ {
PK("endpoint1", "metric1", testTags)
}
}

func Benchmark_PK_orig(b *testing.B) {
for i := 0; i < b.N; i++ {
origPK("endpoint1", "metric1", testTags)
}
}

func Benchmark_PK2(b *testing.B) {
for i := 0; i < b.N; i++ {
PK2("endpoint1", "counter1")
}
}

func Benchmark_PK2_orig(b *testing.B) {
for i := 0; i < b.N; i++ {
origPK2("endpoint1", "counter1")
}
}

func Benchmark_UUID(b *testing.B) {
for i := 0; i < b.N; i++ {
UUID("endpoint1", "metric1", testTags, "dt", 10)
}
}

func Benchmark_UUID_orig(b *testing.B) {
for i := 0; i < b.N; i++ {
origUUID("endpoint1", "metric1", testTags, "dt", 10)
}
}
9 changes: 3 additions & 6 deletions common/utils/md5.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,10 @@ package utils

import (
"crypto/md5"
"fmt"
"io"
"encoding/hex"
)

func Md5(raw string) string {
h := md5.New()
io.WriteString(h, raw)

return fmt.Sprintf("%x", h.Sum(nil))
h := md5.Sum([]byte(raw))
return hex.EncodeToString(h[:])
}
33 changes: 33 additions & 0 deletions common/utils/md5_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package utils

import (
"crypto/md5"
"fmt"
"io"
"testing"
)

func origMd5(raw string) string {
h := md5.New()
io.WriteString(h, raw)

return fmt.Sprintf("%x", h.Sum(nil))
}

func Test_Md5(t *testing.T) {
if Md5("1234567890123") != origMd5("1234567890123") {
t.Error("not expect")
}
}

func Benchmark_Md5(b *testing.B) {
for i := 0; i < b.N; i++ {
Md5("1234567890123")
}
}

func Benchmark_Md5_orig(b *testing.B) {
for i := 0; i < b.N; i++ {
origMd5("1234567890123")
}
}
8 changes: 8 additions & 0 deletions common/utils/objpool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package utils

import (
"bytes"
"sync"
)

var bufferPool = sync.Pool{New: func() interface{} { return new(bytes.Buffer) }}
31 changes: 23 additions & 8 deletions common/utils/tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package utils

import (
"bytes"
"fmt"
"sort"
"strings"
Expand All @@ -31,10 +32,17 @@ func SortedTags(tags map[string]string) string {
return ""
}

ret := bufferPool.Get().(*bytes.Buffer)
ret.Reset()
defer bufferPool.Put(ret)

if size == 1 {
for k, v := range tags {
return fmt.Sprintf("%s=%s", k, v)
ret.WriteString(k)
ret.WriteString("=")
ret.WriteString(v)
}
return ret.String()
}

keys := make([]string, size)
Expand All @@ -46,26 +54,33 @@ func SortedTags(tags map[string]string) string {

sort.Strings(keys)

ret := make([]string, size)
for j, key := range keys {
ret[j] = fmt.Sprintf("%s=%s", key, tags[key])
ret.WriteString(key)
ret.WriteString("=")
ret.WriteString(tags[key])
if j != size-1 {
ret.WriteString(",")
}
}

return strings.Join(ret, ",")
return ret.String()
}

func DictedTagstring(s string) map[string]string {
if s == "" {
return map[string]string{}
}
s = strings.Replace(s, " ", "", -1)

if strings.ContainsRune(s, ' ') {
s = strings.Replace(s, " ", "", -1)
}

tag_dict := make(map[string]string)
tags := strings.Split(s, ",")
for _, tag := range tags {
tag_pair := strings.SplitN(tag, "=", 2)
if len(tag_pair) == 2 {
tag_dict[tag_pair[0]] = tag_pair[1]
idx := strings.IndexRune(tag, '=')
if idx != -1 {
tag_dict[tag[:idx]] = tag[idx+1:]
}
}
return tag_dict
Expand Down
Loading