第二版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

原文地址:https://www.cnblogs.com/maomaomaoge/p/15248626.html