[frameworks/kio] src/core: UDSEntry: size an entry for the fields it holds when loading it
Méven Car <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit cbf2013c5a51d6e78bf0491170373067417004c3 by Méven Car.
Committed on 29/07/2026 at 18:04.
Pushed by meven into branch 'master'.
UDSEntry: size an entry for the fields it holds when loading it
load() sized the two vectors of an entry from the count of its fields alone, giving the strings a
third of it and the numbers two thirds. A stat of a local file gives one string, the name, and eight
numbers, so the numbers grew past their room while the strings kept more than they needed.
The fields now go to buffers that live as long as the thread, so both counts are known before either
vector is sized. A listing of 200000 local files takes 400 bytes an entry rather than 528, and the
entries of the trash and recently used listings 697 rather than 793.
M +17 -7 src/core/udsentry.cpp
https://invent.kde.org/frameworks/kio/-/commit/cbf2013c5a51d6e78bf0491170373067417004c3
diff --git a/src/core/udsentry.cpp b/src/core/udsentry.cpp
index 1054756487..68cb2e214e 100644
--- a/src/core/udsentry.cpp
+++ b/src/core/udsentry.cpp
@@ -273,8 +273,12 @@ void UDSEntryPrivate::load(QDataStream &s)
quint32 size;
s >> size;
- reserveStrings(size / 3);
- reserveNumbers(size * 2 / 3);
+ // Buffers that live as long as the thread, so both counts are known before either vector of the
+ // entry is sized and each takes exactly what it holds.
+ thread_local std::vector<StringField> stagedStrings;
+ thread_local std::vector<NumberField> stagedNumbers;
+ stagedStrings.clear();
+ stagedNumbers.clear();
// We cache the loaded strings. Some of them, like, e.g., the user,
// will often be the same for many entries in a row. Caching them
@@ -296,9 +300,6 @@ void UDSEntryPrivate::load(QDataStream &s)
s >> uds;
if (uds & KIO::UDSEntry::UDS_STRING) {
- // If the QString is the same like the one we read for the
- // previous UDSEntry at the i-th position, use an implicitly
- // shared copy of the same QString to save memory.
s >> buffer;
QString &cachedString = cachedStrings[i];
@@ -306,15 +307,24 @@ void UDSEntryPrivate::load(QDataStream &s)
cachedString = buffer;
}
- insert(uds, cachedString);
+ stagedStrings.emplace_back(uds, cachedString);
} else if (uds & KIO::UDSEntry::UDS_NUMBER) {
long long value;
s >> value;
- insert(uds, value);
+ stagedNumbers.emplace_back(uds, value);
} else {
Q_ASSERT_X(false, "KIO::UDSEntry", "Found a field with an unexpected type");
}
}
+
+ stringStorage.reserve(stagedStrings.size());
+ for (StringField &field : stagedStrings) {
+ stringStorage.emplace_back(field.m_index, std::move(field.m_str));
+ }
+ numberStorage.reserve(stagedNumbers.size());
+ for (const NumberField &field : stagedNumbers) {
+ numberStorage.emplace_back(field.m_index, field.m_long);
+ }
}
QString UDSEntryPrivate::nameOfUdsField(uint field)