aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/vespa/searchlib/fef/fieldpositionsiterator.h
blob: 538ee1d44ce024b25ba4a6070e0ff407d1eb60a5 (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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#pragma once

#include "termfieldmatchdataposition.h"

namespace search::fef {

/**
 * Iterator used to iterate over all positions of a term inside a
 * specific field.
 **/
class FieldPositionsIterator
{
public:
    /**
     * The iterator type of the underlying data, which have all
     * positions for a term across all fields searched.
     **/
    using PositionsIterator = const TermFieldMatchDataPosition *;

private:
    uint32_t          _length;
    PositionsIterator _begin;
    PositionsIterator _pos;
    PositionsIterator _end;

public:
    /**
     * The length reported for fields for which we do not know the
     * real length.
     **/
    static const uint32_t UNKNOWN_LENGTH;

    /**
     * Create a new iterator for a field we know nothing about. This
     * will give the field no position data and a length of 0.
     **/
    FieldPositionsIterator()
        : _length(UNKNOWN_LENGTH), _begin(0), _pos(0), _end(0) {}

    /**
     * Create a new iterator for a field with the given offset and
     * length, using a slice of the underlying position data.
     *
     * @param length the length of the field in words
     * @param begin start of position data slice
     * @param end end of position data slice
     **/
    FieldPositionsIterator(uint32_t length,
                           PositionsIterator begin,
                           PositionsIterator end)
        : _length(length), _begin(begin), _pos(begin), _end(end) {}

    /**
     * Relocate the references held by this object into the actual
     * occurrence data. This method assumes iterators are random
     * access and cheap to copy. This method must be invoked if the
     * underlying occurrence data is moved in memory.
     *
     * @param oldRef old reference iterator
     * @param newRef new reference iterator
     **/
    void relocate(PositionsIterator oldRef, PositionsIterator newRef) {
        if (_begin != PositionsIterator(0)) {
            _begin = newRef + (_begin - oldRef);
            _pos   = newRef + (_pos   - oldRef);
            _end   = newRef + (_end   - oldRef);
        }
    }

    /**
     * Check if there is valid data available at the current position
     * of this iterator.
     *
     * @return false if no more data is available
     **/
    bool valid() const { return _pos != _end; }

    /**
     * Step this iterator to the next position. This method may only
     * be invoked if the @ref valid method returns true.
     **/
    void next() { ++_pos; }

    /**
     * Try to step this iterator backwards. This method will return
     * false if the iterator is already located at the beginning.
     *
     * @return false if we are unable to step backwards
     **/
    bool prev() {
        if (_pos == _begin) {
            return false;
        }
        --_pos;
        return true;
    }

    /**
     * Obtain the word position within the field for the entry
     * indicated by the current position of this iterator. This method
     * may only be invoked if the @ref valid method returns true.
     *
     * @return word position within the field
     **/
    uint32_t getPosition() const { return _pos->getPosition(); }

    /**
     * Obtain the element id within the field for the entry
     * indicated by the current position of this iterator. This method
     * may only be invoked if the @ref valid method returns true.
     *
     * @return element id within the field
     **/
    uint32_t getElementId() const { return _pos->getElementId(); }

    /**
     * Obtain the element length within the field for the entry
     * indicated by the current position of this iterator. This method
     * may only be invoked if the @ref valid method returns true.
     *
     * @return element id within the field
     **/
    uint32_t getElementLen() const { return _pos->getElementLen(); }

    /**
     * Obtain the element weight within the field for the entry
     * indicated by the current position of this iterator. This method
     * may only be invoked if the @ref valid method returns true.
     *
     * @return element id within the field
     **/
    int32_t getElementWeight() const { return _pos->getElementWeight(); }

    /**
     * Obtain the match exactness indicated by the current position of
     * this iterator. This method may only be invoked if the @ref valid
     * method returns true.
     *
     * @return exactness measure
     **/
    double getMatchExactness() const { return _pos->getMatchExactness(); }

    /**
     * Obtain the total number of words in the field.
     *
     * @return field length in words.
     **/
    uint32_t getFieldLength() const { return _length; }

    /**
     * Obtain the number of positions in this iterator.
     *
     * @return number of positions
     **/
    uint32_t size() const { return (_end - _begin); }
};

}