@@ -32,52 +32,73 @@ func findFile(file string) (string, error) {
32
32
// mergeProfs merges profiles for same target packages.
33
33
// It assumes each profiles have same sorted FileName and Blocks.
34
34
func mergeProfs (pfss [][]* cover.Profile ) []* cover.Profile {
35
- // skip empty profiles ([no test files])
36
- for i := 0 ; i < len (pfss ); i ++ {
37
- if len (pfss [i ]) > 0 {
38
- pfss = pfss [i :]
39
- break
40
- }
41
- }
42
35
if len (pfss ) == 0 {
43
36
return nil
44
- } else if len (pfss ) == 1 {
45
- return pfss [0 ]
46
37
}
47
- head , rest := pfss [0 ], pfss [1 :]
48
- ret := make ([]* cover.Profile , 0 , len (head ))
49
- for i , profile := range head {
50
- for _ , ps := range rest {
51
- // find profiles
52
- if len (ps ) == 0 {
53
- continue
54
- } else if len (ps ) < i + 1 {
55
- continue
56
- } else if ps [i ].FileName != profile .FileName {
57
- continue
38
+ for len (pfss ) > 1 {
39
+ i := 0
40
+ for ; 2 * i + 1 < len (pfss ); i ++ {
41
+ pfss [i ] = mergeTwoProfs (pfss [2 * i ], pfss [2 * i + 1 ])
42
+ }
43
+ if 2 * i < len (pfss ) {
44
+ pfss [i ] = pfss [2 * i ]
45
+ i ++
46
+ }
47
+ pfss = pfss [:i ]
48
+ }
49
+ return pfss [0 ]
50
+ }
51
+
52
+ func mergeTwoProfs (left , right []* cover.Profile ) []* cover.Profile {
53
+ ret := make ([]* cover.Profile , 0 , len (left )+ len (right ))
54
+ for len (left ) > 0 && len (right ) > 0 {
55
+ if left [0 ].FileName == right [0 ].FileName {
56
+ profile := & cover.Profile {
57
+ FileName : left [0 ].FileName ,
58
+ Mode : left [0 ].Mode ,
59
+ Blocks : mergeTwoProfBlock (left [0 ].Blocks , right [0 ].Blocks ),
58
60
}
59
- profile .Blocks = mergeProfBlocks (profile .Blocks , ps [i ].Blocks )
61
+ ret = append (ret , profile )
62
+ left = left [1 :]
63
+ right = right [1 :]
64
+ } else if left [0 ].FileName < right [0 ].FileName {
65
+ ret = append (ret , left [0 ])
66
+ left = left [1 :]
67
+ } else {
68
+ ret = append (ret , right [0 ])
69
+ right = right [1 :]
60
70
}
61
- ret = append (ret , profile )
62
71
}
72
+ ret = append (ret , left ... )
73
+ ret = append (ret , right ... )
63
74
return ret
64
75
}
65
76
66
- func mergeProfBlocks (as , bs []cover.ProfileBlock ) []cover.ProfileBlock {
67
- if len (as ) != len (bs ) {
68
- log .Fatal ("Two block length should be same" )
69
- }
70
- // cover.ProfileBlock generated by cover.ParseProfiles() is sorted by
71
- // StartLine and StartCol, so we can use index.
72
- ret := make ([]cover.ProfileBlock , 0 , len (as ))
73
- for i , a := range as {
74
- b := bs [i ]
75
- if a .StartLine != b .StartLine || a .StartCol != b .StartCol {
76
- log .Fatal ("Blocks are not sorted" )
77
+ func mergeTwoProfBlock (left , right []cover.ProfileBlock ) []cover.ProfileBlock {
78
+ ret := make ([]cover.ProfileBlock , 0 , len (left )+ len (right ))
79
+ for len (left ) > 0 && len (right ) > 0 {
80
+ a , b := left [0 ], right [0 ]
81
+ if a .StartLine == b .StartLine && a .StartCol == b .StartCol && a .EndLine == b .EndLine && a .EndCol == b .EndCol {
82
+ ret = append (ret , cover.ProfileBlock {
83
+ StartLine : a .StartLine ,
84
+ StartCol : a .StartCol ,
85
+ EndLine : a .EndLine ,
86
+ EndCol : a .EndCol ,
87
+ NumStmt : a .NumStmt ,
88
+ Count : a .Count + b .Count ,
89
+ })
90
+ left = left [1 :]
91
+ right = right [1 :]
92
+ } else if a .StartLine < b .StartLine || (a .StartLine == b .StartLine && a .StartCol < b .StartCol ) {
93
+ ret = append (ret , a )
94
+ left = left [1 :]
95
+ } else {
96
+ ret = append (ret , b )
97
+ right = right [1 :]
77
98
}
78
- a .Count += b .Count
79
- ret = append (ret , a )
80
99
}
100
+ ret = append (ret , left ... )
101
+ ret = append (ret , right ... )
81
102
return ret
82
103
}
83
104
0 commit comments