poppler/Dict.cc | 24 ++++++++++++++---------- poppler/Dict.h | 2 +- 2 files changed, 15 insertions(+), 11 deletions(-)
New commits: commit 06c344ccb8ccfafa9c506f40226ea2cce0e5f75c Author: Adam Reichold <[email protected]> Date: Fri Sep 21 09:43:40 2018 +0200 Use deferred sorting with Dict again to avoid performance regression This tries to move sorting a Dict into the first find call again, but tries harder to make the double-checked locking work correctly so that at least concurrent calls to find are correct (but concurrent calls to find and add, set or remove are still not allowed). diff --git a/poppler/Dict.cc b/poppler/Dict.cc index 400b5885..0a0ceab3 100644 --- a/poppler/Dict.cc +++ b/poppler/Dict.cc @@ -85,7 +85,7 @@ Dict::Dict(const Dict* dictA) { entries.emplace_back(entry.first, entry.second.copy()); } - sorted = dictA->sorted; + sorted = dictA->sorted.load(); } Dict *Dict::copy(XRef *xrefA) const { @@ -108,20 +108,24 @@ Dict::~Dict() { void Dict::add(const char *key, Object &&val) { dictLocker(); + entries.emplace_back(key, std::move(val)); + sorted = false; +} + +inline const Dict::DictEntry *Dict::find(const char *key) const { if (entries.size() >= SORT_LENGTH_LOWER_LIMIT) { if (!sorted) { - std::sort(entries.begin(), entries.end(), CmpDictEntry{}); - sorted = true; + dictLocker(); + if (!sorted) { + auto& entries = const_cast<std::vector<DictEntry>&>(this->entries); + auto& sorted = const_cast<std::atomic_bool&>(this->sorted); + + std::sort(entries.begin(), entries.end(), CmpDictEntry{}); + sorted = true; + } } - const auto pos = std::upper_bound(entries.begin(), entries.end(), key, CmpDictEntry{}); - entries.emplace(pos, key, std::move(val)); - } else { - entries.emplace_back(key, std::move(val)); - sorted = false; } -} -inline const Dict::DictEntry *Dict::find(const char *key) const { if (sorted) { const auto pos = std::lower_bound(entries.begin(), entries.end(), key, CmpDictEntry{}); if (pos != entries.end() && pos->first == key) { diff --git a/poppler/Dict.h b/poppler/Dict.h index d7ade695..a4fd1c56 100644 --- a/poppler/Dict.h +++ b/poppler/Dict.h @@ -110,7 +110,7 @@ private: using DictEntry = std::pair<std::string, Object>; struct CmpDictEntry; - bool sorted; + std::atomic_bool sorted; XRef *xref; // the xref table for this PDF file std::vector<DictEntry> entries; std::atomic_int ref; // reference count _______________________________________________ poppler mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/poppler
