[poppler] poppler/Dict.cc poppler/Dict.h
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Sep 21 12:29:14 UTC 2018
poppler/Dict.cc | 24 ++++++++++++++----------
poppler/Dict.h | 2 +-
2 files changed, 15 insertions(+), 11 deletions(-)
New commits:
commit 06c344ccb8ccfafa9c506f40226ea2cce0e5f75c
Author: Adam Reichold <adam.reichold at t-online.de>
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
More information about the poppler
mailing list