--- a/src/index/fsindexer.cpp
+++ b/src/index/fsindexer.cpp
@@ -66,10 +66,23 @@
FsIndexer::FsIndexer(RclConfig *cnf, Rcl::Db *db, DbIxStatusUpdater *updfunc)
: m_config(cnf), m_db(db), m_updater(updfunc), m_missing(new FIMissingStore)
+#ifdef IDX_THREADS
+ , m_wqueue(10)
+#endif // IDX_THREADS
{
m_havelocalfields = m_config->hasNameAnywhere("localfields");
+#ifdef IDX_THREADS
+ if (!m_wqueue.start(FsIndexerIndexWorker, this)) {
+ LOGERR(("FsIndexer::FsIndexer: worker start failed\n"));
+ return;
+ }
+#endif // IDX_THREADS
}
FsIndexer::~FsIndexer() {
+#ifdef IDX_THREADS
+ void *status = m_wqueue.setTerminateAndWait();
+ LOGERR(("FsIndexer: worker status: %ld\n", long(status)));
+#endif // IDX_THREADS
delete m_missing;
}
@@ -127,6 +140,9 @@
}
}
+#ifdef IDX_THREADS
+ m_wqueue.waitIdle();
+#endif // IDX_THREADS
string missing;
FileInterner::getMissingDescription(m_missing, missing);
if (!missing.empty()) {
@@ -288,6 +304,28 @@
sprintf(cbuf, OFFTPC "%ld", stp->st_size, (long)stp->RCL_STTIME);
out = cbuf;
}
+
+#ifdef IDX_THREADS
+void *FsIndexerIndexWorker(void * fsp)
+{
+ FsIndexer *fip = (FsIndexer*)fsp;
+ WorkQueue<IndexingTask*> *tqp = &fip->m_wqueue;
+ IndexingTask *tsk;
+ for (;;) {
+ if (!tqp->take(&tsk)) {
+ tqp->workerExit();
+ return (void*)1;
+ }
+ LOGDEB(("FsIndexerIndexWorker: got task, ql %d\n", int(tqp->size())));
+ if (!fip->m_db->addOrUpdate(tsk->udi, tsk->parent_udi, tsk->doc)) {
+ tqp->setTerminateAndWait();
+ tqp->workerExit();
+ return (void*)0;
+ }
+ delete tsk;
+ }
+}
+#endif // IDX_THREADS
/// This method gets called for every file and directory found by the
/// tree walker.
@@ -443,8 +481,16 @@
// of the file document.
string udi;
make_udi(fn, doc.ipath, udi);
+
+#ifdef IDX_THREADS
+ IndexingTask *tp = new IndexingTask(udi, doc.ipath.empty() ?
+ cstr_null : parent_udi, doc);
+ if (!m_wqueue.put(tp))
+ return FsTreeWalker::FtwError;
+#else
if (!m_db->addOrUpdate(udi, doc.ipath.empty() ? cstr_null : parent_udi, doc))
return FsTreeWalker::FtwError;
+#endif // IDX_THREADS
// Tell what we are doing and check for interrupt request
if (m_updater) {
@@ -476,8 +522,14 @@
fileDoc.fbytes = cbuf;
// Document signature for up to date checks.
makesig(stp, fileDoc.sig);
+#ifdef IDX_THREADS
+ IndexingTask *tp = new IndexingTask(parent_udi, cstr_null, fileDoc);
+ if (!m_wqueue.put(tp))
+ return FsTreeWalker::FtwError;
+#else
if (!m_db->addOrUpdate(parent_udi, cstr_null, fileDoc))
return FsTreeWalker::FtwError;
+#endif // IDX_THREADS
}
return FsTreeWalker::FtwOk;