1+ /// This class maintains the mapping between .INT/.MAC/.CLS and therefore is critical for
2+ /// interpreting the .INT-level coverage data that the line-by-line monitor collects.
13Class TestCoverage .Data .CodeUnitMap Extends %Persistent
24{
35
@@ -23,33 +25,99 @@ ForeignKey ToCodeUnitFK(ToHash) References TestCoverage.Data.CodeUnit(Hash) [ On
2325
2426ClassMethod Create (pFromHash As %String , pFromLine As %Integer , pToHash As %String , pToLineStart As %Integer , pToLineEnd As %Integer ) As %Status
2527{
28+ #def1arg DefaultStorageNode (%node ) ##expression ($$$comMemberKeyGet (" TestCoverage.Data.CodeUnitMap" , $$$cCLASSstorage , " Default" , %node ))
29+ #def1arg CodeUnitMasterMap (%arg ) $$$DefaultStorageNode ($$$cSDEFdatalocation )(%arg )
30+ #def1arg CodeUnitReverseMap (%arg ) $$$DefaultStorageNode ($$$cSDEFindexlocation )(" Reverse" ,%arg )
31+
2632 Set tSC = $$$OK
2733 Try {
28- &sql (insert or update %NOLOCK %NOCHECK into TestCoverage_Data .CodeUnitMap
29- (FromHash, FromLine, ToHash, ToLine)
30- select :pFromHash , :pFromLine , :pToHash , Counter
31- from TestCoverage .Sequence (:pToLineStart ,:pToLineEnd ))
32- If (SQLCODE < 0 ) {
33- Throw ##class (%Exception.SQL ).CreateFromSQLCODE (SQLCODE ,%msg )
34+ For counter =pToLineStart :1 :pToLineEnd {
35+ // Uses direct global references for performance boost; this is one of the most performance-critical sections.
36+ If '$Data ($$$CodeUnitMasterMap(pFromHash ,pFromLine ,pToHash ,counter )) {
37+ &sql (insert %NOLOCK %NOCHECK into TestCoverage_Data .CodeUnitMap
38+ (FromHash, FromLine, ToHash, ToLine)
39+ select :pFromHash , :pFromLine , :pToHash , :counter )
40+ If (SQLCODE < 0 ) {
41+ Throw ##class (%Exception.SQL ).CreateFromSQLCODE (SQLCODE ,%msg )
42+ }
43+ }
3444 }
3545
3646 // Insert/update transitive data (e.g., .INT -> .MAC (generator) -> .CLS)
47+ // Original implementation:
48+ /*
49+ // Leg 1: Lines that map to the "from" line also map to the "to" line
50+ // Leg 2: The "from" line also maps to lines that the "to" line maps to
3751 &sql(
38- /* Lines that map to the "from" line also map to the "to" line */
3952 insert or update %NOLOCK %NOCHECK into TestCoverage_Data.CodeUnitMap
4053 (FromHash, FromLine, ToHash, ToLine)
4154 select FromHash, FromLine, :pToHash, Counter
4255 from TestCoverage.Sequence(:pToLineStart,:pToLineEnd),TestCoverage_Data.CodeUnitMap
4356 where ToHash = :pFromHash and ToLine = :pFromLine
4457 union
45- /* The "from" line also maps to lines that the "to" line maps to */
4658 select :pFromHash, :pFromLine, ToHash, ToLine
4759 from TestCoverage.Sequence(:pToLineStart,:pToLineEnd)
4860 join TestCoverage_Data.CodeUnitMap
4961 on FromHash = :pToHash and FromLine = Counter)
5062 If (SQLCODE < 0) {
5163 Throw ##class(%Exception.SQL).CreateFromSQLCODE(SQLCODE,%msg)
5264 }
65+ */
66+
67+ // This introduced some unacceptable performance overhead, and has been rewritten with direct global references.
68+ // This reduces overall overhead of code capture for test coverage measurement by roughly 40%.
69+
70+ // Leg 1: Lines that map to the "from" line also map to the "to" line
71+ Set fromHash = " "
72+ For {
73+ Set fromHash = $Order ($$$CodeUnitReverseMap(pFromHash ,pFromLine ,fromHash ))
74+ If (fromHash = " " ) {
75+ Quit
76+ }
77+ Set fromLine = " "
78+ For {
79+ Set fromLine = $Order ($$$CodeUnitReverseMap(pFromHash ,pFromLine ,fromHash ,fromLine ))
80+ If (fromLine = " " ) {
81+ Quit
82+ }
83+ For counter =pToLineStart :1 :pToLineEnd {
84+ If '$Data ($$$CodeUnitMasterMap(fromHash ,fromLine ,pToHash ,counter )) {
85+ &sql (insert %NOLOCK %NOCHECK into TestCoverage_Data .CodeUnitMap
86+ (FromHash, FromLine, ToHash, ToLine)
87+ select :fromHash , :fromLine , :pToHash , :counter )
88+ If (SQLCODE < 0 ) {
89+ Throw ##class (%Exception.SQL ).CreateFromSQLCODE (SQLCODE ,%msg )
90+ }
91+ }
92+ }
93+ }
94+ }
95+
96+ For counter =pToLineStart :1 :pToLineEnd {
97+ // Leg 2: The "from" line also maps to lines that the "to" line maps to
98+ Set toHash = " "
99+ For {
100+ Set toHash = $Order ($$$CodeUnitMasterMap(pToHash ,counter ,toHash ))
101+ If (toHash = " " ) {
102+ Quit
103+ }
104+ Set toLine = " "
105+ For {
106+ Set toLine = $Order ($$$CodeUnitMasterMap(pToHash ,counter ,toHash ,toLine ))
107+ If (toLine = " " ) {
108+ Quit
109+ }
110+ If '$Data ($$$CodeUnitMasterMap(pFromHash ,pFromLine ,toHash ,toLine )) {
111+ &sql (insert %NOLOCK %NOCHECK into TestCoverage_Data .CodeUnitMap
112+ (FromHash, FromLine, ToHash, ToLine)
113+ select :pFromHash , :pFromLine , :toHash , :toLine )
114+ If (SQLCODE < 0 ) {
115+ Throw ##class (%Exception.SQL ).CreateFromSQLCODE (SQLCODE ,%msg )
116+ }
117+ }
118+ }
119+ }
120+ }
53121 } Catch e {
54122 Set tSC = e .AsStatus ()
55123 }
0 commit comments