diff --git a/g/container/gvar/gvar_bench_test.go b/g/container/gvar/gvar_z_bench_test.go similarity index 100% rename from g/container/gvar/gvar_bench_test.go rename to g/container/gvar/gvar_z_bench_test.go diff --git a/g/os/gcfg/gcfg.go b/g/os/gcfg/gcfg.go index c18fff811..f031e574a 100644 --- a/g/os/gcfg/gcfg.go +++ b/g/os/gcfg/gcfg.go @@ -63,8 +63,13 @@ func (c *Config) filePath(file...string) (path string) { } c.paths.RLockFunc(func(array []string) { for _, v := range array { + //fmt.Println("search:", v, name) if path, _ = gspath.Search(v, name); path != "" { break + } else { + //if strings.EqualFold(v, "/Users/john/Temp/config") { + // gutil.Dump(gspath.Get(v).AllPaths()) + //} } } }) diff --git a/g/os/glog/glog_logger.go b/g/os/glog/glog_logger.go index 2e273b3c5..99a0c8877 100644 --- a/g/os/glog/glog_logger.go +++ b/g/os/glog/glog_logger.go @@ -8,6 +8,7 @@ package glog import ( + "errors" "fmt" "gitee.com/johng/gf/g/container/gtype" "gitee.com/johng/gf/g/os/gfile" @@ -160,6 +161,10 @@ func (l *Logger) getFilePointer() *gfpool.File { // 设置日志文件的存储目录路径 func (l *Logger) SetPath(path string) error { + // path必须有值 + if path == "" { + return errors.New("path is empty") + } // 如果目录不存在,则递归创建 if !gfile.Exists(path) { if err := gfile.Mkdir(path); err != nil { diff --git a/g/os/gspath/gspath.go b/g/os/gspath/gspath.go index fa228acfe..b524631be 100644 --- a/g/os/gspath/gspath.go +++ b/g/os/gspath/gspath.go @@ -47,7 +47,9 @@ func New(path...string) *SPath { cache : gmap.NewStringStringMap(), } if len(path) > 0 { - sp.Add(path[0]) + if _, err := sp.Add(path[0]); err != nil { + //fmt.Errorf(err.Error()) + } } return sp } @@ -111,6 +113,7 @@ func (sp *SPath) Add(path string) (realPath string, err error) { } // 添加的搜索路径必须为目录 if gfile.IsDir(realPath) { + //fmt.Println("gspath:", realPath, sp.paths.Search(realPath)) // 如果已经添加则不再添加 if sp.paths.Search(realPath) < 0 { realPath = strings.TrimRight(realPath, gfile.Separator) @@ -223,9 +226,12 @@ func (sp *SPath) addToCache(filePath, rootPath string) { // 如果添加的是目录,那么需要递归添加 if idDir { if files, err := gfile.ScanDir(filePath, "*", true); err == nil { + //fmt.Println("gspath add to cache:", filePath, files) for _, path := range files { sp.cache.SetIfNotExist(sp.nameFromPath(path, rootPath), sp.makeCacheValue(path, gfile.IsDir(path))) } + } else { + //fmt.Errorf(err.Error()) } } } diff --git a/g/os/gtime/gtime.go b/g/os/gtime/gtime.go index 5d6df5486..16cf43856 100644 --- a/g/os/gtime/gtime.go +++ b/g/os/gtime/gtime.go @@ -12,7 +12,6 @@ package gtime import ( "errors" "gitee.com/johng/gf/g/string/gregex" - "gitee.com/johng/gf/g/string/gstr" "regexp" "strconv" "strings" @@ -137,7 +136,7 @@ func parseDateStr(s string) (year, month, day int) { return } // 判断年份在开头还是末尾 - if gstr.IsNumeric(array[1]) { + if isNumeric(array[1]) { year, _ = strconv.Atoi(array[0]) month, _ = strconv.Atoi(array[1]) day, _ = strconv.Atoi(array[2]) @@ -307,4 +306,18 @@ func FuncCost(f func()) int64 { t := Nanosecond() f() return Nanosecond() - t +} + +// 判断锁给字符串是否为数字 +func isNumeric(s string) bool { + length := len(s) + if length == 0 { + return false + } + for i := 0; i < len(s); i++ { + if s[i] < byte('0') || s[i] > byte('9') { + return false + } + } + return true } \ No newline at end of file diff --git a/g/os/gtime/gtime_test.go b/g/os/gtime/gtime_z_bench_test.go similarity index 100% rename from g/os/gtime/gtime_test.go rename to g/os/gtime/gtime_z_bench_test.go diff --git a/g/string/gregex/gregex.go b/g/string/gregex/gregex.go index 10b2ddb1d..6959a855b 100644 --- a/g/string/gregex/gregex.go +++ b/g/string/gregex/gregex.go @@ -10,26 +10,9 @@ package gregex import ( - "gitee.com/johng/gf/g/container/gmap" "regexp" ) -// 缓存对象,主要用于缓存底层regx对象 -var regxCache = gmap.NewStringInterfaceMap() - -// 根据pattern生成对应的regexp正则对象 -func getRegexp(pattern string) (*regexp.Regexp, error) { - if v := regxCache.Get(pattern); v != nil { - return v.(*regexp.Regexp), nil - } - if r, err := regexp.Compile(pattern); err == nil { - regxCache.Set(pattern, r) - return r, nil - } else { - return nil, err - } -} - // 转移正则规则字符串,例如:Quote(`[foo]`) 返回 `\[foo\]` func Quote(s string) string { return regexp.QuoteMeta(s) diff --git a/g/string/gregex/gregex_cache.go b/g/string/gregex/gregex_cache.go new file mode 100644 index 000000000..ead3f49f6 --- /dev/null +++ b/g/string/gregex/gregex_cache.go @@ -0,0 +1,46 @@ +// Copyright 2019 gf Author(https://gitee.com/johng/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://gitee.com/johng/gf. + +package gregex + +import ( + "regexp" + "sync" +) + +// 缓存对象,主要用于缓存底层regx对象 +var ( + regexMu = sync.RWMutex{} + regexMap = make(map[string]*regexp.Regexp) +) + +// 根据pattern生成对应的regexp正则对象 +func getRegexp(pattern string) (*regexp.Regexp, error) { + if r := getCache(pattern); r != nil { + return r, nil + } + if r, err := regexp.Compile(pattern); err == nil { + setCache(pattern, r) + return r, nil + } else { + return nil, err + } +} + +// 获得正则缓存对象 +func getCache(pattern string) (regex *regexp.Regexp) { + regexMu.RLock() + regex = regexMap[pattern] + regexMu.RUnlock() + return +} + +// 设置正则缓存对象 +func setCache(pattern string, regex *regexp.Regexp) { + regexMu.Lock() + regexMap[pattern] = regex + regexMu.Unlock() +} diff --git a/g/test/gtest/gtest.go b/g/test/gtest/gtest.go index 1ee4667e2..e5bb4dad9 100644 --- a/g/test/gtest/gtest.go +++ b/g/test/gtest/gtest.go @@ -33,24 +33,15 @@ func Case(t *testing.T, f func()) { // 断言判断, 相等 func Assert(value, expect interface{}) { - rvValue := reflect.ValueOf(value) - rvExpect := reflect.ValueOf(expect) + rvValue := reflect.ValueOf(value) if rvValue.Kind() == reflect.Ptr { if rvValue.IsNil() { value = nil } } - //if rvExpect.Kind() == reflect.Map { - // if rvValue.Kind() == reflect.Map { - // ksExpect := rvExpect.MapKeys() - // for _, k := range ksExpect { - // rvValue.M.MapIndex() - // m[String(k.Interface())] = rv.MapIndex(k).Interface() - // } - // } else { - // panic(fmt.Sprint(`[ASSERT] EXPECT VALUE TO BE A MAP`)) - // } - //} + if err := compareMap(value, expect); err != nil { + panic(err) + } if fmt.Sprintf("%v", value) != fmt.Sprintf("%v", expect) { panic(fmt.Sprintf(`[ASSERT] EXPECT %v == %v`, value, expect)) } @@ -64,12 +55,34 @@ func AssertEQ(value, expect interface{}) { if t1 != t2 { panic(fmt.Sprintf(`[ASSERT] EXPECT TYPE %v == %v`, t1, t2)) } - rv := reflect.ValueOf(value) - if rv.Kind() == reflect.Ptr { - if rv.IsNil() { + rvValue := reflect.ValueOf(value) + rvExpect := reflect.ValueOf(expect) + if rvValue.Kind() == reflect.Ptr { + if rvValue.IsNil() { value = nil } } + // map类型比较 + if rvExpect.Kind() == reflect.Map { + if rvValue.Kind() == reflect.Map { + if rvExpect.Len() == rvValue.Len() { + ksExpect := rvExpect.MapKeys() + for _, key := range ksExpect { + if rvValue.MapIndex(key).Interface() != rvExpect.MapIndex(key).Interface() { + panic(fmt.Sprintf(`[ASSERT] EXPECT VALUE map["%v"]:%v == %v`, + key, + rvValue.MapIndex(key).Interface(), + rvExpect.MapIndex(key).Interface(), + )) + } + } + } else { + panic(fmt.Sprintf(`[ASSERT] EXPECT MAP LENGTH %d == %d`, rvExpect.Len(), rvValue.Len())) + } + } else { + panic(fmt.Sprint(`[ASSERT] EXPECT VALUE TO BE A MAP`)) + } + } if fmt.Sprintf("%v", value) != fmt.Sprintf("%v", expect) { panic(fmt.Sprintf(`[ASSERT] EXPECT %v == %v`, value, expect)) } @@ -77,9 +90,9 @@ func AssertEQ(value, expect interface{}) { // 断言判断, 不相等 func AssertNE(value, expect interface{}) { - rv := reflect.ValueOf(value) - if rv.Kind() == reflect.Ptr { - if rv.IsNil() { + rvValue := reflect.ValueOf(value) + if rvValue.Kind() == reflect.Ptr { + if rvValue.IsNil() { value = nil } } @@ -220,6 +233,38 @@ func Fatal(message...interface{}) { os.Exit(1) } +// Map比较,如果相等返回nil,否则返回错误信息. +func compareMap(value, expect interface{}) error { + rvValue := reflect.ValueOf(value) + rvExpect := reflect.ValueOf(expect) + if rvValue.Kind() == reflect.Ptr { + if rvValue.IsNil() { + value = nil + } + } + if rvExpect.Kind() == reflect.Map { + if rvValue.Kind() == reflect.Map { + if rvExpect.Len() == rvValue.Len() { + ksExpect := rvExpect.MapKeys() + for _, key := range ksExpect { + if rvValue.MapIndex(key).Interface() != rvExpect.MapIndex(key).Interface() { + return fmt.Errorf(`[ASSERT] EXPECT VALUE map["%v"]:%v == %v`, + key, + rvValue.MapIndex(key).Interface(), + rvExpect.MapIndex(key).Interface(), + ) + } + } + } else { + return fmt.Errorf(`[ASSERT] EXPECT MAP LENGTH %d == %d`, rvExpect.Len(), rvValue.Len()) + } + } else { + return fmt.Errorf(`[ASSERT] EXPECT VALUE TO BE A MAP`) + } + } + return nil +} + // 获取文件调用回溯字符串,参数skip表示调用端往上多少级开始回溯 func getBacktrace(skip...int) string { customSkip := 0 diff --git a/geg/other/test.go b/geg/other/test.go index d5cfc1631..5a4f07625 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,10 +1,10 @@ package main import ( - "fmt" - "gitee.com/johng/gf/g/string/gstr" + "gitee.com/johng/gf/g/os/gspath" + "gitee.com/johng/gf/g/util/gutil" ) func main() { - fmt.Println(gstr.PosI("abcdEfg", "eF", 0)) + gutil.Dump(gspath.Get("/Users/john/Temp/config").AllPaths()) } \ No newline at end of file