mongo高效率引擎轮子总结

  • e := adc.NewEngine()

     新建一个引擎,同时`Setup()`  即开创一个 `sync.Pool`内存池
    
  • func (imp* EngineImp) SetCtx(key string, value interface{}){ imp.ctx.kv[key] = value } 引擎中的属性之一-内存池有个kv(map)属性,把MongoSrcKey = "MongoSrcKey" 加入kv的key中, 数据库db放在kv的value中

  • e.LoadFile("test.adc")

     inp := adcInterpreterPool.Get().(*interpreterImp)
    
    
     加载文件代码块,同时也创建一个 sync.Pool 内存池
    
    
     `loader.clear = true
     loader.braceStack = newBytesStack()
     loader.bracketStack = newBytesStack()
     loader.parenthesisStack = newBytesStack()
     loader.braceBuff = make([]byte, 0)
     loader.bracketBuff = make([]byte, 0)
     loader.parenthesisBuff = make([]byte, 0)
     同时这个interpreterImp 内存池的属性中包含很多buff 和stack  都是[]byte  这一步同时初始化
     `
    
  • loader.fp = f 把文件流放在了interpreterImp 里面的fp属性,然后开始一行行读取文件流

  • 按照line读取文件流 -读取文件的每一行 #(35)除外

func readByLine(f string) [][]byte {
    
    
			r := make([][]byte, 0)
			fi, err := os.Open(f)
			if err != nil {
    
    
				return nil
			}
			defer fi.Close()
		
			br := bufio.NewReader(fi)
			for {
    
    
				l, _, e := br.ReadLine()
				if e != nil {
    
    
					if e == io.EOF {
    
    
						break
					}else {
    
    
						return nil
					}
				}
				if len(l) == 0 {
    
    
					continue
				}

		data := bytes.TrimSpace(l)
		if data[0] == commentPrefix {
    
    
			continue
		}
		r = append(r, utils.CopyBytes(data))
		}
		return r
		}
  • 然后读取每一行的每一个字符,这里是分析标识符 { ( 这些
	for k, v := range data {
    
    
		out.InitRow(k)
		for _, ch := range v {
    
    
			switch ch {
    
    
			case chBraceStart:
				loader.braceStack.push(ch)
				loader.appendChToBuf(ch)
			case chBracketStart:
				loader.bracketStack.push(ch)
				loader.appendChToBuf(ch)
			case chParenthesisStart:
				loader.parenthesisStack.push(ch)
				loader.appendChToBuf(ch)
			case chBraceEnd:
				loader.appendChToBuf(ch)
				if loader.braceStack.getLen() == 0 {
    
    
					return LSSyntaxError
				}
				loader.braceStack.pop()
				if loader.braceStack.getLen() == 0 {
    
    
					out.AppendData(k, adcData.STypeBrace, utils.CopyBytes(loader.braceBuff))
					loader.braceBuff = loader.braceBuff[:0]
				}
			case chBracketEnd:
				loader.appendChToBuf(ch)
				if loader.bracketStack.getLen() == 0 {
    
    
					return LSSyntaxError
				}
				loader.bracketStack.pop()
				if loader.bracketStack.getLen() == 0 {
    
    
					out.AppendData(k, adcData.STypeBracket, utils.CopyBytes(loader.bracketBuff))
					loader.bracketBuff = loader.bracketBuff[:0]
				}
			case chParenthesisEnd:
				loader.appendChToBuf(ch)
				if loader.parenthesisStack.getLen() == 0 {
    
    
					return LSSyntaxError
				}
				loader.parenthesisStack.pop()
				if loader.parenthesisStack.getLen() == 0 {
    
    
					out.AppendData(k, adcData.STypeParenthesis, utils.CopyBytes(loader.parenthesisBuff))
					loader.parenthesisBuff = loader.parenthesisBuff[:0]
				}
			default:
				loader.appendChToBuf(ch)
			}
		}
		if !loader.allRight() {
    
    
			return LSSyntaxError
		}
	}
	return LSSuccess
}
  • 读取规则: 如果是[ 把字符放在 interpreterImp 里面的bracketStack,bracketBuff属性里
    如果遇到 ] 则pop出来,
    如果是( { [ 则把字符存在stack里面,后面会根据stack的长度来判断,这三个字符分别对应着不同,固定的stack

    具体是怎么存,怎么弹出来的 没搞明白

  • 规则:先执行case,当所有的case都判断完不符合bai条件的时候,才会执行default,无论你的default放在哪

	default:
				loader.appendChToBuf(ch)

把除了大小括号的字符都存在 了 interpreterImp属性里面的 braceBuff bracketBuff parenthesisBuff

  • 引擎的line属性 初始化 imp.lines = make([]*pipeline, len(data.data))
    line是个数组 遍历文件流data 数组的每个字符都要
imp.lines = make([]*pipeline, len(data.data))
	for k, v := range data.data {
    
    
		imp.lines[k] = getPipeline()
		imp.lines[k].form(imp, v)
	}

get一下sync pool里面的东西 不理解,然后进入到form方法
创建line 里面的sts 属性 是[]*stage 创建line里面的temp属性 是[]string
然后根据data里面的 []位置的数据开始遍历 (就是每次截取两个[]中间的数据)

	for k, v := range data[adcData.STypeBracket] {
    
    
		line.sts[k] = getStage()
		line.sts[k].form(line, v, data[adcData.STypeParenthesis][k], data[adcData.STypeBrace][k])
	}

这个st属性就是存类型的

st.st = stageType(trimData(sd)[0])
st      stageType
const (
	stSource = 102 //f
	stProcess = 112 //p
	stTo = 116 //t
)

这个方法是把自定义的方法标签提取出来 ,比如@jkv @mongoTree

st.f, st.fn = formFunction(trimData(vd))

这个是把数据提取粗来,比如[t{@jkv(hello2)}] 里面的hell02

pd := trimData(fd)

然后把数据put到pool里面

  • 然后到了run方法,先创建一个string缓存栈
	buf := bytes.NewBufferString("")

然后遍历引擎里面的 imp.lines 将遍历的结果跑run的方法 并且把返回的参数加入到buf的缓存区
run方法参数是一个写死的map

tm := map[string]interface{
    
    }{
    
    "data" : "foo"} --lkv
buf.WriteString(v.run(lkv))
  • 遍历 line.sts里面的每一个值 然后进行v.run()方法
for k, v := range line.sts {
    
    
		line.nowSts = k
		line.temp[k] = v.run()
	}

这里会选择进行哪个函数

result, kv := st.f(temp, args, ctx.kv)

type fHandler func(temp string, args []string, kv map[string]interface{
    
    }) (string, map[string]interface{
    
    })

var fMap = map[string]fHandler{
    
    
	ftPlaint:     functions.Plain,
	ftMongo:      functions.MongoTree,
	ftMongoMulti: functions.MongoTreeMulti,
	ftJKV:        functions.JKV,
	ftJKVMulti:   functions.JKVMulti,
	ftJKVNow:     functions.JKVNow,
	ftNow:        functions.Now,
}



跑完v.run之后 会把 结果推到sync池里面 putContext(line.ctx)

猜你喜欢

转载自blog.csdn.net/weixin_42123182/article/details/106661743