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 "phraseanditerator.h"
9#include "positioninfo.h"
10
11using namespace Baloo;
12
13PhraseAndIterator::PhraseAndIterator(const QVector<VectorPositionInfoIterator*>& iterators)
14 : m_iterators(iterators)
15 , m_docId(0)
16{
17 if (m_iterators.contains(t: nullptr)) {
18 qDeleteAll(c: m_iterators);
19 m_iterators.clear();
20 }
21}
22
23PhraseAndIterator::~PhraseAndIterator()
24{
25 qDeleteAll(c: m_iterators);
26}
27
28quint64 PhraseAndIterator::docId() const
29{
30 return m_docId;
31}
32
33bool PhraseAndIterator::checkIfPositionsMatch()
34{
35 using Offset = decltype(m_iterators[0]->positions().size());
36 using Position = std::remove_reference<decltype(m_iterators[0]->positions()[0])>::type;
37
38 std::vector<Offset> offsets;
39 offsets.resize(new_size: m_iterators.size());
40
41 const auto firstPositions = m_iterators[0]->positions();
42 Position lower_bound = 0;
43
44 while (offsets[0] < firstPositions.size()) {
45 for (int i = 0; i < m_iterators.size(); i++) {
46 const auto positions = m_iterators[i]->positions();
47 Offset off = offsets[i];
48
49 for (; off < positions.size(); ++off) {
50 Position pos = positions[off];
51 // Adjust the position. We have a match iff
52 // term0 is at pos N, term1 at N+1, term2 at N+2 ...
53 if (pos >= (lower_bound + i)) {
54 lower_bound = pos - i;
55 break;
56 }
57 }
58 if (off >= positions.size()) {
59 return false;
60 }
61 offsets[i] = off;
62 }
63
64 if (lower_bound == firstPositions[offsets[0]]) {
65 // lower_bound has not changed, i.e. all offsets are aligned
66 for (int i = 0; i < m_iterators.size(); i++) {
67 auto positions = m_iterators[i]->positions();
68 }
69 return true;
70 } else {
71 offsets[0]++;
72 }
73 }
74 return false;
75}
76
77quint64 PhraseAndIterator::skipTo(quint64 id)
78{
79 if (m_iterators.isEmpty()) {
80 m_docId = 0;
81 return 0;
82 }
83
84 while (true) {
85 quint64 lower_bound = id;
86 for (PostingIterator* iter : std::as_const(t&: m_iterators)) {
87 lower_bound = iter->skipTo(docId: lower_bound);
88
89 if (lower_bound == 0) {
90 m_docId = 0;
91 return 0;
92 }
93 }
94
95 if (lower_bound == id) {
96 if (checkIfPositionsMatch()) {
97 m_docId = lower_bound;
98 return lower_bound;
99 } else {
100 lower_bound = m_iterators[0]->next();
101 }
102 }
103 id = lower_bound;
104 }
105}
106
107quint64 PhraseAndIterator::next()
108{
109 if (m_iterators.isEmpty()) {
110 m_docId = 0;
111 return 0;
112 }
113
114 m_docId = m_iterators[0]->next();
115 m_docId = skipTo(id: m_docId);
116
117 return m_docId;
118}
119

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