Добавил базовые методы и модели для тестирования нарезки дерева
continuous-integration/drone/push Build is passing Details

main
Андрей Иванов 2024-10-03 17:42:55 +03:00
parent c3d06df00a
commit 5693923d03
11 changed files with 281 additions and 69 deletions

View File

@ -12,7 +12,7 @@ race:
.PHONY: bench
bench: ## Бенчмарки
go test -benchtime=10x -benchmem -bench=Benchmark ./... | grep allocs
go test -benchtime=3x -benchmem -bench=Benchmark ./... | grep allocs
help: ## Print this help and exit
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

View File

@ -0,0 +1,5 @@
package main
func DecomposeTree(tree map[string]*WeightedNode, threshold int) ([]SubTree, error) {
return []SubTree{{path: "/", tree: tree["1.0.0.0"].node}}, nil
}

View File

@ -0,0 +1,32 @@
package main
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestDecomposeTree(t *testing.T){
for name, tt := range map[string]struct{
inputTree map[string]*WeightedNode
inputThreshold int
outputParts []SubTree
err string
}{
"Normal":{
inputTree: smallTree.Tree,
inputThreshold: smallTree.Threshold,
outputParts: smallTree.Parts,
},
}{
t.Run(name, func(t *testing.T) {
result, err := DecomposeTree(tt.inputTree, tt.inputThreshold)
if tt.err == "" {
require.NoError(t, err)
require.ElementsMatch(t, result, tt.outputParts)
} else {
require.EqualError(t, err, tt.err)
}
})
}
}

View File

@ -0,0 +1,232 @@
package main
type testDecomposingData struct {
Tree map[string]*WeightedNode
Threshold int
Parts []SubTree
}
var smallTree = testDecomposingData{
Tree: tree3by3.WeightingTreeWithStack(),
Threshold: 2,
Parts: []SubTree{
{
path: "/",
tree: tree3by3,
},
},
}
var tree3by3 = &Node{
ID: "1.0.0.0",
Name: "/",
Children: []*Node{
{
ID: "1.1.0.0",
Name: "folder1",
Children: []*Node{
{
ID: "1.1.1.0",
Name: "folder1",
Children: []*Node{
{
ID: "1.1.1.1",
Name: "folder1",
Children: []*Node{},
},
{
ID: "1.1.1.2",
Name: "folder2",
Children: []*Node{},
},
{
ID: "1.1.1.3",
Name: "folder3",
Children: []*Node{},
},
},
},
{
ID: "1.1.2.0",
Name: "folder2",
Children: []*Node{
{
ID: "1.1.2.1",
Name: "folder1",
Children: []*Node{},
},
{
ID: "1.1.2.2",
Name: "folder2",
Children: []*Node{},
},
{
ID: "1.1.2.3",
Name: "folder3",
Children: []*Node{},
},
},
},
{
ID: "1.1.3.0",
Name: "folder3",
Children: []*Node{
{
ID: "1.1.3.1",
Name: "folder3",
Children: []*Node{},
},
{
ID: "1.1.3.2",
Name: "folder3",
Children: []*Node{},
},
{
ID: "1.1.3.3",
Name: "folder3",
Children: []*Node{},
},
},
},
},
},
{
ID: "1.2.0.0",
Name: "folder2",
Children: []*Node{
{
ID: "1.2.1.0",
Name: "folder1",
Children: []*Node{
{
ID: "1.2.1.1",
Name: "folder1",
Children: []*Node{},
},
{
ID: "1.2.1.2",
Name: "folder2",
Children: []*Node{},
},
{
ID: "1.2.1.3",
Name: "folder3",
Children: []*Node{},
},
},
},
{
ID: "1.2.2.0",
Name: "folder2",
Children: []*Node{
{
ID: "1.2.2.1",
Name: "folder1",
Children: []*Node{},
},
{
ID: "1.2.2.2",
Name: "folder2",
Children: []*Node{},
},
{
ID: "1.2.2.3",
Name: "folder3",
Children: []*Node{},
},
},
},
{
ID: "1.2.3.0",
Name: "folder3",
Children: []*Node{
{
ID: "1.2.3.1",
Name: "folder1",
Children: []*Node{},
},
{
ID: "1.2.3.2",
Name: "folder2",
Children: []*Node{},
},
{
ID: "1.2.3.3",
Name: "folder3",
Children: []*Node{},
},
},
},
},
},
{
ID: "1.3.0.0",
Name: "folder3",
Children: []*Node{
{
ID: "1.3.1.0",
Name: "folder1",
Children: []*Node{
{
ID: "1.3.1.1",
Name: "folder1",
Children: []*Node{},
},
{
ID: "1.3.1.2",
Name: "folder2",
Children: []*Node{},
},
{
ID: "1.3.1.3",
Name: "folder3",
Children: []*Node{},
},
},
},
{
ID: "1.3.2.0",
Name: "folder2",
Children: []*Node{
{
ID: "1.3.2.1",
Name: "folder1",
Children: []*Node{},
},
{
ID: "1.3.2.2",
Name: "folder2",
Children: []*Node{},
},
{
ID: "1.3.2.3",
Name: "folder3",
Children: []*Node{},
},
},
},
{
ID: "1.3.3.0",
Name: "folder3",
Children: []*Node{
{
ID: "1.3.3.1",
Name: "folder1",
Children: []*Node{},
},
{
ID: "1.3.3.2",
Name: "folder2",
Children: []*Node{},
},
{
ID: "1.3.3.3",
Name: "folder3",
Children: []*Node{},
},
},
},
},
},
},
}

View File

@ -2,7 +2,7 @@ package main
import (
"maps"
"tests/weghting_n_cutting_the_tree/dll"
"tests/weighting_n_cutting_the_tree/dll"
)
func (root *Node) WeightingTreeWithRecursion(parent *Node) map[string]*WeightedNode {
@ -103,7 +103,3 @@ func (root *Node) WeightingTreeWithDLL() map[string]*WeightedNode {
return counter
}
func DecomposeTree(tree map[string]*WeightedNode, threshold int) ([]SubTree, error) {
return []SubTree{{path: "/", tree: tree["root"].node}}, nil
}

View File

@ -2,7 +2,6 @@ package main
import (
"fmt"
"github.com/stretchr/testify/require"
"sort"
"testing"
@ -10,9 +9,9 @@ import (
)
func TestNode_WeighingTreeAllAlgo(t *testing.T) {
for name,tt := range map[string]TestTree{
"Ordinary VFS tree": getTestTree(3, 3, nil),
"VFS in the form of a pathological tree":getTestTree(1, 7, nil),
for name,tt := range map[string]WeightedTree{
"Ordinary VFS tree": getWeightedTree(3, 3, nil),
"VFS in the form of a pathological tree":getWeightedTree(1, 7, nil),
}{
t.Run(name,func(t *testing.T) {
t.Run("WeightingTreeWithRecursion", func(t *testing.T) {
@ -34,31 +33,6 @@ func TestNode_WeighingTreeAllAlgo(t *testing.T) {
}
}
func TestDecomposeTree(t *testing.T){
for name, tt := range map[string]struct{
inputTree map[string]*WeightedNode
inputThreshold int
outputParts []SubTree
err string
}{
"Normal":{
inputTree: smallTree.Tree,
inputThreshold: smallTree.Threshold,
outputParts: smallTree.Parts,
},
}{
t.Run(name, func(t *testing.T) {
result, err := DecomposeTree(tt.inputTree, tt.inputThreshold)
if tt.err == "" {
require.NoError(t, err)
require.ElementsMatch(t, result, tt.outputParts)
} else {
require.EqualError(t, err, tt.err)
}
})
}
}
func Benchmark(b *testing.B) {
b.StopTimer()
b.ResetTimer()
@ -73,9 +47,9 @@ func Benchmark(b *testing.B) {
"Pathological tree (10K nodes)": {1, 10000}, // 10'000 nodes,
}{
b.Run(name, func(b *testing.B) {
tree := getTestTree(tt.branches, tt.depth, nil)
tree := getWeightedTree(tt.branches, tt.depth, nil)
b.Cleanup(func() {
tree = TestTree{nil, nil}
tree = WeightedTree{nil, nil}
})
b.Run("Weighing with recursion", func(b *testing.B) {
for i := 0; i < b.N; i++ {

View File

@ -5,14 +5,14 @@ import (
"maps"
)
type TestTree struct {
type WeightedTree struct {
Tree *Node
Weights map[string]*WeightedNode
}
func getTestTree(branches, depth int, parent *Node) TestTree {
func getWeightedTree(branches, depth int, parent *Node) WeightedTree {
if depth == 0 {
return TestTree{}
return WeightedTree{}
}
id := uuid.NewString()
node := &Node{
@ -20,7 +20,7 @@ func getTestTree(branches, depth int, parent *Node) TestTree {
Name: id,
Children: []*Node{},
}
tree := TestTree{
tree := WeightedTree{
Tree: node,
Weights: map[string]*WeightedNode{id: &WeightedNode{
node: node,
@ -30,7 +30,7 @@ func getTestTree(branches, depth int, parent *Node) TestTree {
}},
}
for i := 0; i < branches; i++ {
childTree := getTestTree(branches, depth-1, node)
childTree := getWeightedTree(branches, depth-1, node)
if childTree.Tree != nil {
tree.Tree.Children = append(tree.Tree.Children, childTree.Tree)
tree.Weights[id].children = append(tree.Weights[id].children, childTree.Tree)
@ -42,30 +42,3 @@ func getTestTree(branches, depth int, parent *Node) TestTree {
}
return tree
}
type testDecomposingData struct {
Tree map[string]*WeightedNode
Threshold int
Parts []SubTree
}
var smallTree = testDecomposingData{
Tree: map[string]*WeightedNode{
"root": {
node: &Node{
ID: "root",
Name: "root",
},
},
},
Threshold: 2,
Parts: []SubTree{
{
path: "/",
tree: &Node{
ID: "root",
Name: "root",
},
},
},
}