Skip to content

Commit bc7da6d

Browse files
committed
More performance improvements
Avoid calling NormalizeFilename (shouldn't ever actually be necessary in cases it was used) as it's highly expensive Reduce calls to %RoutineMgr:UserType (TODO: caching layer around this would help too; this is the main bottleneck other than $zf(-100) calls) Cache InternalName/ExternalName mapping in a new table (reduces overhead of $System.OBJ.Load calls) Unlock session for WebUI calls to avoid bottlenecks and make UI more snappy RefreshUncommitted on fewer WebUI git calls
1 parent b0bf03f commit bc7da6d

File tree

5 files changed

+96
-17
lines changed

5 files changed

+96
-17
lines changed

cls/SourceControl/Git/Change.cls

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ ClassMethod IsUncommitted(Filename, ByRef ID) As %Boolean
8080
/// Goes through Uncommitted queue and removes any items of action 'edit' or 'add' which are ReadOnly or non-existent on the filesystem
8181
ClassMethod RefreshUncommitted(Display = 0, IncludeRevert = 0, Output gitFiles, Force As %Boolean = 0) As %Status
8282
{
83+
set lock = $System.AutoLock.Lock("^SourceControl.Git.Refresh",,10)
84+
if lock = $$$NULLOREF {
85+
quit $$$ERROR($$$GeneralError,"Unable to get exclusive lock for refresh of uncommitted changes.")
86+
}
8387
if 'Force {
8488
// 10-second throttle on RefreshUncommitted
8589
if $zdatetime($ztimestamp,-2) - $Get(^IRIS.Temp.gitsourcecontrol("Refresh"),0) < 10 {

cls/SourceControl/Git/File.cls

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/// Has a cache of file internal/external name mappings as of LastModifiedTime.
2+
Class SourceControl.Git.File Extends %Persistent
3+
{
4+
5+
Property ExternalName As %String(MAXLEN = "") [ Required ];
6+
7+
Property ExternalNameHash As %String [ Calculated, SqlComputeCode = {set {*} = $System.Encryption.SHAHash(256,{ExternalName})}, SqlComputed ];
8+
9+
Property InternalName As %String(MAXLEN = 255) [ Required ];
10+
11+
Property LastModifiedTime As %String [ Required ];
12+
13+
Index InternalName On InternalName;
14+
15+
Index ExternalNameHash On ExternalNameHash [ Unique ];
16+
17+
ClassMethod ExternalNameToInternalName(ExternalName As %String) As %String
18+
{
19+
set internalName = ""
20+
if ##class(%File).Exists(ExternalName) {
21+
set lastModified = ##class(%Library.File).GetFileDateModified(ExternalName)
22+
set hash = $System.Encryption.SHAHash(256,ExternalName)
23+
if ..ExternalNameHashExists(hash,.id) {
24+
set inst = ..%OpenId(id,,.sc)
25+
$$$ThrowOnError(sc)
26+
if inst.LastModifiedTime = lastModified {
27+
quit inst.InternalName
28+
} else {
29+
set inst.LastModifiedTime = lastModified
30+
}
31+
} else {
32+
set inst = ..%New()
33+
set inst.ExternalName = ExternalName
34+
set inst.LastModifiedTime = lastModified
35+
}
36+
new %SourceControl //don't trigger source hooks with this test load to get the Name
37+
set sc=$system.OBJ.Load(ExternalName,"-d",,.outName,1)
38+
if (($data(outName)=1) || ($data(outName) = 11 && ($order(outName(""),-1) = $order(outName(""))))) && ($zconvert(##class(SourceControl.Git.Utils).Type(outName),"U") '= "CSP") {
39+
set internalName = outName
40+
set inst.InternalName = internalName
41+
$$$ThrowOnError(inst.%Save())
42+
}
43+
}
44+
quit internalName
45+
}
46+
47+
Storage Default
48+
{
49+
<Data name="FileDefaultData">
50+
<Value name="1">
51+
<Value>%%CLASSNAME</Value>
52+
</Value>
53+
<Value name="2">
54+
<Value>ExternalName</Value>
55+
</Value>
56+
<Value name="3">
57+
<Value>InternalName</Value>
58+
</Value>
59+
<Value name="4">
60+
<Value>LastModifiedTime</Value>
61+
</Value>
62+
</Data>
63+
<DataLocation>^SourceControl.Git.FileD</DataLocation>
64+
<DefaultData>FileDefaultData</DefaultData>
65+
<IdLocation>^SourceControl.Git.FileD</IdLocation>
66+
<IndexLocation>^SourceControl.Git.FileI</IndexLocation>
67+
<StreamLocation>^SourceControl.Git.FileS</StreamLocation>
68+
<Type>%Storage.Persistent</Type>
69+
}
70+
71+
}

cls/SourceControl/Git/Utils.cls

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,9 @@ ClassMethod Type(InternalName As %String) As %String
776776
} else {
777777
set type ="csp"
778778
}
779+
if (type = "csp") {
780+
quit type
781+
}
779782
}
780783

781784
// For an abstract document, use the GetOther() method to try to determine its "real" class
@@ -966,7 +969,7 @@ ClassMethod IsInSourceControl(InternalName As %String, ByRef sourceControlItem A
966969

967970
ClassMethod FullExternalName(ByRef InternalName As %String, ByRef MappingExists As %Boolean) As %String [ CodeMode = expression ]
968971
{
969-
##class(%File).NormalizeFilename(..TempFolder()_..ExternalName(.InternalName, .MappingExists))
972+
..TempFolder()_..ExternalName(.InternalName, .MappingExists)
970973
}
971974

972975
ClassMethod NormalizeInternalName(ByRef name As %String) As %String
@@ -1564,9 +1567,11 @@ ClassMethod Name(InternalName As %String, ByRef MappingExists As %Boolean) As %S
15641567
set InternalName = actualName
15651568
}
15661569
}
1570+
} else {
1571+
set usertype = 0
15671572
}
15681573

1569-
if '##class(%Library.RoutineMgr).UserType(InternalName) && $$CheckProtect^%qccServer(InternalName) {
1574+
if 'usertype && $$CheckProtect^%qccServer(InternalName) {
15701575
quit ""
15711576
}
15721577

@@ -1643,7 +1648,7 @@ ClassMethod Name(InternalName As %String, ByRef MappingExists As %Boolean) As %S
16431648
set InternalName=$extract(InternalName,$length(p)+2,*)
16441649
quit $translate(found_$translate(InternalName,"%","_"),"\","/")
16451650

1646-
} elseif ext="CLS"||(ext="PRJ")||(usertype&&(##class(%RoutineMgr).UserType(InternalName))) {
1651+
} elseif ext="CLS"||(ext="PRJ")||usertype {
16471652
set nam=$replace(nam,"%", ..PercentClassReplace())
16481653
if default{
16491654
set nam=$translate(nam,".","/")
@@ -1670,21 +1675,16 @@ ClassMethod NameToInternalName(Name, IgnorePercent = 1, IgnoreNonexistent = 1, V
16701675
set context = ##class(SourceControl.Git.PackageManagerContext).%Get()
16711676
if (context.IsInGitEnabledPackage) {
16721677
if ($zconvert(Name,"U")'[$zconvert(context.Package.Root,"U")) {
1673-
set Name = ##class(%File).NormalizeFilename(context.Package.Root_Name)
1678+
set Name = context.Package.Root_Name
16741679
}
16751680
} elseif ($zconvert(Name,"U")'[$zconvert($$$SourceRoot,"U")) {
1676-
set Name = ##class(%File).NormalizeFilename(..TempFolder()_Name)
1681+
set Name = ..TempFolder()_Name
16771682
}
16781683
if (##class(%File).Exists(Name)) {
1679-
new %SourceControl //don't trigger source hooks with this test load to get the Name
1680-
set sc=$system.OBJ.Load(Name,"-d",,.outName,1)
1681-
if (($data(outName)=1) || ($data(outName) = 11 && ($order(outName(""),-1) = $order(outName(""))))) && ($zconvert(..Type(outName),"U") '= "CSP") {
1682-
//only set if a single Name was returned ... ignore multi-item files
1683-
set InternalName=outName
1684-
if (context.IsInGitEnabledPackage) {
1685-
// Don't need mappings!
1686-
return ..NormalizeInternalName(InternalName)
1687-
}
1684+
set InternalName = ##class(SourceControl.Git.File).ExternalNameToInternalName(Name)
1685+
if (InternalName '= "") && (context.IsInGitEnabledPackage) {
1686+
// Don't need mappings!
1687+
return ..NormalizeInternalName(InternalName)
16881688
}
16891689
} else {
16901690
// check for file in uncommitted queue
@@ -2011,4 +2011,3 @@ ClassMethod ResetSourceControlClass()
20112011
}
20122012

20132013
}
2014-

cls/SourceControl/Git/WebUIDriver.cls

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Class SourceControl.Git.WebUIDriver
33

44
ClassMethod HandleRequest(pagePath As %String, InternalName As %String = "", Output handled As %Boolean = 0, Output %data As %Stream.Object)
55
{
6+
do %session.Unlock()
67
set context = ##class(SourceControl.Git.PackageManagerContext).ForInternalName(InternalName)
78
kill %data
89
#dim %response as %CSP.Response
@@ -99,6 +100,8 @@ ClassMethod HandleRequest(pagePath As %String, InternalName As %String = "", Out
99100
set stdin = $piece(args(1),$char(10),2,*)
100101
set args(1) = $piece(args(1),$char(10))
101102
}
103+
set readOnlyCommands = $listbuild("branch","tag","log","ls-files","ls-tree","show","status","diff")
104+
set baseCommand = $Piece(args(1)," ")
102105

103106
set gitArgs($increment(gitArgs)) = "color.ui=true"
104107

@@ -154,7 +157,9 @@ ClassMethod HandleRequest(pagePath As %String, InternalName As %String = "", Out
154157
do %data.WriteLine("Git-Stderr-Length: " _ (errStream.Size + nLines))
155158
do %data.Write("Git-Return-Code: " _ returnCode) // No ending newline expected
156159
do %data.Rewind()
157-
do ##class(SourceControl.Git.Change).RefreshUncommitted()
160+
if '$listfind(readOnlyCommands,baseCommand) {
161+
do ##class(SourceControl.Git.Change).RefreshUncommitted()
162+
}
158163
set handled = 1
159164
}
160165
}
@@ -218,4 +223,3 @@ ClassMethod GetSettingsURL(%request As %CSP.Request) As %SystemBase
218223
}
219224

220225
}
221-

csp/webuidriver.csp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
} catch e {
2020
// ignore; may occur on platform versions without the above properties
2121
}
22+
do %session.Unlock()
2223

2324
// Serve static content when appropriate.
2425
// index.html

0 commit comments

Comments
 (0)