1/*
2 This file is part of the KDE Baloo project.
3 SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.1-or-later
6*/
7
8#include "orpostingiterator.h"
9
10using namespace Baloo;
11
12OrPostingIterator::OrPostingIterator(const QVector<PostingIterator*>& iterators)
13 : m_iterators(iterators)
14 , m_docId(0)
15 , m_nextId(0)
16{
17 /*
18 * Check for null iterators
19 * Preferably, these are not pushed to the list at all, but better be safe
20 */
21 m_iterators.removeAll(t: nullptr);
22
23 for (PostingIterator* iter : std::as_const(t&: m_iterators)) {
24 auto docId = iter->next();
25 // find smallest docId
26 if (docId && (docId < m_nextId || m_nextId == 0)) {
27 m_nextId = docId;
28 }
29 }
30}
31
32OrPostingIterator::~OrPostingIterator()
33{
34 qDeleteAll(c: m_iterators);
35}
36
37quint64 OrPostingIterator::docId() const
38{
39 return m_docId;
40}
41
42quint64 OrPostingIterator::skipTo(quint64 id)
43{
44 if (m_docId >= id) {
45 return m_docId;
46 }
47 if (m_nextId == 0) {
48 m_docId = m_nextId;
49 return 0;
50 }
51
52 if (id > m_nextId) {
53 // Fast forward - move all iterators to the lowest position
54 // greater or equal to id
55 m_nextId = 0;
56 for (PostingIterator* iter : std::as_const(t&: m_iterators)) {
57 auto docId = iter->skipTo(docId: id);
58 if (docId > 0) {
59 if (docId < m_nextId || !m_nextId) {
60 m_nextId = docId;
61 }
62 }
63 }
64 if (m_nextId == 0) {
65 m_docId = m_nextId;
66 return 0;
67 }
68 }
69
70 m_docId = m_nextId;
71 m_nextId = 0;
72
73 // advance all iterators which point to the lowest docId
74 for (PostingIterator*& iter : m_iterators) {
75 auto docId = iter->docId();
76 if (docId == m_docId) {
77 docId = iter->next();
78 }
79
80 if (docId == 0) {
81 // remove element if iterator has reached the end
82 delete iter;
83 iter = nullptr;
84 } else {
85 // check if the docId is the new lowest docId
86 if (docId < m_nextId || !m_nextId) {
87 m_nextId = docId;
88 }
89 }
90 }
91 auto tail = std::remove_if(first: m_iterators.begin(), last: m_iterators.end(),
92 pred: [](const PostingIterator* it) { return it == nullptr; });
93 m_iterators.erase(abegin: tail, aend: m_iterators.end());
94
95 return m_docId;
96}
97
98quint64 OrPostingIterator::next()
99{
100 if (m_nextId) {
101 m_docId = skipTo(id: m_nextId);
102 } else {
103 m_docId = 0;
104 }
105 return m_docId;
106}
107

source code of baloo/src/engine/orpostingiterator.cpp