Skip to content

Commit

Permalink
优化 pandora key convert
Browse files Browse the repository at this point in the history
  • Loading branch information
李红 authored and 李红 committed Jul 20, 2018
1 parent b7c0b57 commit 6a867c7
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 21 deletions.
2 changes: 1 addition & 1 deletion reader/cloudwatch/cloudwatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ func formatKey(metricName string, statistic string) string {
}

func snakeCase(s string) string {
s = models.PandoraKey(s)
s, _ = models.PandoraKey(s)
s = strings.Replace(s, "__", "_", -1)
return s
}
Expand Down
73 changes: 58 additions & 15 deletions utils/models/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -752,31 +752,74 @@ func GetMapList(data string) map[string]string {
return ret
}

func PandoraKey(key string) string {
var nk string
for _, c := range key {
// 判断时只有数字和字母为合法字符,规则:
// 1. 首字符为数字时,增加首字符 "K"
// 2. 首字符为非法字符时,去掉首字符(例如,如果字符串全为非法字符,则转换后为空)
// 3. 非首字符并且为非法字符时,使用 "_" 替代非法字符
func PandoraKey(key string) (string, bool) {
// check
valid := true
size := 0
for idx, c := range key {
if c >= '0' && c <= '9' {
if len(nk) == 0 {
nk = "K"
size++
if idx == 0 {
size++
valid = false
}
nk = nk + string(c)
} else if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') {
nk = nk + string(c)
} else if len(nk) > 0 {
nk = nk + "_"
continue
}
if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') {
size++
continue
}

if idx > 0 && size > 0 {
size++
}
valid = false
}
return nk
if valid {
return key, true
}

if size <= 0 {
return "", false
}

// set
bytes := make([]byte, size)
bp := 0
for idx, c := range key {
if c >= '0' && c <= '9' {
if idx == 0 {
bp += copy(bytes, "K")
}
bp += copy(bytes[bp:], string(c))
continue
}
if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') {
bp += copy(bytes[bp:], string(c))
continue
}

if idx > 0 {
bp += copy(bytes[bp:], "_")
}
}
return string(bytes), false
}

func DeepConvertKey(data map[string]interface{}) map[string]interface{} {
newData := make(map[string]interface{})
for k, v := range data {
nk := PandoraKey(k)
nk, valid := PandoraKey(k)
if nv, ok := v.(map[string]interface{}); ok {
v = DeepConvertKey(nv)
}
newData[nk] = v
if !valid {
delete(data, k)
data[nk] = v
}
}
return newData
return data
}
45 changes: 40 additions & 5 deletions utils/models/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,9 +618,44 @@ func TestPickMapValue(t *testing.T) {
func TestPandoraKey(t *testing.T) {
testKeys := []string{"@timestamp", ".dot", "percent%100", "^^^^^^^^^^", "timestamp"}
expectKeys := []string{"timestamp", "dot", "percent_100", "", "timestamp"}
expectValid := []bool{false, false, false, false, true}
for idx, key := range testKeys {
actual := PandoraKey(key)
actual, valid := PandoraKey(key)
assert.Equal(t, expectKeys[idx], actual)
assert.Equal(t, expectValid[idx], valid)
}
}

func BenchmarkPandoraKey(b *testing.B) {
b.ReportAllocs()
testKeys := []string{"@timestamp", ".dot", "percent%100", "^^^^^^^^^^", "timestamp", "aaa"}
for i := 0; i < b.N; i++ {
for _, key := range testKeys {
PandoraKey(key)
}
}
}

func BenchmarkDeepConvertKey(b *testing.B) {
b.ReportAllocs()
testDatas := []map[string]interface{}{
{
"@timestamp": "2018-07-18T10:17:36.549054846+08:00",
//"timestamp": "2018-07-19T10:17:36.549054846+08:00",
},
{
".dot": map[string]interface{}{".dot2": "dot"},
},
{
"dot": map[string]interface{}{".dot2": "dot"},
"percent%100": 100,
"^^^^^^^^^^": "mytest",
},
}
for i := 0; i < b.N; i++ {
for _, data := range testDatas {
DeepConvertKey(data)
}
}
}

Expand All @@ -631,10 +666,10 @@ func TestDeepConvertKey(t *testing.T) {
//"timestamp": "2018-07-19T10:17:36.549054846+08:00",
},
{
".dot": "dot",
".dot": map[string]interface{}{".dot2": "dot"},
},
{
"dot": "dot",
"dot": map[string]interface{}{".dot2": "dot"},
"percent%100": 100,
"^^^^^^^^^^": "mytest",
},
Expand All @@ -644,10 +679,10 @@ func TestDeepConvertKey(t *testing.T) {
"timestamp": "2018-07-18T10:17:36.549054846+08:00",
},
{
"dot": "dot",
"dot": map[string]interface{}{"dot2": "dot"},
},
{
"dot": "dot",
"dot": map[string]interface{}{"dot2": "dot"},
"percent_100": 100,
"": "mytest",
},
Expand Down

0 comments on commit 6a867c7

Please sign in to comment.