• 第二版mq 数据结构选型


    第二版mq 数据结构选型

    第一版的mq已经完成: gitee.com/maomaomaoge/opmq

    详见 v3.0.0标签

    第一版的遗憾

    1. topic写死了,没有按照topic业界实现规则,但是换来的确实快,是真快
    2. Qos只实现了0

    topic的数据结构

    最后还是选择了无顺树

    1. 字典树的缺陷:

      场景不适合,遇到topic的加号,还是处理不了

    2. btree

      第一版使用的

    3. 二叉树

      不适合

    4. 赫夫曼树

      也不中

    无序数代码

    核心是如何把里面的结果在递归函数存储, 而不是用全局变量

    并发的锁需要在业务中体现,目前不作考虑

    更详细的结果要自己在goland的debug看

    package main
    
    import (
    	"fmt"
    	"strings"
    	"sync"
    )
    
    type UnorderedTree struct {
    	Mux sync.Mutex
    	Name string
    	Children []*UnorderedTree
    }
    
    func NewTree() *UnorderedTree {
    	return &UnorderedTree{
    		Children:make([]*UnorderedTree, 0),
    	}
    }
    
    func (ut *UnorderedTree)AddChild(name string)  {
    	tree := NewTree()
    	tree.Name = name
    
    	ut.Children = append(ut.Children, tree)
    }
    
    func (ut *UnorderedTree)AddChildAndReturnNext(name string) *UnorderedTree {
    	tree := NewTree()
    	tree.Name = name
    
    	// 如果有重复节点,直接返回
    	for _, v := range ut.Children {
    		if v.Name == name {
    			return v
    		}
    	}
    
    	ut.Children = append(ut.Children, tree)
    	return tree
    }
    
    func (ut *UnorderedTree)Find(name string) []*UnorderedTree {
    	res := make([]*UnorderedTree, 0)
    	for _, v := range ut.Children {
    		if v.Name == name || name == "+" {
    			fmt.Println("添加孩子: ", v.Name, " 所有孩子: ", len(ut.Children))
    			res = append(res, v)
    		}
    	}
    
    	return res
    }
    
    type Res struct {
    	Data []*UnorderedTree
    }
    
    // find: 1/+/3
    func Scan(topic string, ut *UnorderedTree, r *Res) {
    	fmt.Println("当前节点", ut.Name)
    	split := strings.SplitN(topic, "/", 2)
    	if len(split) == 1 {
    		ch := ut.Find(split[0])
    		for _, v := range ch {
    			fmt.Println(ut.Name, "结果添加节点", v.Name)
    			r.Data = append(r.Data, v)
    		}
    
    		return
    	}
    
    	if len(split) == 2 {
    		ch := ut.Find(split[0])
    		for _, v := range ch {
    			fmt.Println("递归", len(ch), split[1])
    			Scan(split[1], v, r)
    		}
    	}
    
    	return
    }
    
    func main() {
    	root := NewTree()
    	root.Name = "root"
    
    	// 添加root/1/2/3
    	root.AddChildAndReturnNext("1").AddChildAndReturnNext("2").AddChildAndReturnNext("3").AddChildAndReturnNext("4")
    	// 添加 1/+/2
    	root.AddChildAndReturnNext("1").AddChildAndReturnNext("+").AddChildAndReturnNext("3").AddChildAndReturnNext("5")
    
    	res := &Res{
    		Data: make([]*UnorderedTree, 0),
    	}
    	Scan("1/+/3", root, res)
    
    	fmt.Println(len(res.Data))
    }
    
    
    # 输出
    当前节点 root
    添加孩子:  1  所有孩子:  1
    递归 1 +/3
    当前节点 1
    添加孩子:  2  所有孩子:  2
    添加孩子:  +  所有孩子:  2
    递归 2 3
    当前节点 2
    添加孩子:  3  所有孩子:  1
    2 结果添加节点 3
    递归 2 3
    当前节点 +
    添加孩子:  3  所有孩子:  1
    + 结果添加节点 3
    2
    
    
  • 相关阅读:
    JQuery源码解析-Dom加载过程
    多个script标签的作用域
    JQuery源码解析-JQuery的工具方法(1)
    JQuery源码解析-JQuery的工具方法
    JQuery源码解析-JQuery.extend()方法
    JQuery源码解析-添加JQuery的一些方法和属性
    中兴捧月算法精英挑战赛-迪杰斯特拉派
    C语言中的内存相关问题
    动态内存管理
    虚函数与虚继承小结
  • 原文地址:https://www.cnblogs.com/maomaomaoge/p/15248626.html
Copyright © 2020-2023  润新知