summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2018-07-28 22:29:35 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-07-28 22:29:35 +0200
commita24bf3db83d81d7d7677a1f0f750f208d32998a8 (patch)
tree0d3fa9da24d706c2e6b03e8bf0fd74a434ae871f
parent683ee2ec1d198a9f19572e42d78fa0b9939d7f10 (diff)
downloadsink-a24bf3db83d81d7d7677a1f0f750f208d32998a8.tar.gz
sink-a24bf3db83d81d7d7677a1f0f750f208d32998a8.zip
Avoid unnecessary Identifier conversions in performance ciritical code.
This fixes the performance regressions to a state where we are roughly at the same performance as pre Identifier (but not any better either).
-rw-r--r--common/datastorequery.cpp14
-rw-r--r--common/storage/entitystore.cpp12
-rw-r--r--common/storage/entitystore.h4
-rw-r--r--common/storage/key.cpp6
-rw-r--r--common/storage/key.h2
-rw-r--r--common/typeindex.cpp27
-rw-r--r--common/typeindex.h2
7 files changed, 40 insertions, 27 deletions
diff --git a/common/datastorequery.cpp b/common/datastorequery.cpp
index 52243da..43b4660 100644
--- a/common/datastorequery.cpp
+++ b/common/datastorequery.cpp
@@ -46,14 +46,10 @@ class Source : public FilterBase {
46 QVector<Identifier> mIncrementalIds; 46 QVector<Identifier> mIncrementalIds;
47 QVector<Identifier>::ConstIterator mIncrementalIt; 47 QVector<Identifier>::ConstIterator mIncrementalIt;
48 48
49 Source (const QVector<QByteArray> &ids, DataStoreQuery *store) 49 Source (const QVector<Identifier> &ids, DataStoreQuery *store)
50 : FilterBase(store), 50 : FilterBase(store),
51 mIds() 51 mIds(ids)
52 { 52 {
53 mIds.reserve(ids.size());
54 for (const auto &id : ids) {
55 mIds.append(Identifier::fromDisplayByteArray(id));
56 }
57 mIt = mIds.constBegin(); 53 mIt = mIds.constBegin();
58 } 54 }
59 55
@@ -614,7 +610,11 @@ void DataStoreQuery::setupQuery(const Sink::QueryBase &query_)
614 mSource = [&]() { 610 mSource = [&]() {
615 if (!query.ids().isEmpty()) { 611 if (!query.ids().isEmpty()) {
616 //We have a set of ids as a starting point 612 //We have a set of ids as a starting point
617 return Source::Ptr::create(query.ids().toVector(), this); 613 QVector<Identifier> ids;
614 for (const auto & id: query.ids()) {
615 ids.append(Identifier::fromDisplayByteArray(id));
616 }
617 return Source::Ptr::create(ids, this);
618 } else { 618 } else {
619 QSet<QByteArrayList> appliedFilters; 619 QSet<QByteArrayList> appliedFilters;
620 auto resultSet = mStore.indexLookup(mType, query, appliedFilters, appliedSorting); 620 auto resultSet = mStore.indexLookup(mType, query, appliedFilters, appliedSorting);
diff --git a/common/storage/entitystore.cpp b/common/storage/entitystore.cpp
index 71690fe..1ba7c6c 100644
--- a/common/storage/entitystore.cpp
+++ b/common/storage/entitystore.cpp
@@ -426,19 +426,19 @@ bool EntityStore::cleanupRevisions(qint64 revision)
426 return cleanupIsNecessary; 426 return cleanupIsNecessary;
427} 427}
428 428
429QVector<QByteArray> EntityStore::fullScan(const QByteArray &type) 429QVector<Identifier> EntityStore::fullScan(const QByteArray &type)
430{ 430{
431 SinkTraceCtx(d->logCtx) << "Looking for : " << type; 431 SinkTraceCtx(d->logCtx) << "Looking for : " << type;
432 if (!d->exists()) { 432 if (!d->exists()) {
433 SinkTraceCtx(d->logCtx) << "Database is not existing: " << type; 433 SinkTraceCtx(d->logCtx) << "Database is not existing: " << type;
434 return QVector<QByteArray>(); 434 return {};
435 } 435 }
436 //The scan can return duplicate results if we have multiple revisions, so we use a set to deduplicate. 436 //The scan can return duplicate results if we have multiple revisions, so we use a set to deduplicate.
437 QSet<QByteArray> keys; 437 QSet<Identifier> keys;
438 DataStore::mainDatabase(d->getTransaction(), type) 438 DataStore::mainDatabase(d->getTransaction(), type)
439 .scan(QByteArray(), 439 .scan(QByteArray(),
440 [&](const QByteArray &key, const QByteArray &value) -> bool { 440 [&](const QByteArray &key, const QByteArray &value) -> bool {
441 const auto uid = Sink::Storage::Key::fromInternalByteArray(key).identifier().toDisplayByteArray(); 441 const auto uid = Sink::Storage::Key::fromInternalByteArray(key).identifier();
442 if (keys.contains(uid)) { 442 if (keys.contains(uid)) {
443 //Not something that should persist if the replay works, so we keep a message for now. 443 //Not something that should persist if the replay works, so we keep a message for now.
444 SinkTraceCtx(d->logCtx) << "Multiple revisions for key: " << key; 444 SinkTraceCtx(d->logCtx) << "Multiple revisions for key: " << key;
@@ -452,11 +452,11 @@ QVector<QByteArray> EntityStore::fullScan(const QByteArray &type)
452 return keys.toList().toVector(); 452 return keys.toList().toVector();
453} 453}
454 454
455QVector<QByteArray> EntityStore::indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting) 455QVector<Identifier> EntityStore::indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting)
456{ 456{
457 if (!d->exists()) { 457 if (!d->exists()) {
458 SinkTraceCtx(d->logCtx) << "Database is not existing: " << type; 458 SinkTraceCtx(d->logCtx) << "Database is not existing: " << type;
459 return QVector<QByteArray>(); 459 return {};
460 } 460 }
461 return d->typeIndex(type).query(query, appliedFilters, appliedSorting, d->getTransaction(), d->resourceContext.instanceId()); 461 return d->typeIndex(type).query(query, appliedFilters, appliedSorting, d->getTransaction(), d->resourceContext.instanceId());
462} 462}
diff --git a/common/storage/entitystore.h b/common/storage/entitystore.h
index 619b884..7979798 100644
--- a/common/storage/entitystore.h
+++ b/common/storage/entitystore.h
@@ -57,8 +57,8 @@ public:
57 void abortTransaction(); 57 void abortTransaction();
58 bool hasTransaction() const; 58 bool hasTransaction() const;
59 59
60 QVector<QByteArray> fullScan(const QByteArray &type); 60 QVector<Sink::Storage::Identifier> fullScan(const QByteArray &type);
61 QVector<QByteArray> indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting); 61 QVector<Sink::Storage::Identifier> indexLookup(const QByteArray &type, const QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting);
62 QVector<Sink::Storage::Identifier> indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value); 62 QVector<Sink::Storage::Identifier> indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value);
63 void indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback); 63 void indexLookup(const QByteArray &type, const QByteArray &property, const QVariant &value, const std::function<void(const QByteArray &uid)> &callback);
64 template<typename EntityType, typename PropertyType> 64 template<typename EntityType, typename PropertyType>
diff --git a/common/storage/key.cpp b/common/storage/key.cpp
index 23d7a6a..2327061 100644
--- a/common/storage/key.cpp
+++ b/common/storage/key.cpp
@@ -26,6 +26,12 @@ using Sink::Storage::Identifier;
26using Sink::Storage::Key; 26using Sink::Storage::Key;
27using Sink::Storage::Revision; 27using Sink::Storage::Revision;
28 28
29
30uint Sink::Storage::qHash(const Sink::Storage::Identifier &identifier)
31{
32 return qHash(identifier.toInternalByteArray());
33}
34
29QDebug &operator<<(QDebug &dbg, const Identifier &id) 35QDebug &operator<<(QDebug &dbg, const Identifier &id)
30{ 36{
31 dbg << id.toDisplayString(); 37 dbg << id.toDisplayString();
diff --git a/common/storage/key.h b/common/storage/key.h
index 211aea7..baabe38 100644
--- a/common/storage/key.h
+++ b/common/storage/key.h
@@ -119,6 +119,8 @@ private:
119 Revision rev; 119 Revision rev;
120}; 120};
121 121
122SINK_EXPORT uint qHash(const Sink::Storage::Identifier &);
123
122} // namespace Storage 124} // namespace Storage
123} // namespace Sink 125} // namespace Sink
124 126
diff --git a/common/typeindex.cpp b/common/typeindex.cpp
index 47512e8..646a60f 100644
--- a/common/typeindex.cpp
+++ b/common/typeindex.cpp
@@ -265,10 +265,10 @@ void TypeIndex::remove(const Identifier &identifier, const Sink::ApplicationDoma
265 } 265 }
266} 266}
267 267
268static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filter, 268static QVector<Identifier> indexLookup(Index &index, QueryBase::Comparator filter,
269 std::function<QByteArray(const QVariant &)> valueToKey = getByteArray) 269 std::function<QByteArray(const QVariant &)> valueToKey = getByteArray)
270{ 270{
271 QVector<QByteArray> keys; 271 QVector<Identifier> keys;
272 QByteArrayList lookupKeys; 272 QByteArrayList lookupKeys;
273 if (filter.comparator == Query::Comparator::Equals) { 273 if (filter.comparator == Query::Comparator::Equals) {
274 lookupKeys << valueToKey(filter.value); 274 lookupKeys << valueToKey(filter.value);
@@ -283,7 +283,7 @@ static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filte
283 for (const auto &lookupKey : lookupKeys) { 283 for (const auto &lookupKey : lookupKeys) {
284 index.lookup(lookupKey, 284 index.lookup(lookupKey,
285 [&](const QByteArray &value) { 285 [&](const QByteArray &value) {
286 keys << Identifier::fromInternalByteArray(value).toDisplayByteArray(); 286 keys << Identifier::fromInternalByteArray(value);
287 }, 287 },
288 [lookupKey](const Index::Error &error) { 288 [lookupKey](const Index::Error &error) {
289 SinkWarning() << "Lookup error in index: " << error.message << lookupKey; 289 SinkWarning() << "Lookup error in index: " << error.message << lookupKey;
@@ -293,7 +293,7 @@ static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filte
293 return keys; 293 return keys;
294} 294}
295 295
296static QVector<QByteArray> sortedIndexLookup(Index &index, QueryBase::Comparator filter) 296static QVector<Identifier> sortedIndexLookup(Index &index, QueryBase::Comparator filter)
297{ 297{
298 if (filter.comparator == Query::Comparator::In || filter.comparator == Query::Comparator::Contains) { 298 if (filter.comparator == Query::Comparator::In || filter.comparator == Query::Comparator::Contains) {
299 SinkWarning() << "In and Contains comparison not supported on sorted indexes"; 299 SinkWarning() << "In and Contains comparison not supported on sorted indexes";
@@ -303,7 +303,7 @@ static QVector<QByteArray> sortedIndexLookup(Index &index, QueryBase::Comparator
303 return indexLookup(index, filter, toSortableByteArray); 303 return indexLookup(index, filter, toSortableByteArray);
304 } 304 }
305 305
306 QVector<QByteArray> keys; 306 QVector<Identifier> keys;
307 307
308 QByteArray lowerBound, upperBound; 308 QByteArray lowerBound, upperBound;
309 auto bounds = filter.value.value<QVariantList>(); 309 auto bounds = filter.value.value<QVariantList>();
@@ -318,7 +318,7 @@ static QVector<QByteArray> sortedIndexLookup(Index &index, QueryBase::Comparator
318 318
319 index.rangeLookup(lowerBound, upperBound, 319 index.rangeLookup(lowerBound, upperBound,
320 [&](const QByteArray &value) { 320 [&](const QByteArray &value) {
321 keys << Identifier::fromInternalByteArray(value).toDisplayByteArray(); 321 keys << Identifier::fromInternalByteArray(value);
322 }, 322 },
323 [bounds](const Index::Error &error) { 323 [bounds](const Index::Error &error) {
324 SinkWarning() << "Lookup error in index:" << error.message 324 SinkWarning() << "Lookup error in index:" << error.message
@@ -328,14 +328,14 @@ static QVector<QByteArray> sortedIndexLookup(Index &index, QueryBase::Comparator
328 return keys; 328 return keys;
329} 329}
330 330
331static QVector<QByteArray> sampledIndexLookup(Index &index, QueryBase::Comparator filter) 331static QVector<Identifier> sampledIndexLookup(Index &index, QueryBase::Comparator filter)
332{ 332{
333 if (filter.comparator != Query::Comparator::Overlap) { 333 if (filter.comparator != Query::Comparator::Overlap) {
334 SinkWarning() << "Comparisons other than Overlap not supported on sampled period indexes"; 334 SinkWarning() << "Comparisons other than Overlap not supported on sampled period indexes";
335 return {}; 335 return {};
336 } 336 }
337 337
338 QVector<QByteArray> keys; 338 QVector<Identifier> keys;
339 339
340 auto bounds = filter.value.value<QVariantList>(); 340 auto bounds = filter.value.value<QVariantList>();
341 341
@@ -349,7 +349,7 @@ static QVector<QByteArray> sampledIndexLookup(Index &index, QueryBase::Comparato
349 349
350 index.rangeLookup(lowerBucket, upperBucket, 350 index.rangeLookup(lowerBucket, upperBucket,
351 [&](const QByteArray &value) { 351 [&](const QByteArray &value) {
352 keys << Identifier::fromInternalByteArray(value).toDisplayByteArray(); 352 keys << Identifier::fromInternalByteArray(value);
353 }, 353 },
354 [bounds](const Index::Error &error) { 354 [bounds](const Index::Error &error) {
355 SinkWarning() << "Lookup error in index:" << error.message 355 SinkWarning() << "Lookup error in index:" << error.message
@@ -359,13 +359,18 @@ static QVector<QByteArray> sampledIndexLookup(Index &index, QueryBase::Comparato
359 return keys; 359 return keys;
360} 360}
361 361
362QVector<QByteArray> TypeIndex::query(const Sink::QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId) 362QVector<Identifier> TypeIndex::query(const Sink::QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
363{ 363{
364 const auto baseFilters = query.getBaseFilters(); 364 const auto baseFilters = query.getBaseFilters();
365 for (auto it = baseFilters.constBegin(); it != baseFilters.constEnd(); it++) { 365 for (auto it = baseFilters.constBegin(); it != baseFilters.constEnd(); it++) {
366 if (it.value().comparator == QueryBase::Comparator::Fulltext) { 366 if (it.value().comparator == QueryBase::Comparator::Fulltext) {
367 FulltextIndex fulltextIndex{resourceInstanceId}; 367 FulltextIndex fulltextIndex{resourceInstanceId};
368 const auto keys = fulltextIndex.lookup(it.value().value.toString()); 368 QVector<Identifier> keys;
369 const auto ids = fulltextIndex.lookup(it.value().value.toString());
370 keys.reserve(ids.size());
371 for (const auto &id : ids) {
372 keys.append(Identifier::fromDisplayByteArray(id));
373 }
369 appliedFilters << it.key(); 374 appliedFilters << it.key();
370 SinkTraceCtx(mLogCtx) << "Fulltext index lookup found " << keys.size() << " keys."; 375 SinkTraceCtx(mLogCtx) << "Fulltext index lookup found " << keys.size() << " keys.";
371 return keys; 376 return keys;
diff --git a/common/typeindex.h b/common/typeindex.h
index f2cabaf..875eb7a 100644
--- a/common/typeindex.h
+++ b/common/typeindex.h
@@ -94,7 +94,7 @@ public:
94 void modify(const Sink::Storage::Identifier &identifier, const Sink::ApplicationDomain::ApplicationDomainType &oldEntity, const Sink::ApplicationDomain::ApplicationDomainType &newEntity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId); 94 void modify(const Sink::Storage::Identifier &identifier, const Sink::ApplicationDomain::ApplicationDomainType &oldEntity, const Sink::ApplicationDomain::ApplicationDomainType &newEntity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId);
95 void remove(const Sink::Storage::Identifier &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId); 95 void remove(const Sink::Storage::Identifier &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId);
96 96
97 QVector<QByteArray> query(const Sink::QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId); 97 QVector<Sink::Storage::Identifier> query(const Sink::QueryBase &query, QSet<QByteArrayList> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId);
98 QVector<Sink::Storage::Identifier> lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction); 98 QVector<Sink::Storage::Identifier> lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction);
99 99
100 template <typename Left, typename Right> 100 template <typename Left, typename Right>