27
27
#include " IndexStoreDB/Support/Logging.h"
28
28
#include " indexstore/IndexStoreCXX.h"
29
29
#include " llvm/ADT/ArrayRef.h"
30
+ #include " llvm/ADT/DenseMap.h"
30
31
#include " llvm/ADT/STLExtras.h"
31
32
#include " llvm/ADT/StringMap.h"
32
33
#include " llvm/ADT/StringRef.h"
@@ -147,8 +148,7 @@ class StoreUnitRepo : public std::enable_shared_from_this<StoreUnitRepo> {
147
148
void removeUnitMonitor (IDCode unitCode);
148
149
149
150
void onUnitOutOfDate (IDCode unitCode, StringRef unitName,
150
- sys::TimePoint<> outOfDateModTime,
151
- OutOfDateTriggerHintRef hint,
151
+ OutOfDateFileTriggerRef trigger,
152
152
bool synchronous = false );
153
153
void onFSEvent (std::vector<std::string> parentPaths);
154
154
void checkUnitContainingFileIsOutOfDate (StringRef file);
@@ -184,23 +184,20 @@ class IndexDatastoreImpl {
184
184
};
185
185
186
186
class UnitMonitor {
187
- struct OutOfDateTrigger {
188
- OutOfDateTriggerHintRef hint;
189
- sys::TimePoint<> outOfDateModTime;
190
-
191
- std::string getTriggerFilePath () const {
192
- return hint->originalFileTrigger ();
193
- }
194
- };
195
-
196
187
std::weak_ptr<StoreUnitRepo> UnitRepo;
197
188
IDCode UnitCode;
198
189
std::string UnitName;
199
190
sys::TimePoint<> ModTime;
200
191
201
192
mutable llvm::sys::Mutex StateMtx;
202
- // / Map of out-of-date file path to its associated info.
203
- StringMap<OutOfDateTrigger> OutOfDateTriggers;
193
+
194
+ // / Map of out-of-date file paths to their associated info. Note that the
195
+ // / StringRef key references the string in the trigger, so must not outlive
196
+ // / it. Access to this map should be guarded by \c StateMtx.
197
+ llvm::DenseMap<StringRef, OutOfDateFileTriggerRef> OutOfDateTriggers;
198
+
199
+ // / Retrieves an unordered list of out-of-date trigger files.
200
+ std::vector<OutOfDateFileTriggerRef> getUnorderedOutOfDateTriggers () const ;
204
201
205
202
public:
206
203
UnitMonitor (std::shared_ptr<StoreUnitRepo> unitRepo);
@@ -217,10 +214,8 @@ class UnitMonitor {
217
214
StringRef getUnitName () const { return UnitName; }
218
215
sys::TimePoint<> getModTime () const { return ModTime; }
219
216
220
- std::vector<OutOfDateTrigger> getOutOfDateTriggers () const ;
221
-
222
217
void checkForOutOfDate (sys::TimePoint<> outOfDateModTime, StringRef filePath, bool synchronous=false );
223
- void markOutOfDate (sys::TimePoint<> outOfDateModTime, OutOfDateTriggerHintRef hint, bool synchronous= false );
218
+ void markOutOfDate (OutOfDateFileTriggerRef trigger, bool synchronous = false );
224
219
225
220
static std::pair<StringRef, sys::TimePoint<>> getMostRecentModTime (ArrayRef<StringRef> filePaths);
226
221
static sys::TimePoint<> getModTimeForOutOfDateCheck (StringRef filePath);
@@ -826,8 +821,7 @@ void StoreUnitRepo::removeUnitMonitor(IDCode unitCode) {
826
821
}
827
822
828
823
void StoreUnitRepo::onUnitOutOfDate (IDCode unitCode, StringRef unitName,
829
- sys::TimePoint<> outOfDateModTime,
830
- OutOfDateTriggerHintRef hint,
824
+ OutOfDateFileTriggerRef trigger,
831
825
bool synchronous) {
832
826
CanonicalFilePath MainFilePath;
833
827
std::string OutFileIdentifier;
@@ -859,15 +853,13 @@ void StoreUnitRepo::onUnitOutOfDate(IDCode unitCode, StringRef unitName,
859
853
CurrModTime,
860
854
SymProviderKind
861
855
};
862
- Delegate->unitIsOutOfDate (unitInfo, outOfDateModTime, hint , synchronous);
856
+ Delegate->unitIsOutOfDate (unitInfo, trigger , synchronous);
863
857
}
864
858
865
859
for (IDCode depUnit : dependentUnits) {
866
860
if (auto monitor = getUnitMonitor (depUnit)) {
867
- if (monitor->getModTime () < outOfDateModTime)
868
- monitor->markOutOfDate (outOfDateModTime,
869
- DependentUnitOutOfDateTriggerHint::create (unitName, hint),
870
- synchronous);
861
+ if (monitor->getModTime () < trigger->getModTime ())
862
+ monitor->markOutOfDate (trigger, synchronous);
871
863
}
872
864
}
873
865
}
@@ -957,12 +949,9 @@ void UnitMonitor::initialize(IDCode unitCode,
957
949
this ->ModTime = modTime;
958
950
for (IDCode unitDepCode : userUnitDepends) {
959
951
if (auto depMonitor = unitRepo->getUnitMonitor (unitDepCode)) {
960
- for (const auto &trigger : depMonitor->getOutOfDateTriggers ()) {
961
- if (trigger.outOfDateModTime > modTime) {
962
- markOutOfDate (trigger.outOfDateModTime ,
963
- DependentUnitOutOfDateTriggerHint::create (depMonitor->getUnitName (),
964
- trigger.hint ));
965
- }
952
+ for (const auto &trigger : depMonitor->getUnorderedOutOfDateTriggers ()) {
953
+ if (trigger->getModTime () > modTime)
954
+ markOutOfDate (trigger);
966
955
}
967
956
}
968
957
}
@@ -975,43 +964,63 @@ void UnitMonitor::initialize(IDCode unitCode,
975
964
}
976
965
auto mostRecentFileAndTime = getMostRecentModTime (filePaths);
977
966
if (mostRecentFileAndTime.second > modTime) {
978
- markOutOfDate (mostRecentFileAndTime.second , DependentFileOutOfDateTriggerHint::create (mostRecentFileAndTime.first ));
967
+ auto trigger = OutOfDateFileTrigger::create (mostRecentFileAndTime.first ,
968
+ mostRecentFileAndTime.second );
969
+ markOutOfDate (trigger);
979
970
}
980
971
}
981
972
}
982
973
983
974
UnitMonitor::~UnitMonitor () {}
984
975
985
- std::vector<UnitMonitor::OutOfDateTrigger> UnitMonitor::getOutOfDateTriggers () const {
976
+ std::vector<OutOfDateFileTriggerRef>
977
+ UnitMonitor::getUnorderedOutOfDateTriggers () const {
986
978
sys::ScopedLock L (StateMtx);
987
- std::vector<OutOfDateTrigger > triggers;
979
+ std::vector<OutOfDateFileTriggerRef > triggers;
988
980
for (const auto &entry : OutOfDateTriggers) {
989
- triggers.push_back (entry.getValue () );
981
+ triggers.push_back (entry.second );
990
982
}
991
983
return triggers;
992
984
}
993
985
994
- void UnitMonitor::checkForOutOfDate (sys::TimePoint<> outOfDateModTime, StringRef filePath, bool synchronous) {
986
+ void UnitMonitor::checkForOutOfDate (sys::TimePoint<> outOfDateModTime,
987
+ StringRef filePath, bool synchronous) {
995
988
sys::ScopedLock L (StateMtx);
996
989
auto findIt = OutOfDateTriggers.find (filePath);
997
- if (findIt != OutOfDateTriggers.end () && findIt->getValue ().outOfDateModTime >= outOfDateModTime) {
990
+ if (findIt != OutOfDateTriggers.end () &&
991
+ findIt->second ->getModTime () >= outOfDateModTime) {
998
992
return ; // already marked as out-of-date related to this trigger file.
999
993
}
1000
- if (ModTime < outOfDateModTime)
1001
- markOutOfDate (outOfDateModTime, DependentFileOutOfDateTriggerHint::create (filePath), synchronous);
994
+ if (ModTime < outOfDateModTime) {
995
+ markOutOfDate (OutOfDateFileTrigger::create (filePath, outOfDateModTime),
996
+ synchronous);
997
+ }
1002
998
}
1003
999
1004
- void UnitMonitor::markOutOfDate (sys::TimePoint<> outOfDateModTime, OutOfDateTriggerHintRef hint, bool synchronous) {
1000
+ void UnitMonitor::markOutOfDate (OutOfDateFileTriggerRef trigger,
1001
+ bool synchronous) {
1005
1002
{
1003
+ // Note we have to be careful with the memory management here since the
1004
+ // key for OutOfDateTriggers is a reference into the stored trigger value.
1006
1005
sys::ScopedLock L (StateMtx);
1007
- OutOfDateTrigger trigger{ hint, outOfDateModTime};
1008
- auto &entry = OutOfDateTriggers[trigger.getTriggerFilePath ()];
1009
- if (entry.outOfDateModTime >= outOfDateModTime)
1010
- return ; // already marked as out-of-date related to this trigger file.
1011
- entry = trigger;
1006
+ auto iterAndInserted =
1007
+ OutOfDateTriggers.try_emplace (trigger->getPathRef (), trigger);
1008
+ if (!iterAndInserted.second ) {
1009
+ // If we have the same or newer mod time for this trigger already stored,
1010
+ // we've seen it before, and have already informed the delegate that the
1011
+ // unit is out of date.
1012
+ auto iter = iterAndInserted.first ;
1013
+ if (iter->second ->getModTime () >= trigger->getModTime ())
1014
+ return ;
1015
+
1016
+ // We have a newer mod time for the file, update our trigger, and inform
1017
+ // the delegate that the unit is out of date. Note we need to overwrite
1018
+ // the key as well since it references the path stored in the trigger.
1019
+ *iter = {trigger->getPathRef (), trigger};
1020
+ }
1012
1021
}
1013
1022
if (auto localUnitRepo = UnitRepo.lock ())
1014
- localUnitRepo->onUnitOutOfDate (UnitCode, UnitName, outOfDateModTime, hint , synchronous);
1023
+ localUnitRepo->onUnitOutOfDate (UnitCode, UnitName, trigger , synchronous);
1015
1024
}
1016
1025
1017
1026
std::pair<StringRef, sys::TimePoint<>> UnitMonitor::getMostRecentModTime (ArrayRef<StringRef> filePaths) {
0 commit comments