From fbd8bf9d18e96d819937ec4fb74dc8f2bb6f4dbb Mon Sep 17 00:00:00 2001 From: John Date: Fri, 19 Jan 2018 15:26:28 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/encoding/gjson/gjson.go | 18 +- g/encoding/gjson/internal/gjson.go | 443 ----------------------------- g/encoding/gxml/gxml.go | 31 ++ g/frame/gcfg/gcfg.go | 28 +- geg/database/mysql/mysql.go | 4 +- geg/other/test.go | 50 +++- 6 files changed, 118 insertions(+), 456 deletions(-) delete mode 100644 g/encoding/gjson/internal/gjson.go create mode 100644 g/encoding/gxml/gxml.go diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index 98196ad34..96df83bf9 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -13,6 +13,9 @@ import ( "io/ioutil" "encoding/json" "gitee.com/johng/gf/g/util/gconv" + "gitee.com/johng/gf/g/os/gfile" + "errors" + "gitee.com/johng/gf/g/encoding/gxml" ) // json解析结果存放数组 @@ -39,7 +42,7 @@ func Decode (b []byte) (interface{}, error) { } } -// 解析json字符串为go变量,注意第二个参数为指针 +// 解析json字符串为go变量,注意第二个参数为指针(任意结构的变量) func DecodeTo (b []byte, v interface{}) error { return json.Unmarshal(b, v) } @@ -53,13 +56,22 @@ func DecodeToJson (b []byte) (*Json, error) { } } -// 加载json文件内容,并转换为json对象 +// 支持多种配置文件类型转换为json格式内容并解析为gjson.Json对象 +// 支持的配置文件格式:xml, json, yml func Load (path string) (*Json, error) { + var result interface{} data, err := ioutil.ReadFile(path) if err != nil { return nil, err } - var result interface{} + switch gfile.Ext(path) { + case ".xml": + data, err = gxml.ToJson(data) + if err != nil { + return nil, err + } + case ".yml": + } if err := json.Unmarshal(data, &result); err != nil { return nil, err } diff --git a/g/encoding/gjson/internal/gjson.go b/g/encoding/gjson/internal/gjson.go deleted file mode 100644 index 362fa1a17..000000000 --- a/g/encoding/gjson/internal/gjson.go +++ /dev/null @@ -1,443 +0,0 @@ -// Copyright 2017 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 internal - -import ( - "fmt" - "errors" - "strings" - "strconv" -) - -// 这是一个自己开发的,使用go进行json语法解析的解析器,效率没有官方的json解析高,仅作学习参考 - -const ( - gJSON_CHAR_BRACE_LEFT = rune('{') - gJSON_CHAR_BRACE_RIGHT = rune('}') - gJSON_CHAR_BRACKET_LEFT = rune('[') - gJSON_CHAR_BRACKET_RIGHT = rune(']') - gJSON_CHAR_QUOTATION = rune('\\') - gJSON_CHAR_COMMA = rune(',') - gJSON_CHAR_COLON = rune(':') - gJSON_CHAR_DOUBLE_QUOTE_MARK = rune('"') -) - -const ( - gJSON_TOKEN_BRACE_LEFT = rune('{') - gJSON_TOKEN_BRACE_RIGHT = rune('}') - gJSON_TOKEN_BRACKET_LEFT = rune('[') - gJSON_TOKEN_BRACKET_RIGHT = rune(']') - gJSON_TOKEN_COMMA = rune(',') - gJSON_TOKEN_COLON = rune(':') - gJSON_TOKEN_STRING = rune('"') - gJSON_TOKEN_NUMBER = rune('0') -) - -// json关联数组(哈希表) -type JsonMap map[string]interface{} -// json索引数组(普通数组,从0开始索引) -type JsonArray []interface{} - -// JSON数据对象 -type gJsonNode struct { - m JsonMap - a JsonArray -} - -// JSON语义token -type gJsonToken struct { - token []rune // token字符串 - tokenType rune // token类型 - tokenindex int // token在原始字符串中的索引位置 -} - -// JSON解析结构对象 -type gJsonParser struct { - content []rune // 需要解析json字符串(通过string转换为[]rune) - tokens []gJsonToken // 存放解析content后的json token数组 - root *gJsonNode // json根节点 - pointer *gJsonNode // 指向当前正在解析的json节点 -} - -// 解析json字符串 -func Decode(j *string) (*gJsonParser, error) { - p := &gJsonParser{content:[]rune(*j)} - err := p.parse() - if err == nil { - return p, err - } else { - return nil, err - } -} - -// 判断所给字符串是否为数字 -func isNumeric(s string) bool { - for i :=0; i < len(s); i++ { - if s[i] < byte('0') || s[i] > byte('9') { - return false - } - } - return true -} - -// 获得一个键值对关联数组/哈希表,方便操作,不需要自己做类型转换 -// 注意,如果获取的值不存在,或者类型与json类型不匹配,那么将会返回nil -func (p *gJsonParser) GetMap(pattern string) JsonMap { - result := p.Get(pattern) - if result != nil { - if r, ok := result.(JsonMap); ok { - return r - } - } - return nil -} - -// 获得一个数组[]interface{},方便操作,不需要自己做类型转换 -// 注意,如果获取的值不存在,或者类型与json类型不匹配,那么将会返回nil -func (p *gJsonParser) GetArray(pattern string) JsonArray { - result := p.Get(pattern) - if result != nil { - if r, ok := result.(JsonArray); ok { - return r - } - } - return nil -} - - -// 根据约定字符串方式访问json解析数据,参数形如: "items.name.first", "list.0" -// 返回的结果类型的interface{},因此需要自己做类型转换 -// 如果找不到对应节点的数据,返回nil -func (p *gJsonParser) Get(pattern string) interface{} { - var result interface{} - pointer := p.root - array := strings.Split(pattern, ".") - length := len(array) - for i:= 0; i < length; i++ { - // 优先判断数组 - if isNumeric(array[i]) { - n, err := strconv.Atoi(array[i]) - if err == nil && len(pointer.a) > n { - if i == length - 1 { - result = pointer.a[n] - break; - } else { - if p, ok := pointer.a[n].(*gJsonNode); ok { - pointer = p - continue - } - } - } - } - // 其次判断哈希表,如果一个键在数组及map中均不存在,直接返回nil - if v, ok := pointer.m[array[i]]; ok { - if i == length - 1 { - result = v - } else { - if p, ok := v.(*gJsonNode); ok { - pointer = p - continue - } - } - } else { - return nil - } - } - // 处理结果,如果是gJsonNode类型,那么需要做转换 - if r, ok := result.(*gJsonNode); ok { - if len(r.m) < 1 { - return r.a - } else { - return r.m - } - } - return result -} - -// 遍历json字符串数组,并且判断转义 -func (p *gJsonParser) getNextChar(c rune, f int) int { - for i := f + 1; i < len(p.content); i++ { - if p.content[i] == c { - if i > 0 && p.content[i - 1] != gJSON_CHAR_QUOTATION { - return i - } - } else { - switch p.content[i] { - case gJSON_CHAR_DOUBLE_QUOTE_MARK: - r := p.getNextChar(gJSON_CHAR_DOUBLE_QUOTE_MARK, i) - if r > 0 { - i = r - } - } - } - } - return 0 -} - -// 判断字符是否为数字 -func (p *gJsonParser) isCharNumber(c rune) bool { - if c >= rune('0') && c <= rune('9') { - return true - } - return false -} - -// 按照json语法对保存的字符串进行解析 -func (p *gJsonParser) parse() error { - // 首先将字符串解析成token进行保存 - for i := 0; i < len(p.content); i++ { - if p.isCharNumber(p.content[i]) { - j := i + 1 - for ; j < len(p.content); j++ { - if !p.isCharNumber(p.content[j]) { - break; - } - } - p.tokens = append(p.tokens, gJsonToken { - token: p.content[i:j], - tokenType: gJSON_TOKEN_NUMBER, - tokenindex: i, - }) - i = j - 1 - } else { - switch p.content[i] { - case gJSON_CHAR_DOUBLE_QUOTE_MARK: - r := p.getNextChar(gJSON_CHAR_DOUBLE_QUOTE_MARK, i) - if r > 0 { - // 注意这里需要去掉字符串两边的双引号 - p.tokens = append(p.tokens, gJsonToken { - token: p.content[i+1:r], - tokenType: gJSON_TOKEN_STRING, - tokenindex: i, - }) - i = r - } - case gJSON_CHAR_COLON: - p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_COLON, tokenindex: i}) - case gJSON_CHAR_COMMA: - p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_COMMA, tokenindex: i}) - case gJSON_CHAR_BRACE_LEFT: - p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_BRACE_LEFT, tokenindex: i}) - case gJSON_CHAR_BRACE_RIGHT: - p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_BRACE_RIGHT, tokenindex: i}) - case gJSON_CHAR_BRACKET_LEFT: - p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_BRACKET_LEFT, tokenindex: i}) - case gJSON_CHAR_BRACKET_RIGHT: - p.tokens = append(p.tokens, gJsonToken{token: p.content[i:i+1], tokenType: gJSON_TOKEN_BRACKET_RIGHT, tokenindex: i}) - - default: - c := string(p.content[i]) - if c != " " && c != "\r" && c != "\n" && c != "\t" { - return errors.New(fmt.Sprintf("json parse error: invalid char '%s' at index %d", c, i)) - } - } - } - } - // 最后对解析后的token转换为go变量 - return p.parseTokenNodeToVar(0, len(p.tokens) - 1) -} - -// 获取json范围字符包含范围最右侧的索引位置 -func (p *gJsonParser)getTokenBorderRightIndex(token rune, from int) int { - switch token { - case gJSON_TOKEN_BRACE_LEFT: - leftCount := 0 - for i := from + 1; i < len(p.tokens); i++ { - if p.tokens[i].tokenType == gJSON_TOKEN_BRACE_LEFT { - leftCount ++ - } else if p.tokens[i].tokenType == gJSON_TOKEN_BRACE_RIGHT { - if leftCount < 1 { - return i - } else { - leftCount-- - } - } - } - case gJSON_CHAR_BRACKET_LEFT: - leftCount := 0 - for i := from + 1; i < len(p.tokens); i++ { - if p.tokens[i].tokenType == gJSON_CHAR_BRACKET_LEFT { - leftCount ++ - } else if p.tokens[i].tokenType == gJSON_CHAR_BRACKET_RIGHT { - if leftCount < 1 { - return i - } else { - leftCount-- - } - } - } - } - return 0 -} - -// 将解析过后的json token转换为go变量 -func (p *gJsonParser) parseTokenNodeToVar(left int, right int) error { - //fmt.Println("================================") - //for i := left; i <= right; i++ { - // fmt.Println(string(p.tokens[i].token)) - //} - for i := left; i <= right; i++ { - //fmt.Println(string(p.tokens[i].token)) - switch p.tokens[i].tokenType { - case gJSON_TOKEN_BRACE_LEFT: - fallthrough - case gJSON_TOKEN_BRACKET_LEFT: - node := newJsonNode() - // 判断根节点 - if p.root == nil { - p.root = node - p.pointer = node - } - // 判断层级关系 - borderRight := p.getTokenBorderRightIndex(p.tokens[i].tokenType, i) - if borderRight < 1 { - return errors.New(fmt.Sprintf("json parse error: unclosed tag '%s' at index %d", string(p.tokens[i].token), p.tokens[i].tokenindex)) - } - if i > 1 && ( - p.tokens[i-1].tokenType == gJSON_TOKEN_COLON && - p.tokens[i-2].tokenType == gJSON_TOKEN_STRING) { - // json赋值操作 - oldptr := p.pointer - k := string(p.tokens[i-2].token) - p.pointer.m[k] = node - p.pointer = node - err := p.parseTokenNodeToVar(i + 1, borderRight - 1) - if err != nil { - return err - } else { - i = borderRight - p.pointer = oldptr - } - - } else if i > 0 && ( - p.tokens[i-1].tokenType == gJSON_TOKEN_COMMA || - p.tokens[i-1].tokenType == gJSON_TOKEN_BRACE_LEFT || - p.tokens[i-1].tokenType == gJSON_TOKEN_BRACKET_LEFT) { - // json数组操作 - oldptr := p.pointer - p.pointer.a = append(p.pointer.a, node) - p.pointer = node - err := p.parseTokenNodeToVar(i + 1, borderRight - 1) - if err != nil { - return err - } else { - i = borderRight - p.pointer = oldptr - } - } else { - // json层级关系 - p.pointer = node - err := p.parseTokenNodeToVar(i + 1, borderRight - 1) - if err != nil { - return err - } else { - i = borderRight - } - } - - case gJSON_TOKEN_STRING: - fallthrough - case gJSON_TOKEN_NUMBER: - if i > 0 && p.tokens[i-1].tokenType == gJSON_TOKEN_COLON { - k := string(p.tokens[i-2].token) - v := string(p.tokens[i].token) - p.pointer.m[k] = v - } else if p.tokens[i+1].tokenType != gJSON_TOKEN_COLON { - p.pointer.a = append(p.pointer.a, string(p.tokens[i].token)) - } - - case gJSON_TOKEN_COLON: - if i < 1 || (p.tokens[i-1].tokenType != gJSON_TOKEN_STRING) { - return errors.New(fmt.Sprintf("json parse error: invalid charactar '%s' at index %d", string(p.tokens[i].token), p.tokens[i].tokenindex)) - } - - case gJSON_TOKEN_COMMA: - if (p.tokens[i+1].tokenType != gJSON_TOKEN_STRING && - p.tokens[i+1].tokenType != gJSON_TOKEN_NUMBER && - p.tokens[i+1].tokenType != gJSON_TOKEN_BRACE_LEFT && - p.tokens[i+1].tokenType != gJSON_TOKEN_BRACKET_LEFT) || - (i < 1 || ( - p.tokens[i-1].tokenType != gJSON_TOKEN_STRING && - p.tokens[i-1].tokenType != gJSON_TOKEN_NUMBER && - p.tokens[i-1].tokenType != gJSON_TOKEN_BRACE_RIGHT && - p.tokens[i-1].tokenType != gJSON_TOKEN_BRACKET_RIGHT)) { - return errors.New(fmt.Sprintf("json parse error: invalid charactar '%s' at index %d", string(p.tokens[i].token), p.tokens[i].tokenindex)) - } - } - } - return nil -} - -// 打印出所有的token(测试用) -func (p *gJsonParser)printTokens() { - for _, v := range p.tokens { - fmt.Println(string(v.token)) - } -} - -// 格式化打印根节点 -func (p *gJsonParser)Print() { - if len(p.root.m) > 0 { - fmt.Println("{") - } else { - fmt.Println("[") - } - p.printNode(p.pointer, "\t") - if len(p.root.m) > 0 { - fmt.Println("}") - } else { - fmt.Println("]") - } -} - -// 格式化打印根节点 -func (p *gJsonParser)printNode(n *gJsonNode, indent string) { - if len(n.m) > 0 { - for k, v := range n.m { - if t, ok := v.(*gJsonNode); ok { - if len(t.m) > 0 { - fmt.Printf("%v%v\t: {\n", indent, k) - p.printNode(t, indent + "\t") - fmt.Printf("%v}\n", indent) - } else { - fmt.Printf("%v%v\t: [\n", indent, k) - p.printNode(t, indent + "\t") - fmt.Printf("%v}\n", indent) - } - } else { - fmt.Printf("%v%v\t: %v\n", indent, k, v) - } - } - } - if len(n.a) > 0 { - for k, v := range n.a { - if t, ok := v.(*gJsonNode); ok { - if len(t.m) > 0 { - fmt.Printf("%v%v\t: {\n", indent, k) - p.printNode(t, indent + "\t") - fmt.Printf("%v}\n", indent) - } else { - fmt.Printf("%v%v\t: [\n", indent, k) - p.printNode(t, indent + "\t") - fmt.Printf("%v}\n", indent) - } - } else { - fmt.Printf("%v%v : %v\n", indent, k, v) - } - } - } -} - -// 创建一个json数据对象 -func newJsonNode() *gJsonNode { - return &gJsonNode { - m: make(map[string]interface{}), - a: make([]interface{}, 0), - } -} - diff --git a/g/encoding/gxml/gxml.go b/g/encoding/gxml/gxml.go new file mode 100644 index 000000000..b54b7916a --- /dev/null +++ b/g/encoding/gxml/gxml.go @@ -0,0 +1,31 @@ +// Copyright 2017 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. + +// XML +package gxml + +import ( + "github.com/clbanning/mxj" +) + +// 将XML内容解析为map变量 +func Decode(xmlbyte []byte) (map[string]interface{}, error) { + return mxj.NewMapXml(xmlbyte) +} + +// 将map变量解析为XML格式内容 +func Encode(v map[string]interface{}) ([]byte, error) { + return mxj.Map(v).Xml() +} + +// XML格式内容直接转换为JSON格式内容 +func ToJson(xmlbyte []byte) ([]byte, error) { + if mv, err := mxj.NewMapXml(xmlbyte); err == nil { + return mv.Json() + } else { + return nil, err + } +} \ No newline at end of file diff --git a/g/frame/gcfg/gcfg.go b/g/frame/gcfg/gcfg.go index 0c85405c8..aaef0f8f3 100644 --- a/g/frame/gcfg/gcfg.go +++ b/g/frame/gcfg/gcfg.go @@ -16,7 +16,7 @@ import ( ) const ( - gDEFAULT_CONFIG_FILE = "config" // 默认的配置管理文件名称 + gDEFAULT_CONFIG_FILE = "config.json" // 默认的配置管理文件名称 ) // 配置管理对象 @@ -43,7 +43,7 @@ func (c *Config) filePath(files []string) string { c.mu.RLock() fpath := c.path + gfile.Separator + file c.mu.RUnlock() - return fpath + ".json" + return fpath } // 设置配置管理器的配置文件存放目录绝对路径 @@ -111,6 +111,14 @@ func (c *Config) GetBool(pattern string, files...string) bool { return false } +// 返回指定json中的float32 +func (c *Config) GetFloat32(pattern string, files...string) float32 { + if j := c.getJson(files); j != nil { + return j.GetFloat32(pattern) + } + return 0 +} + // 返回指定json中的float64 func (c *Config) GetFloat64(pattern string, files...string) float64 { if j := c.getJson(files); j != nil { @@ -121,10 +129,16 @@ func (c *Config) GetFloat64(pattern string, files...string) float64 { // 返回指定json中的float64->int func (c *Config) GetInt(pattern string, files...string) int { - return int(c.GetFloat64(pattern)) + if j := c.getJson(files); j != nil { + return j.GetInt(pattern) + } + return 0 } -// 返回指定json中的float64->int64 -func (c *Config) GetInt64(pattern string, files...string) int64 { - return int64(c.GetFloat64(pattern)) -} +// 返回指定json中的float64->uint +func (c *Config) GetUint(pattern string, files...string) uint { + if j := c.getJson(files); j != nil { + return j.GetUint(pattern) + } + return 0 +} \ No newline at end of file diff --git a/geg/database/mysql/mysql.go b/geg/database/mysql/mysql.go index cdd7f15c1..172e57292 100644 --- a/geg/database/mysql/mysql.go +++ b/geg/database/mysql/mysql.go @@ -17,7 +17,7 @@ func init () { Port : "3306", User : "root", Pass : "123456", - Name : "test2", + Name : "test", Type : "mysql", Role : "master", Charset : "utf8", @@ -416,7 +416,7 @@ func main() { //create() //create() //insert() - //query() + query() //replace() //save() //batchInsert() diff --git a/geg/other/test.go b/geg/other/test.go index 154f87dfc..c614d0644 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,8 +2,56 @@ package main import ( "fmt" + "gitee.com/johng/gf/g/encoding/gxml" + "gitee.com/johng/gf/g/os/gfile" ) func main() { - fmt.Printf("%b\n", 123) + //json := gfile.GetBinContents("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/config.json") + //y, err := yaml.JSONToYAML(json) + //fmt.Println(err) + //fmt.Println(string(y)) + // + //j, err := yaml.YAMLToJSON(y) + //fmt.Println(err) + //fmt.Println(string(j)) + + x := ` + + + + Comments for 碎言碎语 + + http://johng.cn + + Fri, 05 Jan 2018 02:56:11 +0000 + hourly + 1 + https://wordpress.org/?v=4.7.3 + + Comment on Go性能优化:string与[ ]byte转换 by John + http://johng.cn/go-optimize-string-bytes/#comment-114 + + Fri, 05 Jan 2018 02:56:11 +0000 + http://johng.cn/?p=3435#comment-114 + + 这篇文章我转自雨痕,由于string和[]byte之间的转换比较常用,所以这篇文章的性能对比才比较惊人。其他基本类型与[]byte这件的转换性能差别不大,struct与[]byte的转换性能差别主要在数据结构设计上,比如socket通信的话,基本都是自己通过二进制转换来组织需要的数据结构。总得来说,在go开发的时候尽量多用二进制参数([]byte)是好的。

+]]>
+
+ + + Comment on 层次不同的人,是很难沟通的 by buhuipao + http://johng.cn/hard-for-communitication-between-different-levels/#comment-105 + + Tue, 19 Sep 2017 09:10:08 +0000 + http://johng.cn/?p=2854#comment-105 + + 博主说得很对,认知很重要。

+]]>
+
+
+
` + + j, _ := gxml.ToJson([]byte(x)) + fmt.Println(string(j)) } \ No newline at end of file From 8ecddef8e68ed43a23dfc39e2d4651d488dacfe2 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 19 Jan 2018 16:19:48 +0800 Subject: [PATCH 2/4] =?UTF-8?q?yaml,xml,json=E6=95=B0=E6=8D=AE=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=B0=81=E8=A3=85=E8=A7=A3=E6=9E=90=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/encoding/gjson/gjson.go | 54 ++++++++++++++++++++++++++++++--------- g/encoding/gxml/gxml.go | 8 ++++-- g/encoding/gyaml/gyaml.go | 27 ++++++++++++++++++++ g/frame/gcfg/gcfg.go | 3 ++- geg/frame/config.xml | 1 + geg/frame/config.yml | 29 +++++++++++++++++++++ geg/other/test.go | 53 +++----------------------------------- 7 files changed, 111 insertions(+), 64 deletions(-) create mode 100644 g/encoding/gyaml/gyaml.go create mode 100644 geg/frame/config.xml create mode 100644 geg/frame/config.yml diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index 96df83bf9..3f028fb9f 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -12,10 +12,10 @@ import ( "strconv" "io/ioutil" "encoding/json" - "gitee.com/johng/gf/g/util/gconv" "gitee.com/johng/gf/g/os/gfile" - "errors" + "gitee.com/johng/gf/g/util/gconv" "gitee.com/johng/gf/g/encoding/gxml" + "gitee.com/johng/gf/g/encoding/gyaml" ) // json解析结果存放数组 @@ -57,20 +57,33 @@ func DecodeToJson (b []byte) (*Json, error) { } // 支持多种配置文件类型转换为json格式内容并解析为gjson.Json对象 -// 支持的配置文件格式:xml, json, yml func Load (path string) (*Json, error) { - var result interface{} data, err := ioutil.ReadFile(path) if err != nil { return nil, err } - switch gfile.Ext(path) { + return LoadContent(data, gfile.Ext(path)) +} + +// 支持的配置文件格式:xml, json, yml +func LoadContent (data []byte, t string) (*Json, error) { + var err error + var result interface{} + switch t { + case "xml": fallthrough case ".xml": data, err = gxml.ToJson(data) if err != nil { return nil, err } - case ".yml": + case "yml": fallthrough + case "yaml": fallthrough + case ".yml": fallthrough + case ".yaml": + data, err = gyaml.ToJson(data) + if err != nil { + return nil, err + } } if err := json.Unmarshal(data, &result); err != nil { return nil, err @@ -201,10 +214,9 @@ func (p *Json) Get(pattern string) interface{} { // 转换为map[string]interface{}类型,如果转换失败,返回nil func (p *Json) ToMap() map[string]interface{} { - pointer := p.value - switch (*pointer).(type) { + switch (*(p.value)).(type) { case map[string]interface{}: - return (*pointer).(map[string]interface{}) + return (*(p.value)).(map[string]interface{}) default: return nil } @@ -212,15 +224,33 @@ func (p *Json) ToMap() map[string]interface{} { // 转换为[]interface{}类型,如果转换失败,返回nil func (p *Json) ToArray() []interface{} { - pointer := p.value - switch (*pointer).(type) { + switch (*(p.value)).(type) { case []interface{}: - return (*pointer).([]interface{}) + return (*(p.value)).([]interface{}) default: return nil } } +func (p *Json) ToXml(rootTag...string) ([]byte, error) { + return gxml.Encode(p.ToMap(), rootTag...) +} + +func (p *Json) ToXmlIndent(rootTag...string) ([]byte, error) { + return gxml.EncodeWithIndent(p.ToMap(), rootTag...) +} + +func (p *Json) ToJson() ([]byte, error) { + return Encode(*(p.value)) +} + +func (p *Json) ToJsonIndent() ([]byte, error) { + return json.MarshalIndent(*(p.value), "", "\t") +} + +func (p *Json) ToYaml() ([]byte, error) { + return gyaml.Encode(*(p.value)) +} // 判断所给字符串是否为数字 func isNumeric(s string) bool { diff --git a/g/encoding/gxml/gxml.go b/g/encoding/gxml/gxml.go index b54b7916a..4a132546b 100644 --- a/g/encoding/gxml/gxml.go +++ b/g/encoding/gxml/gxml.go @@ -17,8 +17,12 @@ func Decode(xmlbyte []byte) (map[string]interface{}, error) { } // 将map变量解析为XML格式内容 -func Encode(v map[string]interface{}) ([]byte, error) { - return mxj.Map(v).Xml() +func Encode(v map[string]interface{}, rootTag...string) ([]byte, error) { + return mxj.Map(v).Xml(rootTag...) +} + +func EncodeWithIndent(v map[string]interface{}, rootTag...string) ([]byte, error) { + return mxj.Map(v).XmlIndent("", "\t", rootTag...) } // XML格式内容直接转换为JSON格式内容 diff --git a/g/encoding/gyaml/gyaml.go b/g/encoding/gyaml/gyaml.go new file mode 100644 index 000000000..356e25d26 --- /dev/null +++ b/g/encoding/gyaml/gyaml.go @@ -0,0 +1,27 @@ +// Copyright 2017 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. + +// YAML +package gyaml + +import "github.com/ghodss/yaml" + +func Encode(v interface{}) ([]byte, error) { + return yaml.Marshal(v) +} + +func Decode(v []byte) error { + var result interface{} + return yaml.Unmarshal(v, &result) +} + +func DecodeTo(v []byte, result interface{}) error { + return yaml.Unmarshal(v, &result) +} + +func ToJson(v []byte) ([]byte, error) { + return yaml.YAMLToJSON(v) +} \ No newline at end of file diff --git a/g/frame/gcfg/gcfg.go b/g/frame/gcfg/gcfg.go index aaef0f8f3..75c2aaeb6 100644 --- a/g/frame/gcfg/gcfg.go +++ b/g/frame/gcfg/gcfg.go @@ -4,7 +4,8 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. -// 配置管理 +// 配置管理. +// 配置文件格式支持:json, xml, yml package gcfg import ( diff --git a/geg/frame/config.xml b/geg/frame/config.xml new file mode 100644 index 000000000..42c1bdf97 --- /dev/null +++ b/geg/frame/config.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/geg/frame/config.yml b/geg/frame/config.yml new file mode 100644 index 000000000..433dcf4a9 --- /dev/null +++ b/geg/frame/config.yml @@ -0,0 +1,29 @@ +{ + "viewpath" : "/home/www/templates/", + "database" : { + "default" : [ + { + "host" : "127.0.0.1", + "port" : "3306", + "user" : "root", + "pass" : "123456", + "name" : "test", + "type" : "mysql", + "role" : "master", + "charset" : "utf8", + "priority" : "1" + }, + { + "host" : "127.0.0.1", + "port" : "3306", + "user" : "root", + "pass" : "123456", + "name" : "test", + "type" : "mysql", + "role" : "master", + "charset" : "utf8", + "priority" : "1" + } + ] + } +} \ No newline at end of file diff --git a/geg/other/test.go b/geg/other/test.go index c614d0644..d04c615bd 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,56 +2,11 @@ package main import ( "fmt" - "gitee.com/johng/gf/g/encoding/gxml" - "gitee.com/johng/gf/g/os/gfile" + "gitee.com/johng/gf/g/encoding/gjson" ) func main() { - //json := gfile.GetBinContents("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/config.json") - //y, err := yaml.JSONToYAML(json) - //fmt.Println(err) - //fmt.Println(string(y)) - // - //j, err := yaml.YAMLToJSON(y) - //fmt.Println(err) - //fmt.Println(string(j)) - - x := ` - - - - Comments for 碎言碎语 - - http://johng.cn - - Fri, 05 Jan 2018 02:56:11 +0000 - hourly - 1 - https://wordpress.org/?v=4.7.3 - - Comment on Go性能优化:string与[ ]byte转换 by John - http://johng.cn/go-optimize-string-bytes/#comment-114 - - Fri, 05 Jan 2018 02:56:11 +0000 - http://johng.cn/?p=3435#comment-114 - - 这篇文章我转自雨痕,由于string和[]byte之间的转换比较常用,所以这篇文章的性能对比才比较惊人。其他基本类型与[]byte这件的转换性能差别不大,struct与[]byte的转换性能差别主要在数据结构设计上,比如socket通信的话,基本都是自己通过二进制转换来组织需要的数据结构。总得来说,在go开发的时候尽量多用二进制参数([]byte)是好的。

-]]>
-
- - - Comment on 层次不同的人,是很难沟通的 by buhuipao - http://johng.cn/hard-for-communitication-between-different-levels/#comment-105 - - Tue, 19 Sep 2017 09:10:08 +0000 - http://johng.cn/?p=2854#comment-105 - - 博主说得很对,认知很重要。

-]]>
-
-
-
` - - j, _ := gxml.ToJson([]byte(x)) - fmt.Println(string(j)) + j, _ := gjson.Load("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/config.json") + c, _ := j.ToXmlIndent("config") + fmt.Println(string(c)) } \ No newline at end of file From 94e859812b469eed75e2ecf12f4eae9e40b90fb4 Mon Sep 17 00:00:00 2001 From: John Date: Fri, 19 Jan 2018 17:48:40 +0800 Subject: [PATCH 3/4] =?UTF-8?q?gcfg=E5=8A=9F=E8=83=BD=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- geg/frame/config.xml | 29 +++++++++++++++++++++++++- geg/frame/config.yml | 49 ++++++++++++++++++-------------------------- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/geg/frame/config.xml b/geg/frame/config.xml index 42c1bdf97..f0dfbf90f 100644 --- a/geg/frame/config.xml +++ b/geg/frame/config.xml @@ -1 +1,28 @@ - \ No newline at end of file + + + /home/www/templates/ + + + 127.0.0.1 + 3306 + root + 123456 + test + master + mysql + utf8 + 1 + + + 127.0.0.1 + 3306 + root + 123456 + test + master + mysql + utf8 + 1 + + + \ No newline at end of file diff --git a/geg/frame/config.yml b/geg/frame/config.yml index 433dcf4a9..c19de3fc7 100644 --- a/geg/frame/config.yml +++ b/geg/frame/config.yml @@ -1,29 +1,20 @@ -{ - "viewpath" : "/home/www/templates/", - "database" : { - "default" : [ - { - "host" : "127.0.0.1", - "port" : "3306", - "user" : "root", - "pass" : "123456", - "name" : "test", - "type" : "mysql", - "role" : "master", - "charset" : "utf8", - "priority" : "1" - }, - { - "host" : "127.0.0.1", - "port" : "3306", - "user" : "root", - "pass" : "123456", - "name" : "test", - "type" : "mysql", - "role" : "master", - "charset" : "utf8", - "priority" : "1" - } - ] - } -} \ No newline at end of file +viewpath: /home/www/templates/ +database: + default: + - host: 127.0.0.1 + port: 3306 + user: root + pass: 123456 + name: test + type: mysql + role: master + priority: 1 + - host: 127.0.0.1 + port: 3306 + user: root + pass: 123456 + name: test + type: mysql + role: master + priority: 1 + From 6081ac78873c44df97b4949459b81808e462d3e0 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 20 Jan 2018 11:09:27 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E7=9A=84=E5=AE=89=E5=85=A8=E9=98=9F=E5=88=97?= =?UTF-8?q?gqueue=EF=BC=8C=E5=B9=B6=E4=BF=AE=E6=AD=A3grpool=E5=85=B3?= =?UTF-8?q?=E9=97=AD=E6=97=B6=E7=9A=84=E6=95=B0=E9=87=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/container/gqueue/int_queue.go | 54 ++++++++++++++++++++++++++ g/container/gqueue/interface_queue.go | 55 +++++++++++++++++++++++++++ g/container/gqueue/string_queue.go | 54 ++++++++++++++++++++++++++ g/container/gqueue/uint_queue.go | 54 ++++++++++++++++++++++++++ g/encoding/gjson/gjson.go | 22 ++++++++--- g/encoding/gtoml/gtoml.go | 42 ++++++++++++++++++++ g/encoding/gyaml/gyaml.go | 7 +++- g/frame/gins/gins.go | 6 +-- g/{frame => os}/gcfg/gcfg.go | 2 +- g/os/grpool/grpool_api.go | 2 +- geg/container/gqueue.go | 32 ++++++++++++++++ geg/other/test.go | 13 +++++-- 12 files changed, 327 insertions(+), 16 deletions(-) create mode 100644 g/container/gqueue/int_queue.go create mode 100644 g/container/gqueue/interface_queue.go create mode 100644 g/container/gqueue/string_queue.go create mode 100644 g/container/gqueue/uint_queue.go create mode 100644 g/encoding/gtoml/gtoml.go rename g/{frame => os}/gcfg/gcfg.go (98%) create mode 100644 geg/container/gqueue.go diff --git a/g/container/gqueue/int_queue.go b/g/container/gqueue/int_queue.go new file mode 100644 index 000000000..794004ee7 --- /dev/null +++ b/g/container/gqueue/int_queue.go @@ -0,0 +1,54 @@ +// Copyright 2017 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 gqueue + +import ( + "math" + "sync" + "container/list" +) + +type IntQueue struct { + mu sync.RWMutex + list *list.List + events chan struct{} +} + +func NewIntQueue() *IntQueue { + return &IntQueue{ + list : list.New(), + events : make(chan struct{}, math.MaxInt64), + } +} + +// 将数据压入队列 +func (q *IntQueue) Push(v int) { + q.mu.Lock() + q.list.PushBack(v) + q.mu.Unlock() + q.events <- struct{}{} +} + +// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 +func (q *IntQueue) Pop() int { + select { + case <- q.events: + q.mu.Lock() + if elem := q.list.Front(); elem != nil { + item := q.list.Remove(elem).(int) + q.mu.Unlock() + return item + } + q.mu.Unlock() + } + return 0 +} + +// 获取当前队列大小 +func (q *IntQueue) Size() int { + return len(q.events) +} \ No newline at end of file diff --git a/g/container/gqueue/interface_queue.go b/g/container/gqueue/interface_queue.go new file mode 100644 index 000000000..7c6122f23 --- /dev/null +++ b/g/container/gqueue/interface_queue.go @@ -0,0 +1,55 @@ +// Copyright 2017 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. + +// 动态大小的安全队列(dynamic channel). +package gqueue + +import ( + "math" + "sync" + "container/list" +) + +type InterfaceQueue struct { + mu sync.RWMutex + list *list.List + events chan struct{} +} + +func NewInterfaceQueue() *InterfaceQueue { + return &InterfaceQueue { + list : list.New(), + events : make(chan struct{}, math.MaxInt64), + } +} + +// 将数据压入队列 +func (q *InterfaceQueue) Push(v interface{}) { + q.mu.Lock() + q.list.PushBack(v) + q.mu.Unlock() + q.events <- struct{}{} +} + +// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 +func (q *InterfaceQueue) Pop() interface{} { + select { + case <- q.events: + q.mu.Lock() + if elem := q.list.Front(); elem != nil { + item := q.list.Remove(elem) + q.mu.Unlock() + return item + } + q.mu.Unlock() + } + return nil +} + +// 获取当前队列大小 +func (q *InterfaceQueue) Size() int { + return len(q.events) +} \ No newline at end of file diff --git a/g/container/gqueue/string_queue.go b/g/container/gqueue/string_queue.go new file mode 100644 index 000000000..fb67c0c0c --- /dev/null +++ b/g/container/gqueue/string_queue.go @@ -0,0 +1,54 @@ +// Copyright 2017 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 gqueue + +import ( + "math" + "sync" + "container/list" +) + +type StringQueue struct { + mu sync.RWMutex + list *list.List + events chan struct{} +} + +func NewStringQueue() *StringQueue { + return &StringQueue{ + list : list.New(), + events : make(chan struct{}, math.MaxInt64), + } +} + +// 将数据压入队列 +func (q *StringQueue) Push(v string) { + q.mu.Lock() + q.list.PushBack(v) + q.mu.Unlock() + q.events <- struct{}{} +} + +// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 +func (q *StringQueue) Pop() string { + select { + case <- q.events: + q.mu.Lock() + if elem := q.list.Front(); elem != nil { + item := q.list.Remove(elem).(string) + q.mu.Unlock() + return item + } + q.mu.Unlock() + } + return "" +} + +// 获取当前队列大小 +func (q *StringQueue) Size() int { + return len(q.events) +} \ No newline at end of file diff --git a/g/container/gqueue/uint_queue.go b/g/container/gqueue/uint_queue.go new file mode 100644 index 000000000..601ffb59e --- /dev/null +++ b/g/container/gqueue/uint_queue.go @@ -0,0 +1,54 @@ +// Copyright 2017 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 gqueue + +import ( + "math" + "sync" + "container/list" +) + +type UintQueue struct { + mu sync.RWMutex + list *list.List + events chan struct{} +} + +func NewUintQueue() *UintQueue { + return &UintQueue{ + list : list.New(), + events : make(chan struct{}, math.MaxInt64), + } +} + +// 将数据压入队列 +func (q *UintQueue) Push(v uint) { + q.mu.Lock() + q.list.PushBack(v) + q.mu.Unlock() + q.events <- struct{}{} +} + +// 先进先出地从队列取出一项数据,当没有数据可获取时,阻塞等待 +func (q *UintQueue) Pop() uint { + select { + case <- q.events: + q.mu.Lock() + if elem := q.list.Front(); elem != nil { + item := q.list.Remove(elem).(uint) + q.mu.Unlock() + return item + } + q.mu.Unlock() + } + return 0 +} + +// 获取当前队列大小 +func (q *UintQueue) Size() int { + return len(q.events) +} \ No newline at end of file diff --git a/g/encoding/gjson/gjson.go b/g/encoding/gjson/gjson.go index 3f028fb9f..3712459b5 100644 --- a/g/encoding/gjson/gjson.go +++ b/g/encoding/gjson/gjson.go @@ -16,6 +16,7 @@ import ( "gitee.com/johng/gf/g/util/gconv" "gitee.com/johng/gf/g/encoding/gxml" "gitee.com/johng/gf/g/encoding/gyaml" + "gitee.com/johng/gf/g/encoding/gtoml" ) // json解析结果存放数组 @@ -65,25 +66,32 @@ func Load (path string) (*Json, error) { return LoadContent(data, gfile.Ext(path)) } -// 支持的配置文件格式:xml, json, yml +// 支持的配置文件格式:xml, json, yaml/yml, toml func LoadContent (data []byte, t string) (*Json, error) { var err error var result interface{} switch t { - case "xml": fallthrough + case "xml": fallthrough case ".xml": data, err = gxml.ToJson(data) if err != nil { return nil, err } - case "yml": fallthrough - case "yaml": fallthrough - case ".yml": fallthrough + case "yml": fallthrough + case "yaml": fallthrough + case ".yml": fallthrough case ".yaml": data, err = gyaml.ToJson(data) if err != nil { return nil, err } + + case "toml": fallthrough + case ".toml": + data, err = gtoml.ToJson(data) + if err != nil { + return nil, err + } } if err := json.Unmarshal(data, &result); err != nil { return nil, err @@ -252,6 +260,10 @@ func (p *Json) ToYaml() ([]byte, error) { return gyaml.Encode(*(p.value)) } +func (p *Json) ToToml() ([]byte, error) { + return gtoml.Encode(*(p.value)) +} + // 判断所给字符串是否为数字 func isNumeric(s string) bool { for i := 0; i < len(s); i++ { diff --git a/g/encoding/gtoml/gtoml.go b/g/encoding/gtoml/gtoml.go new file mode 100644 index 000000000..2e50a4b8a --- /dev/null +++ b/g/encoding/gtoml/gtoml.go @@ -0,0 +1,42 @@ +// Copyright 2017 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. + +// TOML +package gtoml + +import ( + "bytes" + "encoding/json" + "github.com/BurntSushi/toml" +) + +func Encode(v interface{}) ([]byte, error) { + buffer := bytes.NewBuffer(nil) + if err := toml.NewEncoder(buffer).Encode(v); err != nil { + return nil, err + } + return buffer.Bytes(), nil +} + +func Decode(v []byte) (interface{}, error) { + var result interface{} + if err := toml.Unmarshal(v, &result); err != nil { + return nil, err + } + return result, nil +} + +func DecodeTo(v []byte, result interface{}) error { + return toml.Unmarshal(v, result) +} + +func ToJson(v []byte) ([]byte, error) { + if r, err := Decode(v); err != nil { + return nil, err + } else { + return json.Marshal(r) + } +} \ No newline at end of file diff --git a/g/encoding/gyaml/gyaml.go b/g/encoding/gyaml/gyaml.go index 356e25d26..0371b69ec 100644 --- a/g/encoding/gyaml/gyaml.go +++ b/g/encoding/gyaml/gyaml.go @@ -13,9 +13,12 @@ func Encode(v interface{}) ([]byte, error) { return yaml.Marshal(v) } -func Decode(v []byte) error { +func Decode(v []byte) (interface{}, error) { var result interface{} - return yaml.Unmarshal(v, &result) + if err := yaml.Unmarshal(v, &result); err != nil { + return nil, err + } + return result, nil } func DecodeTo(v []byte, result interface{}) error { diff --git a/g/frame/gins/gins.go b/g/frame/gins/gins.go index ef94d27f3..f3288a6b0 100644 --- a/g/frame/gins/gins.go +++ b/g/frame/gins/gins.go @@ -4,18 +4,18 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://gitee.com/johng/gf. -// 单例对象管理. -// 框架内置了一些核心对象,并且可以通过Set和Get方法实现IoC以及对内置核心对象的自定义替换 +// 单例对象管理(耦合了一些框架核心对象获取方法). +// 框架内置了一些核心对象获取方法,并且可以通过Set和Get方法实现IoC以及对内置核心对象的自定义替换 package gins import ( "strconv" + "gitee.com/johng/gf/g/os/gcfg" "gitee.com/johng/gf/g/os/gcmd" "gitee.com/johng/gf/g/os/glog" "gitee.com/johng/gf/g/os/genv" "gitee.com/johng/gf/g/os/gview" "gitee.com/johng/gf/g/os/gfile" - "gitee.com/johng/gf/g/frame/gcfg" "gitee.com/johng/gf/g/database/gdb" "gitee.com/johng/gf/g/container/gmap" ) diff --git a/g/frame/gcfg/gcfg.go b/g/os/gcfg/gcfg.go similarity index 98% rename from g/frame/gcfg/gcfg.go rename to g/os/gcfg/gcfg.go index 75c2aaeb6..9f72aa175 100644 --- a/g/frame/gcfg/gcfg.go +++ b/g/os/gcfg/gcfg.go @@ -5,7 +5,7 @@ // You can obtain one at https://gitee.com/johng/gf. // 配置管理. -// 配置文件格式支持:json, xml, yml +// 配置文件格式支持:json, xml, toml, yaml/yml package gcfg import ( diff --git a/g/os/grpool/grpool_api.go b/g/os/grpool/grpool_api.go index e3d66bd8f..773fabdb1 100644 --- a/g/os/grpool/grpool_api.go +++ b/g/os/grpool/grpool_api.go @@ -56,7 +56,7 @@ func New(expire int, sizes...int) *Pool { funcs : glist.NewSafeList(), freeEvents : make(chan struct{}, math.MaxUint32), funcEvents : make(chan struct{}, math.MaxUint32), - stopEvents : make(chan struct{}, 1), + stopEvents : make(chan struct{}, 2), } p.startWorkLoop() p.startClearLoop() diff --git a/geg/container/gqueue.go b/geg/container/gqueue.go new file mode 100644 index 000000000..f85a62ed3 --- /dev/null +++ b/geg/container/gqueue.go @@ -0,0 +1,32 @@ +package main + +import ( + "fmt" + "gitee.com/johng/gf/g/os/gtime" + "gitee.com/johng/gf/g/container/gqueue" + "time" +) + +func main() { + t := gtime.Microsecond() + q := gqueue.NewInterfaceQueue() + fmt.Println("queue creation costs(μs):", gtime.Microsecond() - t) + + // 每隔2秒异步打印出当前队列的大小 + gtime.SetInterval(2*time.Second, func() bool { + fmt.Println("queue size:", q.Size()) + return true + }) + + // push10条数据 + for i := 0; i < 10; i++ { + q.Push(i) + fmt.Println("push:", i) + } + + // 每隔1秒pop1条数据 + for { + time.Sleep(time.Second) + fmt.Println(" pop:", q.Pop()) + } +} diff --git a/geg/other/test.go b/geg/other/test.go index d04c615bd..6ebb57f03 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,11 +2,16 @@ package main import ( "fmt" - "gitee.com/johng/gf/g/encoding/gjson" ) func main() { - j, _ := gjson.Load("/home/john/Workspace/Go/GOPATH/src/gitee.com/johng/gf/geg/frame/config.json") - c, _ := j.ToXmlIndent("config") - fmt.Println(string(c)) + c1 := make(chan int, 2) + c2 := make(chan int, 5) + c1 <- 1 + c1 <- 2 + c2 = c1 + c2 <- 3 + fmt.Println(<-c2) + fmt.Println(<-c2) + fmt.Println(<-c2) } \ No newline at end of file