sample_chain/order/core/transaction_grouping.go

89 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package core
const minNLen = 16
// TransactionGroup 事务分组
type TransactionGroup struct {
N int //总共分了多少个组
Group [][][2]string //分组的结果
Rely map[string]int //存储依赖关系
}
// NewGroup 新建分组
func NewGroup() *TransactionGroup {
//每个元素都是一个包含两个字符串的数组切片
buf1 := make([][][2]string, minNLen)
buf2 := make(map[string]int)
return &TransactionGroup{
N: 1,
Group: buf1,
Rely: buf2,
}
}
// resizeGroup 对分组大小进行扩容
// 切片 g.Group 扩展为原始长度的两倍,并将原始切片的内容复制到新创建的切片中
func (g *TransactionGroup) resizeGroup() {
newBuf := make([][][2]string, g.N<<1)
copy(newBuf, g.Group[:])
g.Group = newBuf
}
func (g *TransactionGroup) GroupTransactionsByDeps(table [][2]string) {
for _, t := range table {
g.AddEdge(t[0], t[1])
}
}
// AddEdge 新加分组t1、t2是存在依赖关系的两个事务
func (g *TransactionGroup) AddEdge(t1, t2 string) {
// 新元素入队之前,当队列长度等于缓存区长度时,缓存区长度重设为两个队列长度
if g.N >= len(g.Group)*8/10 {
g.resizeGroup()
}
//当事务t1和事务t2都没进行分组时将t1和t2加入到一个新的分组中
if g.Rely[t1] == 0 && g.Rely[t2] == 0 {
g.Rely[t1], g.Rely[t2] = g.N, g.N
g.Group[g.N] = append(g.Group[g.N], [2]string{t1, t2})
g.N++
} else if g.Rely[t1] > 0 && g.Rely[t2] == 0 { //如果t1已经分组但是t2还没分组则将t2加入到t1分组
g.Rely[t2] = g.Rely[t1]
g.Group[g.Rely[t1]] = append(g.Group[g.Rely[t1]], [2]string{t1, t2})
} else if g.Rely[t1] == 0 && g.Rely[t2] > 0 { //如果t2已经分组但是t1还没分组则将t1加入到t2分组
g.Rely[t1] = g.Rely[t2]
g.Group[g.Rely[t2]] = append(g.Group[g.Rely[t2]], [2]string{t1, t2})
} else if g.Rely[t1] == g.Rely[t2] { //事务t1和t2都已经分组,并且分到了同一个组中
g.Group[g.Rely[t1]] = append(g.Group[g.Rely[t1]], [2]string{t1, t2})
} else { //事务t1和t2都已经分组但是分到了不同的组中
//记录t2的分组
temp := g.Rely[t2]
//将t2组中的事务和t1组中的事务合并
g.Group[g.Rely[t1]] = append(g.Group[g.Rely[t1]], g.Group[g.Rely[t2]]...)
g.Group[g.Rely[t1]] = append(g.Group[g.Rely[t1]], [2]string{t1, t2})
//将t2的分组改为t1的分组
for _, txs := range g.Group[temp] {
for _, tx := range txs {
g.Rely[tx] = g.Rely[t1]
}
}
g.Group[temp] = nil
}
}
func DeepCopyGroup(group *TransactionGroup) *TransactionGroup {
buf := make([][][2]string, len(group.Group))
for i, arr := range group.Group {
buf[i] = make([][2]string, len(arr))
for j, subArr := range arr {
buf[i][j] = [2]string{subArr[0], subArr[1]}
}
}
copyMap := make(map[string]int)
for key, value := range group.Rely {
copyMap[key] = value
}
return &TransactionGroup{N: group.N, Group: buf, Rely: copyMap}
}