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 {
|
for len(tree) > 0 {
|
||||||
// Индексируем tree по weight и сортируем индекс
|
// Индексируем 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 == "" {
|
if branchID == "" {
|
||||||
return nil, errors.New("[GetNodePath]: threshold too small")
|
return nil, errors.New("[GetNodePath]: threshold too small")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Определяем путь к найденной ветке
|
// Определяем путь к найденной ветке
|
||||||
path, err := GetNodePath(tree, branchID)
|
nodeID := tree[branchID].node.ID
|
||||||
if err != nil {
|
var path string
|
||||||
return nil, errors.Wrap(err, "[GetNodePath]")
|
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
|
||||||
res = append(res, SubTree{
|
res = append(res, SubTree{
|
||||||
path: path,
|
path: path,
|
||||||
tree: branch,
|
tree: node,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return res, nil
|
return res, nil
|
||||||
|
|
Loading…
Reference in New Issue