Coverage Report

Created: 2026-03-12 16:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/segment/page_handle.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 "runtime/exec_env.h"
21
#include "storage/cache/page_cache.h"
22
#include "util/slice.h" // for Slice
23
24
namespace doris {
25
26
// After disable page cache, sometimes we need to know the percentage of data pages in query memory.
27
inline bvar::Adder<int64_t> g_page_no_cache_mem_bytes("doris_page_no_cache_mem_bytes");
28
29
namespace segment_v2 {
30
31
// When a column page is read into memory, we use this to store it.
32
// A page's data may be in cache, or may not in cache. We use this
33
// class to unify these two cases.
34
// If client use this struct to wrap data not in cache, this class
35
// will free data's memory when it is destroyed.
36
class PageHandle {
37
public:
38
55.1M
    PageHandle() : _is_data_owner(false) {}
39
40
    // This class will take the ownership of input data's memory. It will
41
    // free it when deconstructs.
42
2.07M
    PageHandle(DataPage* data) : _is_data_owner(true), _data(data) {
43
2.07M
        g_page_no_cache_mem_bytes << _data->capacity();
44
2.07M
    }
45
46
    // This class will take the content of cache data, and will make input
47
    // cache_data to a invalid cache handle.
48
    PageHandle(PageCacheHandle cache_data)
49
4.13M
            : _is_data_owner(false), _cache_data(std::move(cache_data)) {}
50
51
    // Move constructor
52
5.77M
    PageHandle(PageHandle&& other) noexcept : _cache_data(std::move(other._cache_data)) {
53
        // we can use std::exchange if we switch c++14 on
54
5.77M
        std::swap(_is_data_owner, other._is_data_owner);
55
5.77M
        std::swap(_data, other._data);
56
5.77M
    }
57
58
11.9M
    PageHandle& operator=(PageHandle&& other) noexcept {
59
11.9M
        std::swap(_is_data_owner, other._is_data_owner);
60
11.9M
        std::swap(_data, other._data);
61
11.9M
        _cache_data = std::move(other._cache_data);
62
11.9M
        return *this;
63
11.9M
    }
64
65
66.4M
    ~PageHandle() {
66
66.4M
        if (_is_data_owner) {
67
2.07M
            g_page_no_cache_mem_bytes << -_data->capacity();
68
2.07M
            delete _data;
69
64.3M
        } else {
70
64.3M
            DCHECK(_data == nullptr);
71
64.3M
        }
72
66.4M
    }
73
74
    // the return slice contains uncompressed page body, page footer, and footer size
75
4.06M
    Slice data() const {
76
4.06M
        if (_is_data_owner) {
77
0
            return Slice(_data->data(), _data->size());
78
4.06M
        } else {
79
4.06M
            return _cache_data.data();
80
4.06M
        }
81
4.06M
    }
82
83
private:
84
    // when this is true, it means this struct own data and _data is valid.
85
    // otherwise _cache_data is valid, and data is belong to cache.
86
    bool _is_data_owner = false;
87
    DataPage* _data = nullptr;
88
    PageCacheHandle _cache_data;
89
90
    // Don't allow copy and assign
91
    DISALLOW_COPY_AND_ASSIGN(PageHandle);
92
};
93
94
} // namespace segment_v2
95
} // namespace doris