summaryrefslogtreecommitdiffstats
path: root/common/typeindex.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-10-13 18:38:35 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2018-02-11 23:03:17 +0100
commit6051c1247cde61bcc8e483eb4166e5a297c0ecc6 (patch)
treedf3aba1ef4011f2640b17c8cf7a9b106933231ab /common/typeindex.cpp
parent8740a007515dcf1b315d69ab5c64fcfd40ec980c (diff)
downloadsink-6051c1247cde61bcc8e483eb4166e5a297c0ecc6.tar.gz
sink-6051c1247cde61bcc8e483eb4166e5a297c0ecc6.zip
Xapian based fulltext indexing
This cuts into the sync performance by about 40%, but gives us fast fulltext searching for all local content.
Diffstat (limited to 'common/typeindex.cpp')
-rw-r--r--common/typeindex.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/common/typeindex.cpp b/common/typeindex.cpp
index 0228ecb..f2c67a1 100644
--- a/common/typeindex.cpp
+++ b/common/typeindex.cpp
@@ -20,6 +20,7 @@
20 20
21#include "log.h" 21#include "log.h"
22#include "index.h" 22#include "index.h"
23#include "fulltextindex.h"
23#include <QDateTime> 24#include <QDateTime>
24#include <QDataStream> 25#include <QDataStream>
25 26
@@ -158,7 +159,7 @@ void TypeIndex::addPropertyWithSorting<ApplicationDomain::Reference, QDateTime>(
158 addPropertyWithSorting<QByteArray, QDateTime>(property, sortProperty); 159 addPropertyWithSorting<QByteArray, QDateTime>(property, sortProperty);
159} 160}
160 161
161void TypeIndex::updateIndex(bool add, const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction) 162void TypeIndex::updateIndex(bool add, const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
162{ 163{
163 for (const auto &property : mProperties) { 164 for (const auto &property : mProperties) {
164 const auto value = entity.getProperty(property); 165 const auto value = entity.getProperty(property);
@@ -172,7 +173,7 @@ void TypeIndex::updateIndex(bool add, const QByteArray &identifier, const Sink::
172 indexer(add, identifier, value, sortValue, transaction); 173 indexer(add, identifier, value, sortValue, transaction);
173 } 174 }
174 for (const auto &indexer : mCustomIndexer) { 175 for (const auto &indexer : mCustomIndexer) {
175 indexer->setup(this, &transaction); 176 indexer->setup(this, &transaction, resourceInstanceId);
176 if (add) { 177 if (add) {
177 indexer->add(entity); 178 indexer->add(entity);
178 } else { 179 } else {
@@ -182,14 +183,28 @@ void TypeIndex::updateIndex(bool add, const QByteArray &identifier, const Sink::
182 183
183} 184}
184 185
185void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction) 186void TypeIndex::commitTransaction()
186{ 187{
187 updateIndex(true, identifier, entity, transaction); 188 for (const auto &indexer : mCustomIndexer) {
189 indexer->commitTransaction();
190 }
188} 191}
189 192
190void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction) 193void TypeIndex::abortTransaction()
191{ 194{
192 updateIndex(false, identifier, entity, transaction); 195 for (const auto &indexer : mCustomIndexer) {
196 indexer->abortTransaction();
197 }
198}
199
200void TypeIndex::add(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
201{
202 updateIndex(true, identifier, entity, transaction, resourceInstanceId);
203}
204
205void TypeIndex::remove(const QByteArray &identifier, const Sink::ApplicationDomain::ApplicationDomainType &entity, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
206{
207 updateIndex(false, identifier, entity, transaction, resourceInstanceId);
193} 208}
194 209
195static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filter) 210static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filter)
@@ -211,13 +226,22 @@ static QVector<QByteArray> indexLookup(Index &index, QueryBase::Comparator filte
211 return keys; 226 return keys;
212} 227}
213 228
214QVector<QByteArray> TypeIndex::query(const Sink::QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction) 229QVector<QByteArray> TypeIndex::query(const Sink::QueryBase &query, QSet<QByteArray> &appliedFilters, QByteArray &appliedSorting, Sink::Storage::DataStore::Transaction &transaction, const QByteArray &resourceInstanceId)
215{ 230{
216 QVector<QByteArray> keys; 231 const auto baseFilters = query.getBaseFilters();
232 for (auto it = baseFilters.constBegin(); it != baseFilters.constEnd(); it++) {
233 if (it.value().comparator == QueryBase::Comparator::Fulltext) {
234 FulltextIndex fulltextIndex{resourceInstanceId};
235 const auto keys = fulltextIndex.lookup(it.value().value.toString());
236 appliedFilters << it.key();
237 return keys;
238 }
239 }
240
217 for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) { 241 for (auto it = mSortedProperties.constBegin(); it != mSortedProperties.constEnd(); it++) {
218 if (query.hasFilter(it.key()) && query.sortProperty() == it.value()) { 242 if (query.hasFilter(it.key()) && query.sortProperty() == it.value()) {
219 Index index(indexName(it.key(), it.value()), transaction); 243 Index index(indexName(it.key(), it.value()), transaction);
220 keys << indexLookup(index, query.getFilter(it.key())); 244 const auto keys = indexLookup(index, query.getFilter(it.key()));
221 appliedFilters << it.key(); 245 appliedFilters << it.key();
222 appliedSorting = it.value(); 246 appliedSorting = it.value();
223 SinkTraceCtx(mLogCtx) << "Index lookup on " << it.key() << it.value() << " found " << keys.size() << " keys."; 247 SinkTraceCtx(mLogCtx) << "Index lookup on " << it.key() << it.value() << " found " << keys.size() << " keys.";
@@ -227,14 +251,14 @@ QVector<QByteArray> TypeIndex::query(const Sink::QueryBase &query, QSet<QByteArr
227 for (const auto &property : mProperties) { 251 for (const auto &property : mProperties) {
228 if (query.hasFilter(property)) { 252 if (query.hasFilter(property)) {
229 Index index(indexName(property), transaction); 253 Index index(indexName(property), transaction);
230 keys << indexLookup(index, query.getFilter(property)); 254 const auto keys = indexLookup(index, query.getFilter(property));
231 appliedFilters << property; 255 appliedFilters << property;
232 SinkTraceCtx(mLogCtx) << "Index lookup on " << property << " found " << keys.size() << " keys."; 256 SinkTraceCtx(mLogCtx) << "Index lookup on " << property << " found " << keys.size() << " keys.";
233 return keys; 257 return keys;
234 } 258 }
235 } 259 }
236 SinkTraceCtx(mLogCtx) << "No matching index"; 260 SinkTraceCtx(mLogCtx) << "No matching index";
237 return keys; 261 return {};
238} 262}
239 263
240QVector<QByteArray> TypeIndex::lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction) 264QVector<QByteArray> TypeIndex::lookup(const QByteArray &property, const QVariant &value, Sink::Storage::DataStore::Transaction &transaction)