Baloo

phraseanditerator.cpp
1 /*
2  This file is part of the KDE Baloo project.
3  SPDX-FileCopyrightText: 2015 Vishesh Handa <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7 
8 #include "phraseanditerator.h"
9 #include "positioninfo.h"
10 
11 using namespace Baloo;
12 
13 PhraseAndIterator::PhraseAndIterator(const QVector<VectorPositionInfoIterator*>& iterators)
14  : m_iterators(iterators)
15  , m_docId(0)
16 {
17  if (m_iterators.contains(nullptr)) {
18  qDeleteAll(m_iterators);
19  m_iterators.clear();
20  }
21 }
22 
23 PhraseAndIterator::~PhraseAndIterator()
24 {
25  qDeleteAll(m_iterators);
26 }
27 
28 quint64 PhraseAndIterator::docId() const
29 {
30  return m_docId;
31 }
32 
33 bool 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(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 
77 quint64 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(m_iterators)) {
87  lower_bound = iter->skipTo(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 
107 quint64 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(m_docId);
116 
117  return m_docId;
118 }
A PostingIterator is an abstract base class which can be used to iterate over all the "postings" or "...
Implements storage for docIds without any associated data Instantiated for:
Definition: coding.cpp:11
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Nov 29 2023 03:56:26 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.