Skip to content

Commit ab8d76e

Browse files
committed
Merge branch 'vtjnash-jn/faster'
2 parents 9065ef3 + e0893a6 commit ab8d76e

5 files changed

Lines changed: 204 additions & 162 deletions

File tree

src/definition.cpp

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <algorithm>
1717
#include <iterator>
18+
#include <mutex>
1819
#include <unordered_map>
1920
#include <string>
2021
#include <optional>
@@ -53,6 +54,16 @@
5354

5455
//-----------------------------------------------------------------------------------------
5556

57+
/** once_flag wrapper that is copyable (copy default-initializes the flag) and resettable. */
58+
struct ResettableOnce
59+
{
60+
mutable std::once_flag flag;
61+
ResettableOnce() = default;
62+
ResettableOnce(const ResettableOnce &) {} // copy: leave flag in not-yet-called state
63+
ResettableOnce &operator=(const ResettableOnce &) { return *this; }
64+
void reset() { flag.~once_flag(); new (&flag) std::once_flag{}; }
65+
};
66+
5667
/** Private data associated with a Symbol DefinitionImpl object. */
5768
class DefinitionImpl::Private
5869
{
@@ -81,6 +92,7 @@ class DefinitionImpl::Private
8192
QCString localName; // local (unqualified) name of the definition
8293
// in the future m_name should become m_localName
8394
QCString qualifiedName;
95+
ResettableOnce qualifiedNameOnce;
8496
QCString ref; // reference to external documentation
8597

8698
bool hidden = FALSE;
@@ -1268,47 +1280,28 @@ void DefinitionImpl::addInnerCompound(Definition *)
12681280
err("DefinitionImpl::addInnerCompound() called\n");
12691281
}
12701282

1271-
static std::recursive_mutex g_qualifiedNameMutex;
1272-
12731283
QCString DefinitionImpl::qualifiedName() const
12741284
{
1275-
std::lock_guard<std::recursive_mutex> lock(g_qualifiedNameMutex);
1276-
if (!p->qualifiedName.isEmpty())
1277-
{
1278-
return p->qualifiedName;
1279-
}
1280-
1281-
//printf("start %s::qualifiedName() localName=%s\n",qPrint(name()),qPrint(p->localName));
1282-
if (p->outerScope==nullptr)
1285+
std::call_once(p->qualifiedNameOnce.flag, [this]()
12831286
{
1284-
if (p->localName=="<globalScope>")
1287+
//printf("start %s::qualifiedName() localName=%s\n",qPrint(name()),qPrint(p->localName));
1288+
if (p->outerScope==nullptr || p->outerScope->name()=="<globalScope>")
12851289
{
1286-
return "";
1290+
p->qualifiedName = (p->localName=="<globalScope>") ? QCString() : p->localName;
12871291
}
12881292
else
12891293
{
1290-
return p->localName;
1294+
p->qualifiedName = p->outerScope->qualifiedName()+
1295+
getLanguageSpecificSeparator(getLanguage())+
1296+
p->localName;
12911297
}
1292-
}
1293-
1294-
if (p->outerScope->name()=="<globalScope>")
1295-
{
1296-
p->qualifiedName = p->localName;
1297-
}
1298-
else
1299-
{
1300-
p->qualifiedName = p->outerScope->qualifiedName()+
1301-
getLanguageSpecificSeparator(getLanguage())+
1302-
p->localName;
1303-
}
1304-
//printf("end %s::qualifiedName()=%s\n",qPrint(name()),qPrint(p->qualifiedName));
1305-
//count--;
1298+
//printf("end %s::qualifiedName()=%s\n",qPrint(name()),qPrint(p->qualifiedName));
1299+
});
13061300
return p->qualifiedName;
13071301
}
13081302

13091303
void DefinitionImpl::setOuterScope(Definition *d)
13101304
{
1311-
std::lock_guard<std::recursive_mutex> lock(g_qualifiedNameMutex);
13121305
//printf("%s::setOuterScope(%s)\n",qPrint(name()),d?qPrint(d->name()):"<none>");
13131306
Definition *outerScope = p->outerScope;
13141307
bool found=false;
@@ -1321,6 +1314,7 @@ void DefinitionImpl::setOuterScope(Definition *d)
13211314
if (!found)
13221315
{
13231316
p->qualifiedName.clear(); // flush cached scope name
1317+
p->qualifiedNameOnce.reset();
13241318
p->outerScope = d;
13251319
}
13261320
p->hidden = p->hidden || d->isHidden();

src/doxygen.cpp

Lines changed: 4 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,6 @@ bool Doxygen::parseSourcesNeeded = FALSE;
164164
SearchIndexIntf Doxygen::searchIndex;
165165
SymbolMap<Definition>*Doxygen::symbolMap;
166166
ClangUsrMap *Doxygen::clangUsrMap = nullptr;
167-
Cache<std::string,LookupInfo> *Doxygen::typeLookupCache;
168-
Cache<std::string,LookupInfo> *Doxygen::symbolLookupCache;
169167
DirLinkedMap *Doxygen::dirLinkedMap;
170168
DirRelationLinkedMap Doxygen::dirRelations;
171169
ParserManager *Doxygen::parserManager = nullptr;
@@ -9464,19 +9462,7 @@ static void flushCachedTemplateRelations()
94649462
// as there can be new template instances in the inheritance path
94659463
// to this class. Optimization: only remove those classes that
94669464
// have inheritance instances as direct or indirect sub classes.
9467-
StringVector elementsToRemove;
9468-
for (const auto &ci : *Doxygen::typeLookupCache)
9469-
{
9470-
const LookupInfo &li = ci.second;
9471-
if (li.definition)
9472-
{
9473-
elementsToRemove.push_back(ci.first);
9474-
}
9475-
}
9476-
for (const auto &k : elementsToRemove)
9477-
{
9478-
Doxygen::typeLookupCache->remove(k);
9479-
}
9465+
SymbolResolver::clearTypeLookupCache(SymbolResolver::ClearScope::Classes);
94809466

94819467
// remove all cached typedef resolutions whose target is a
94829468
// template class as this may now be a template instance
@@ -9523,34 +9509,8 @@ static void flushUnresolvedRelations()
95239509
// class A { class I {} };
95249510
// class B : public A {};
95259511
// class C : public B::I {};
9512+
SymbolResolver::clearTypeLookupCache(SymbolResolver::ClearScope::Unresolved);
95269513

9527-
StringVector elementsToRemove;
9528-
for (const auto &ci : *Doxygen::typeLookupCache)
9529-
{
9530-
const LookupInfo &li = ci.second;
9531-
if (li.definition==nullptr && li.typeDef==nullptr)
9532-
{
9533-
elementsToRemove.push_back(ci.first);
9534-
}
9535-
}
9536-
for (const auto &k : elementsToRemove)
9537-
{
9538-
Doxygen::typeLookupCache->remove(k);
9539-
}
9540-
9541-
// for each global function name
9542-
for (const auto &fn : *Doxygen::functionNameLinkedMap)
9543-
{
9544-
// for each function with that name
9545-
for (const auto &ifmd : *fn)
9546-
{
9547-
MemberDefMutable *fmd = toMemberDefMutable(ifmd.get());
9548-
if (fmd)
9549-
{
9550-
fmd->invalidateCachedArgumentTypes();
9551-
}
9552-
}
9553-
}
95549514
// for each class method name
95559515
for (const auto &nm : *Doxygen::memberNameLinkedMap)
95569516
{
@@ -11552,22 +11512,6 @@ void cleanUpDoxygen()
1155211512
delete Doxygen::symbolMap;
1155311513
}
1155411514

11555-
static int computeIdealCacheParam(size_t v)
11556-
{
11557-
//printf("computeIdealCacheParam(v=%u)\n",v);
11558-
11559-
int r=0;
11560-
while (v!=0)
11561-
{
11562-
v >>= 1;
11563-
r++;
11564-
}
11565-
// r = log2(v)
11566-
11567-
// convert to a valid cache size value
11568-
return std::max(0,std::min(r-16,9));
11569-
}
11570-
1157111515
void readConfiguration(int argc, char **argv)
1157211516
{
1157311517
QCString versionString = getFullVersion();
@@ -12556,14 +12500,6 @@ void parseInput()
1255612500
* Initialize global lists and dictionaries
1255712501
**************************************************************************/
1255812502

12559-
// also scale lookup cache with SYMBOL_CACHE_SIZE
12560-
int cacheSize = Config_getInt(LOOKUP_CACHE_SIZE);
12561-
if (cacheSize<0) cacheSize=0;
12562-
if (cacheSize>9) cacheSize=9;
12563-
uint32_t lookupSize = 65536 << cacheSize;
12564-
Doxygen::typeLookupCache = new Cache<std::string,LookupInfo>(lookupSize);
12565-
Doxygen::symbolLookupCache = new Cache<std::string,LookupInfo>(lookupSize);
12566-
1256712503
#ifdef HAS_SIGNALS
1256812504
signal(SIGINT, stopDoxygen);
1256912505
#endif
@@ -12848,7 +12784,7 @@ void parseInput()
1284812784
// calling buildClassList may result in cached relations that
1284912785
// become invalid after resolveClassNestingRelations(), that's why
1285012786
// we need to clear the cache here
12851-
Doxygen::typeLookupCache->clear();
12787+
SymbolResolver::clearTypeLookupCache(SymbolResolver::ClearScope::All);
1285212788
// we don't need the list of using declaration anymore
1285312789
g_usingDeclarations.clear();
1285412790

@@ -13488,23 +13424,7 @@ void generateOutput()
1348813424
g_outputList->cleanup();
1348913425
cleanupInlineGraph();
1349013426

13491-
msg("type lookup cache used {}/{} hits={} misses={}\n",
13492-
Doxygen::typeLookupCache->size(),
13493-
Doxygen::typeLookupCache->capacity(),
13494-
Doxygen::typeLookupCache->hits(),
13495-
Doxygen::typeLookupCache->misses());
13496-
msg("symbol lookup cache used {}/{} hits={} misses={}\n",
13497-
Doxygen::symbolLookupCache->size(),
13498-
Doxygen::symbolLookupCache->capacity(),
13499-
Doxygen::symbolLookupCache->hits(),
13500-
Doxygen::symbolLookupCache->misses());
13501-
int typeCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::typeLookupCache->misses()*2/3)); // part of the cache is flushed, hence the 2/3 correction factor
13502-
int symbolCacheParam = computeIdealCacheParam(static_cast<size_t>(Doxygen::symbolLookupCache->misses()));
13503-
int cacheParam = std::max(typeCacheParam,symbolCacheParam);
13504-
if (cacheParam>Config_getInt(LOOKUP_CACHE_SIZE))
13505-
{
13506-
msg("Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is {} at the cost of higher memory usage.\n",cacheParam);
13507-
}
13427+
SymbolResolver::showCacheUsage();
1350813428

1350913429
if (Debug::isFlagSet(Debug::Time))
1351013430
{

src/doxygen.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,6 @@ class Doxygen
123123
static SearchIndexIntf searchIndex;
124124
static SymbolMap<Definition> *symbolMap;
125125
static ClangUsrMap *clangUsrMap;
126-
static Cache<std::string,LookupInfo> *typeLookupCache;
127-
static Cache<std::string,LookupInfo> *symbolLookupCache;
128126
static DirLinkedMap *dirLinkedMap;
129127
static DirRelationLinkedMap dirRelations;
130128
static ParserManager *parserManager;

0 commit comments

Comments
 (0)