Coverage Report

Created: 2026-09-20 14:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/index/inverted/tokenizer/tokenizer.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#pragma once
19
20
#include <unicode/utf8.h>
21
22
#include <cstdint>
23
#include <span>
24
#include <string_view>
25
#include <vector>
26
27
#include "storage/index/inverted/char_filter/char_filter.h"
28
#include "storage/index/inverted/token_stream.h"
29
30
namespace doris::segment_v2::inverted_index {
31
32
class DorisTokenizer : public Tokenizer, public DorisTokenStream {
33
public:
34
756
    DorisTokenizer() = default;
35
756
    ~DorisTokenizer() override = default;
36
37
3.80k
    void set_reader(const ReaderPtr& in) {
38
3.80k
        if (in == nullptr) {
39
0
            throw Exception(ErrorCode::INVALID_ARGUMENT, "reader must not be null");
40
0
        }
41
3.80k
        _in_pending = in;
42
3.80k
    }
43
44
    using Tokenizer::reset;
45
    // Only use the parameterless reset method
46
3.80k
    void reset() override { _in = _in_pending; };
47
48
88.5k
    std::span<const int32_t> get_source_byte_offsets() const override {
49
88.5k
        return _source_byte_offsets_enabled ? std::span<const int32_t> {_source_byte_offsets}
50
88.5k
                                            : std::span<const int32_t> {};
51
88.5k
    }
52
53
49
    void set_source_byte_offsets_enabled(bool enabled) override {
54
49
        _source_byte_offsets_enabled = enabled;
55
49
    }
56
57
protected:
58
196k
    int32_t correct_source_offset(int32_t offset) const {
59
196k
        const auto* char_filter = dynamic_cast<const DorisCharFilter*>(_in.get());
60
196k
        return char_filter == nullptr ? offset : char_filter->correct_offset(offset);
61
196k
    }
62
63
98.0k
    void set_source_byte_offsets(std::string_view term, int32_t source_start) {
64
98.0k
        _source_byte_offsets.clear();
65
98.0k
        if (!_source_byte_offsets_enabled) {
66
97.9k
            return;
67
97.9k
        }
68
69
82
        const auto* char_filter = dynamic_cast<const DorisCharFilter*>(_in.get());
70
82
        const int32_t corrected_start =
71
82
                char_filter == nullptr ? source_start : char_filter->correct_offset(source_start);
72
82
        _source_byte_offsets.push_back(0);
73
82
        const char* data = term.data();
74
82
        const auto length = static_cast<int32_t>(term.size());
75
82
        int32_t offset = 0;
76
372
        while (offset < length) {
77
290
            UChar32 code_point;
78
290
            U8_NEXT(data, offset, length, code_point);
79
290
            if (code_point < 0) {
80
0
                _source_byte_offsets.clear();
81
0
                return;
82
0
            }
83
290
            _source_byte_offsets.push_back(
84
290
                    char_filter == nullptr
85
290
                            ? offset
86
290
                            : char_filter->correct_offset(source_start + offset) - corrected_start);
87
290
        }
88
82
    }
89
90
    ReaderPtr _in;
91
    ReaderPtr _in_pending;
92
    std::vector<int32_t> _source_byte_offsets;
93
    bool _source_byte_offsets_enabled {false};
94
};
95
using TokenizerPtr = std::shared_ptr<DorisTokenizer>;
96
97
} // namespace doris::segment_v2::inverted_index