Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 0.8, 0.8.1, and 0.8.2

QueryDirstate.cpp: new class HgRepoRoot

Caches calls to GetHgRepoRoot

Changeset 1560550fcdc4

Parent 06f4688b4143

by Adrian Buehlmann

Changes to one file · Browse files at 1560550fcdc4 Showing diff from parent 06f4688b4143 Diff from another changeset...

 
27
28
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
31
32
33
34
35
36
 
37
38
39
 
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
 
126
127
128
129
@@ -27,13 +27,103 @@
 #include <shlwapi.h>     +class HgRepoRoot +{ + struct E + { + std::string hgroot_; + unsigned tickcount_; + unsigned hitcount_; + E(): tickcount_(0), hitcount_(0) {} + }; + + // true, if p is a subdir of refp, or identical + static bool is_subdir(const std::string& refp, const std::string& p); + +public: + static const std::string& get(const std::string& path); +}; + + +bool HgRepoRoot::is_subdir(const std::string& refp, const std::string& p) +{ + // refp = "foo\bar" + // p = "foo\bar\ping" -> return true + + if (refp.size() > p.size()) + return false; + + if (p.compare(0, refp.size(), refp) != 0) + return false; + + if (refp.size() == p.size()) + return true; + + // p is longer than refp + + char c = p[refp.size()]; + + // refp = "foo\bar" + // p = "foo\bar2", c is '2' -> return false + + if (c == '\\' || c == '/') + return true; + + return false; +} + + +const std::string& HgRepoRoot::get(const std::string& path) +{ + static E cache; + + if (!cache.hgroot_.empty() + && is_subdir(cache.hgroot_, path)) + { + unsigned tc = GetTickCount(); + if (tc - cache.tickcount_ < 2000) + { + ++cache.hitcount_; + return cache.hgroot_; + } + } + + std::string r = GetHgRepoRoot(path); + + bool show_hitcount = !cache.hgroot_.empty() && cache.hitcount_ > 0; + if (show_hitcount) + TDEBUG_TRACE("HgRepoRoot::get: '" + << cache.hgroot_ << "' had " << cache.hitcount_ << " hits"); + + cache.hitcount_ = 0; + + if (r.empty()) + { + cache.hgroot_.clear(); + cache.tickcount_ = 0; + } + else + { + if (show_hitcount) + { + const char* verb = (r != cache.hgroot_ ? "caching" : "refreshing" ); + TDEBUG_TRACE("HgRepoRoot::get: " << verb << " '" << cache.hgroot_ << "'"); + } + cache.hgroot_ = r; + cache.tickcount_ = GetTickCount(); + } + + return cache.hgroot_; +} + +  int HgQueryDirstate(   const std::string& path, const char& filterStatus, char& outStatus)  {   if (PathIsRoot(path.c_str()))   return 0;   - std::string hgroot = GetHgRepoRoot(path); + std::string hgroot = HgRepoRoot::get(path);   if (hgroot.empty())   return 0;