Flatten algo
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
parent
3899618605
commit
63b4b4b484
|
@ -10,27 +10,97 @@ func DecomposeTree(tree map[string]*WeightedNode, threshold uint16) ([]SubTree,
|
|||
// Рабочий цикл
|
||||
for len(tree) > 0 {
|
||||
// Индексируем tree по weight и сортируем индекс
|
||||
index := GetTreeIndex(tree)
|
||||
var index = make([]TreeIndex, len(tree))
|
||||
i := 0
|
||||
for k, v := range tree {
|
||||
index[i] = TreeIndex{
|
||||
id: k,
|
||||
weight: v.weight,
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
slices.SortFunc(index, func(a, b TreeIndex) int {
|
||||
return int(b.weight) - int(a.weight)
|
||||
})
|
||||
|
||||
// Ищем ветку подходящую под лимит
|
||||
branchID, weight := GetBranch(tree, index, threshold)
|
||||
var branchID string
|
||||
for _, v := range index {
|
||||
if v.weight < threshold {
|
||||
branchID = v.id
|
||||
break
|
||||
}
|
||||
}
|
||||
if branchID == "" {
|
||||
return nil, errors.New("[GetNodePath]: threshold too small")
|
||||
}
|
||||
|
||||
// Определяем путь к найденной ветке
|
||||
path, err := GetNodePath(tree, branchID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "[GetNodePath]")
|
||||
nodeID := tree[branchID].node.ID
|
||||
var path string
|
||||
if _, ok := tree[nodeID]; !ok {
|
||||
return nil, errors.New("[GetNodePath] node not exists")
|
||||
}
|
||||
if tree[nodeID].parent == nil {
|
||||
path = "/"
|
||||
} else {
|
||||
nodeID = tree[nodeID].parent.ID
|
||||
path = tree[nodeID].node.Name
|
||||
for path != "/" {
|
||||
if tree[nodeID].parent.Name == "/" {
|
||||
path = "/" + path
|
||||
break
|
||||
}
|
||||
nodeID = tree[nodeID].parent.ID
|
||||
path = tree[nodeID].node.Name + "/" + path
|
||||
}
|
||||
}
|
||||
|
||||
// Вычитаем ветку из веса предков
|
||||
RecalculateParents(tree, branchID, weight)
|
||||
currentID := branchID
|
||||
if tree[currentID].parent != nil {
|
||||
currentID = tree[currentID].parent.ID
|
||||
for {
|
||||
tree[currentID].weight -= tree[branchID].weight
|
||||
if tree[currentID].parent == nil {
|
||||
break
|
||||
}
|
||||
currentID = tree[currentID].parent.ID
|
||||
}
|
||||
}
|
||||
|
||||
// Вырезаем её из среза вместе со всеми потомками
|
||||
branch := CutBranch(tree, branchID)
|
||||
// Удаляем ссылки на ноду из родительской ноды
|
||||
if tree[branchID].parent != nil {
|
||||
parent := tree[branchID].parent
|
||||
m := slices.IndexFunc(parent.Children, func(node *Node) bool {
|
||||
return node.ID == branchID
|
||||
})
|
||||
if m >= 0 {
|
||||
parent.Children[m] = parent.Children[len(parent.Children)-1]
|
||||
parent.Children = parent.Children[:len(parent.Children)-1]
|
||||
//parent.Children = append(parent.Children[:m], parent.Children[m+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
node := tree[branchID].node
|
||||
// Удаляем ветви вместе со всеми потомками
|
||||
stack := []string{branchID}
|
||||
for len(stack) > 0 {
|
||||
current := stack[len(stack)-1]
|
||||
stack = stack[:len(stack)-1]
|
||||
if _, ok := tree[current]; ok {
|
||||
for _, v := range tree[current].children {
|
||||
stack = append(stack, v.ID)
|
||||
}
|
||||
delete(tree, current)
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем найденную ветку к res
|
||||
res = append(res, SubTree{
|
||||
path: path,
|
||||
tree: branch,
|
||||
tree: node,
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
|
|
Loading…
Reference in New Issue