blob: 5040ebbd395d6f85cdfd12543d2a898aeda6b366 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
#include "searchiterator.h"
#include "emptysearch.h"
#include <vector>
namespace search::queryeval {
namespace sourceselector { class Iterator; }
/**
* A simple implementation of the source blender operation. This class
* is used to blend results from multiple sources. Each source is
* represented with a separate search iterator. A source selector
* iterator is used to select the appropriate source for each
* document. The source blender will make sure to only propagate
* unpack requests to one of the sources below, enabling them to use
* the same target location for detailed match data unpacking.
**/
class SourceBlenderSearch : public SearchIterator
{
public:
/**
* Small wrapper used to specify the underlying searches to be
* blended.
**/
struct Child {
SearchIterator *search;
uint32_t sourceId;
Child() : search(nullptr), sourceId(0) { }
Child(SearchIterator *s, uint32_t id) noexcept : search(s), sourceId(id) {}
};
using Children = std::vector<Child>;
private:
SourceBlenderSearch(const SourceBlenderSearch &);
SourceBlenderSearch &operator=(const SourceBlenderSearch &);
void visitMembers(vespalib::ObjectVisitor &visitor) const override;
bool isSourceBlender() const override { return true; }
static EmptySearch _emptySearch;
protected:
using Iterator = sourceselector::Iterator;
using Source = uint8_t;
using SourceIndex = std::vector<Source>;
SearchIterator * _matchedChild;
std::unique_ptr<Iterator> _sourceSelector;
SourceIndex _children;
uint32_t _docIdLimit;
SearchIterator * _sources[256];
void doSeek(uint32_t docid) override;
void doUnpack(uint32_t docid) override;
Trinary is_strict() const override { return Trinary::False; }
SourceBlenderSearch(std::unique_ptr<Iterator> sourceSelector, const Children &children);
SearchIterator * getSearch(Source source) const { return _sources[source]; }
public:
/**
* Create a new SourceBlender Search with the given children and
* strictness. A strict blender can assume that all children below
* are also strict. A non-strict blender has no strictness
* assumptions about its children.
*
* @param sourceSelector This is an iterator that provide you with the
* the correct source to use.
* @param children the search objects we are blending
* this object takes ownership of the children.
* @param strict whether this search is strict
* (a strict search will locate its next hit when seeking fails)
**/
static SearchIterator::UP create(std::unique_ptr<Iterator> sourceSelector,
const Children &children,
bool strict);
~SourceBlenderSearch() override;
size_t getNumChildren() const { return _children.size(); }
SearchIterator::UP steal(size_t index) {
SearchIterator::UP retval(_sources[_children[index]]);
_sources[_children[index]] = nullptr;
return retval;
}
void setChild(size_t index, SearchIterator::UP child);
void initRange(uint32_t beginId, uint32_t endId) override;
};
}
void visit(vespalib::ObjectVisitor &self, const vespalib::string &name,
const search::queryeval::SourceBlenderSearch::Child &obj);
|