Commit 06c344cc authored by Adam Reichold's avatar Adam Reichold

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).
parent 22ea442d
Pipeline #4616 passed with stage
in 4 minutes and 28 seconds
......@@ -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) {
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment