Index: src/analyze/gui/locationdata.h =================================================================== --- src/analyze/gui/locationdata.h +++ src/analyze/gui/locationdata.h @@ -28,12 +28,15 @@ #include +using SymbolId = long; + struct Symbol { - Symbol(const QString& symbol = {}, const QString& binary = {}, const QString& path = {}) + Symbol(const QString& symbol = {}, const QString& binary = {}, const QString& path = {}, SymbolId symbolId = 0) : symbol(symbol) , binary(binary) , path(path) + , symbolId(symbolId) { } @@ -43,10 +46,12 @@ QString binary; // path to dso / executable QString path; + // ID + SymbolId symbolId; bool operator==(const Symbol& rhs) const { - return std::tie(symbol, binary, path) == std::tie(rhs.symbol, rhs.binary, rhs.path); + return symbolId == rhs.symbolId; } bool operator!=(const Symbol& rhs) const @@ -56,12 +61,12 @@ bool operator<(const Symbol& rhs) const { - return std::tie(symbol, binary, path) < std::tie(rhs.symbol, rhs.binary, rhs.path); + return symbolId < rhs.symbolId; } bool isValid() const { - return !symbol.isEmpty() || !binary.isEmpty() || !path.isEmpty(); + return symbolId > 0; } }; @@ -99,11 +104,7 @@ inline uint qHash(const Symbol& symbol, uint seed_ = 0) { - size_t seed = seed_; - boost::hash_combine(seed, qHash(symbol.symbol)); - boost::hash_combine(seed, qHash(symbol.binary)); - boost::hash_combine(seed, qHash(symbol.path)); - return seed; + return qHash(symbol.symbolId, seed_); } inline uint qHash(const FileLine& location, uint seed_ = 0) Index: src/analyze/gui/parser.cpp =================================================================== --- src/analyze/gui/parser.cpp +++ src/analyze/gui/parser.cpp @@ -77,20 +77,33 @@ if (binaryIt == m_pathToBinaries.end()) { binaryIt = m_pathToBinaries.insert(module, Util::basename(module)); } - return {{func(frame), *binaryIt, module}, {file(frame), frame.line}}; + const SymbolId id = ++m_nextSymbolId; + auto symbol = Symbol{func(frame), *binaryIt, module, id}; + const auto it = m_symbols.emplace(std::make_pair(std::move(symbol), id)).first; + return {it->first, {file(frame), frame.line}}; } void update(const vector& strings) { transform(strings.begin() + m_strings.size(), strings.end(), back_inserter(m_strings), [](const string& str) { return QString::fromStdString(str); }); } + struct SymbolCompare { + bool operator()(const Symbol &lhs, const Symbol &rhs) { + return std::tie(lhs.symbol, lhs.binary, lhs.path) < std::tie(rhs.symbol, rhs.binary, rhs.path); + } + }; + vector m_strings; // interned module basenames mutable QHash m_pathToBinaries; + // existing symbols + mutable std::map m_symbols; bool diffMode = false; + + mutable SymbolId m_nextSymbolId = 0; }; struct ChartMergeData