bruns added a comment.

  In D11828#242402 <https://phabricator.kde.org/D11828#242402>, @michaelh wrote:
  
  > I'm not very familiar with the concept of iterators (yet). To me it looks 
like `auto i = new OrPostingIterator(iters); i->docId();` will return 0 and 
`i->next()` returns a valid docId. After that `i->docId();` is also valid.
  >  Is this how iterators work? Naively I would expect `i->docId();` to be 
valid after construction or both `i->docId();` and `i->next()` to be invalid.
  >
  > I have to admit, it's very difficult to understand (and I don't, really) 
what baloo is doing here with all this iterating over vectors of inherited 
iterator classes, pointer-to-pointer stuff of which some might not even exist. 
My brain hurts, terribly! All I can presently do is ask some simple questions. 
Sorry, I'm of no help here. Please take my comments as a device for better 
understanding and I hope it's not to much of a bother.
  
  
  Each PostingIterator represents a "set" of document ids. PostingIterators are 
not related to STL or Qt container iterators (although the "subiterators" are 
implemented using QVectors<>).
  
  The `PI::next()` call returns the smallest element and removes it from the 
set, `PI::docId()` just returns the smallest element.
  
  The result set of the OrPostingIterator is the union of its "subsets" 
(represented by its "subiterators", i.e. the QVector<PostingIterator*> 
constructor argument). Or works a little bit like an insertion sort. To return 
the smallest element, it creates the union of the smallest element of all 
subsets, and yields the smallest element of the union. It then calls 
`PI::next()` on all subsets which returned the smallest element, removing it 
from all subsets and thus from the union.
  
  In C++, you can use iterators in two different ways, either PreIncrement or 
PostIncrement. `PostingIterator::next()` will behave like `*(++it)`, i.e. it is 
incremented first, then the current value is returned.
  
  I don't know the original justification for this design. One possible idea is 
to delay the actual database query until `next()` is called the first time. For 
e.g. a query "a AND b AND c", one can execute "a", if not empty do "b", 
intersect (i.e. calling the Iterators of Result("a") and Result("b") until both 
return the same value), and if the intersection is non-empty, do "c".
  
  Currently, it does not implement this optimization. D12025 
<https://phabricator.kde.org/D12025> implements one case, i.e. stopping if a 
leaf query returns an empty set, and propagating it upwards.

REPOSITORY
  R293 Baloo

REVISION DETAIL
  https://phabricator.kde.org/D11828

To: bruns, #baloo, michaelh
Cc: #frameworks, ashaposhnikov, michaelh, astippich, spoorun, ngraham, bruns, 
alexeymin

Reply via email to