File indexing completed on 2024-04-14 03:49:41
0001 /* 0002 This file is part of the KDE Baloo project. 0003 SPDX-FileCopyrightText: 2015 Vishesh Handa <vhanda@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include "orpostingiterator.h" 0009 0010 using namespace Baloo; 0011 0012 OrPostingIterator::OrPostingIterator(const QVector<PostingIterator*>& iterators) 0013 : m_iterators(iterators) 0014 , m_docId(0) 0015 , m_nextId(0) 0016 { 0017 /* 0018 * Check for null iterators 0019 * Preferably, these are not pushed to the list at all, but better be safe 0020 */ 0021 m_iterators.removeAll(nullptr); 0022 0023 for (PostingIterator* iter : std::as_const(m_iterators)) { 0024 auto docId = iter->next(); 0025 // find smallest docId 0026 if (docId && (docId < m_nextId || m_nextId == 0)) { 0027 m_nextId = docId; 0028 } 0029 } 0030 } 0031 0032 OrPostingIterator::~OrPostingIterator() 0033 { 0034 qDeleteAll(m_iterators); 0035 } 0036 0037 quint64 OrPostingIterator::docId() const 0038 { 0039 return m_docId; 0040 } 0041 0042 quint64 OrPostingIterator::skipTo(quint64 id) 0043 { 0044 if (m_docId >= id) { 0045 return m_docId; 0046 } 0047 if (m_nextId == 0) { 0048 m_docId = m_nextId; 0049 return 0; 0050 } 0051 0052 if (id > m_nextId) { 0053 // Fast forward - move all iterators to the lowest position 0054 // greater or equal to id 0055 m_nextId = 0; 0056 for (PostingIterator* iter : std::as_const(m_iterators)) { 0057 auto docId = iter->skipTo(id); 0058 if (docId > 0) { 0059 if (docId < m_nextId || !m_nextId) { 0060 m_nextId = docId; 0061 } 0062 } 0063 } 0064 if (m_nextId == 0) { 0065 m_docId = m_nextId; 0066 return 0; 0067 } 0068 } 0069 0070 m_docId = m_nextId; 0071 m_nextId = 0; 0072 0073 // advance all iterators which point to the lowest docId 0074 for (PostingIterator*& iter : m_iterators) { 0075 auto docId = iter->docId(); 0076 if (docId == m_docId) { 0077 docId = iter->next(); 0078 } 0079 0080 if (docId == 0) { 0081 // remove element if iterator has reached the end 0082 delete iter; 0083 iter = nullptr; 0084 } else { 0085 // check if the docId is the new lowest docId 0086 if (docId < m_nextId || !m_nextId) { 0087 m_nextId = docId; 0088 } 0089 } 0090 } 0091 auto tail = std::remove_if(m_iterators.begin(), m_iterators.end(), 0092 [](const PostingIterator* it) { return it == nullptr; }); 0093 m_iterators.erase(tail, m_iterators.end()); 0094 0095 return m_docId; 0096 } 0097 0098 quint64 OrPostingIterator::next() 0099 { 0100 if (m_nextId) { 0101 m_docId = skipTo(m_nextId); 0102 } else { 0103 m_docId = 0; 0104 } 0105 return m_docId; 0106 }