• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

realm / realm-core / nikola.irinchev_478

10 Jun 2024 05:02PM UTC coverage: 90.821% (-0.2%) from 90.975%
nikola.irinchev_478

Pull #7792

Evergreen

nirinchev
Replace app_config_get_sync_client_config with _set_sync_client_config
Pull Request #7792: Replace app_config_get_sync_client_config with _set_sync_client_config

101696 of 180086 branches covered (56.47%)

0 of 3 new or added lines in 1 file covered. (0.0%)

1872 existing lines in 57 files now uncovered.

214568 of 236253 relevant lines covered (90.82%)

5116114.57 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.86
/src/realm/node_header.hpp
1
/*************************************************************************
2
 *
3
 * Copyright 2018 Realm Inc.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * 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, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 **************************************************************************/
18

19
#ifndef REALM_NODE_HEADER_HPP
20
#define REALM_NODE_HEADER_HPP
21

22
#include <realm/util/assert.hpp>
23

24
namespace realm {
25

26
const size_t max_array_size = 0x00ffffffL;            // Maximum number of elements in an array
27
const size_t max_array_payload_aligned = 0x07ffffc0L; // Maximum number of bytes that the payload of an array can be
28
// Even though the encoding supports arrays with size up to max_array_payload_aligned,
29
// the maximum allocation size is smaller as it must fit within a memory section
30
// (a contiguous virtual address range). This limitation is enforced in SlabAlloc::do_alloc().
31

32
class NodeHeader {
33
public:
34
    enum Type {
35
        type_Normal,
36

37
        /// This array is the main array of an innner node of a B+-tree as used
38
        /// in table columns.
39
        type_InnerBptreeNode,
40

41
        /// This array may contain refs to subarrays. An element whose least
42
        /// significant bit is zero, is a ref pointing to a subarray. An element
43
        /// whose least significant bit is one, is just a value. It is the
44
        /// responsibility of the application to ensure that non-ref values have
45
        /// their least significant bit set. This will generally be done by
46
        /// shifting the desired vlue to the left by one bit position, and then
47
        /// setting the vacated bit to one.
48
        type_HasRefs
49
    };
50

51
    enum WidthType {
52
        wtype_Bits = 0,     // width indicates how many bits every element occupies
53
        wtype_Multiply = 1, // width indicates how many bytes every element occupies
54
        wtype_Ignore = 2,   // each element is 1 byte
55
    };
56

57
    static const int header_size = 8; // Number of bytes used by header
58

59
    // The encryption layer relies on headers always fitting within a single page.
60
    static_assert(header_size == 8, "Header must always fit in entirely on a page");
61

62
    static char* get_data_from_header(char* header) noexcept
63
    {
1,252,083,906✔
64
        return header + header_size;
1,252,083,906✔
65
    }
1,252,083,906✔
66

67
    static char* get_header_from_data(char* data) noexcept
68
    {
4,294,967,294✔
69
        return data - header_size;
4,294,967,294✔
70
    }
4,294,967,294✔
71

72
    static const char* get_data_from_header(const char* header) noexcept
73
    {
325,736,826✔
74
        return get_data_from_header(const_cast<char*>(header));
325,736,826✔
75
    }
325,736,826✔
76

77
    static bool get_is_inner_bptree_node_from_header(const char* header) noexcept
78
    {
1,032,191,865✔
79
        typedef unsigned char uchar;
1,032,191,865✔
80
        const uchar* h = reinterpret_cast<const uchar*>(header);
1,032,191,865✔
81
        return (int(h[4]) & 0x80) != 0;
1,032,191,865✔
82
    }
1,032,191,865✔
83

84
    static bool get_hasrefs_from_header(const char* header) noexcept
85
    {
827,726,226✔
86
        typedef unsigned char uchar;
827,726,226✔
87
        const uchar* h = reinterpret_cast<const uchar*>(header);
827,726,226✔
88
        return (int(h[4]) & 0x40) != 0;
827,726,226✔
89
    }
827,726,226✔
90

91
    static bool get_context_flag_from_header(const char* header) noexcept
92
    {
729,599,901✔
93
        typedef unsigned char uchar;
729,599,901✔
94
        const uchar* h = reinterpret_cast<const uchar*>(header);
729,599,901✔
95
        return (int(h[4]) & 0x20) != 0;
729,599,901✔
96
    }
729,599,901✔
97

98
    static WidthType get_wtype_from_header(const char* header) noexcept
99
    {
1,097,828,784✔
100
        typedef unsigned char uchar;
1,097,828,784✔
101
        const uchar* h = reinterpret_cast<const uchar*>(header);
1,097,828,784✔
102
        return WidthType((int(h[4]) & 0x18) >> 3);
1,097,828,784✔
103
    }
1,097,828,784✔
104

105
    static uint_least8_t get_width_from_header(const char* header) noexcept
106
    {
3,765,120,231✔
107
        typedef unsigned char uchar;
3,765,120,231✔
108
        const uchar* h = reinterpret_cast<const uchar*>(header);
3,765,120,231✔
109
        return uint_least8_t((1 << (int(h[4]) & 0x07)) >> 1);
3,765,120,231✔
110
    }
3,765,120,231✔
111

112
    static size_t get_size_from_header(const char* header) noexcept
113
    {
1,826,859,945✔
114
        typedef unsigned char uchar;
1,826,859,945✔
115
        const uchar* h = reinterpret_cast<const uchar*>(header);
1,826,859,945✔
116
        return (size_t(h[5]) << 16) + (size_t(h[6]) << 8) + h[7];
1,826,859,945✔
117
    }
1,826,859,945✔
118

119
    static size_t get_capacity_from_header(const char* header) noexcept
120
    {
945,767,235✔
121
        typedef unsigned char uchar;
945,767,235✔
122
        const uchar* h = reinterpret_cast<const uchar*>(header);
945,767,235✔
123
        return (size_t(h[0]) << 19) + (size_t(h[1]) << 11) + (h[2] << 3);
945,767,235✔
124
    }
945,767,235✔
125

126
    static Type get_type_from_header(const char* header) noexcept
127
    {
×
128
        if (get_is_inner_bptree_node_from_header(header))
×
129
            return type_InnerBptreeNode;
×
130
        if (get_hasrefs_from_header(header))
×
131
            return type_HasRefs;
×
132
        return type_Normal;
×
133
    }
×
134

135
    static void set_is_inner_bptree_node_in_header(bool value, char* header) noexcept
136
    {
16,218,477✔
137
        typedef unsigned char uchar;
16,218,477✔
138
        uchar* h = reinterpret_cast<uchar*>(header);
16,218,477✔
139
        h[4] = uchar((int(h[4]) & ~0x80) | int(value) << 7);
16,218,477✔
140
    }
16,218,477✔
141

142
    static void set_hasrefs_in_header(bool value, char* header) noexcept
143
    {
16,219,317✔
144
        typedef unsigned char uchar;
16,219,317✔
145
        uchar* h = reinterpret_cast<uchar*>(header);
16,219,317✔
146
        h[4] = uchar((int(h[4]) & ~0x40) | int(value) << 6);
16,219,317✔
147
    }
16,219,317✔
148

149
    static void set_context_flag_in_header(bool value, char* header) noexcept
150
    {
16,932,330✔
151
        typedef unsigned char uchar;
16,932,330✔
152
        uchar* h = reinterpret_cast<uchar*>(header);
16,932,330✔
153
        h[4] = uchar((int(h[4]) & ~0x20) | int(value) << 5);
16,932,330✔
154
    }
16,932,330✔
155

156
    static void set_wtype_in_header(WidthType value, char* header) noexcept
157
    {
16,214,835✔
158
        // Indicates how to calculate size in bytes based on width
159
        // 0: bits      (width/8) * size
160
        // 1: multiply  width * size
161
        // 2: ignore    1 * size
162
        typedef unsigned char uchar;
16,214,835✔
163
        uchar* h = reinterpret_cast<uchar*>(header);
16,214,835✔
164
        h[4] = uchar((int(h[4]) & ~0x18) | int(value) << 3);
16,214,835✔
165
    }
16,214,835✔
166

167
    static void set_width_in_header(int value, char* header) noexcept
168
    {
40,692,024✔
169
        // Pack width in 3 bits (log2)
170
        int w = 0;
40,692,024✔
171
        while (value) {
144,533,124✔
172
            ++w;
103,841,100✔
173
            value >>= 1;
103,841,100✔
174
        }
103,841,100✔
175
        REALM_ASSERT_3(w, <, 8);
40,692,024✔
176

177
        typedef unsigned char uchar;
40,692,024✔
178
        uchar* h = reinterpret_cast<uchar*>(header);
40,692,024✔
179
        h[4] = uchar((int(h[4]) & ~0x7) | w);
40,692,024✔
180
    }
40,692,024✔
181

182
    static void set_size_in_header(size_t value, char* header) noexcept
183
    {
953,256,105✔
184
        REALM_ASSERT_3(value, <=, max_array_size);
953,256,105✔
185
        typedef unsigned char uchar;
953,256,105✔
186
        uchar* h = reinterpret_cast<uchar*>(header);
953,256,105✔
187
        h[5] = uchar((value >> 16) & 0x000000FF);
953,256,105✔
188
        h[6] = uchar((value >> 8) & 0x000000FF);
953,256,105✔
189
        h[7] = uchar(value & 0x000000FF);
953,256,105✔
190
    }
953,256,105✔
191

192
    // Note: There is a copy of this function is test_alloc.cpp
193
    static void set_capacity_in_header(size_t value, char* header) noexcept
194
    {
35,372,346✔
195
        REALM_ASSERT_3(value, <=, (0xffffff << 3));
35,372,346✔
196
        typedef unsigned char uchar;
35,372,346✔
197
        uchar* h = reinterpret_cast<uchar*>(header);
35,372,346✔
198
        h[0] = uchar((value >> 19) & 0x000000FF);
35,372,346✔
199
        h[1] = uchar((value >> 11) & 0x000000FF);
35,372,346✔
200
        h[2] = uchar(value >> 3 & 0x000000FF);
35,372,346✔
201
    }
35,372,346✔
202

203
    static size_t get_byte_size_from_header(const char* header) noexcept
204
    {
166,282,965✔
205
        size_t size = get_size_from_header(header);
166,282,965✔
206
        uint_least8_t width = get_width_from_header(header);
166,282,965✔
207
        WidthType wtype = get_wtype_from_header(header);
166,282,965✔
208
        size_t num_bytes = calc_byte_size(wtype, size, width);
166,282,965✔
209

210
        return num_bytes;
166,282,965✔
211
    }
166,282,965✔
212

213
    static size_t calc_byte_size(WidthType wtype, size_t size, uint_least8_t width) noexcept
214
    {
214,606,044✔
215
        size_t num_bytes = 0;
214,606,044✔
216
        switch (wtype) {
214,606,044✔
217
            case wtype_Bits: {
60,702,453✔
218
                // Current assumption is that size is at most 2^24 and that width is at most 64.
219
                // In that case the following will never overflow. (Assuming that size_t is at least 32 bits)
220
                REALM_ASSERT_3(size, <, 0x1000000);
60,702,453✔
221
                size_t num_bits = size * width;
60,702,453✔
222
                num_bytes = (num_bits + 7) >> 3;
60,702,453✔
223
                break;
60,702,453✔
UNCOV
224
            }
×
225
            case wtype_Multiply: {
4,626,489✔
226
                num_bytes = size * width;
4,626,489✔
227
                break;
4,626,489✔
UNCOV
228
            }
×
229
            case wtype_Ignore:
150,730,917✔
230
                num_bytes = size;
150,730,917✔
231
                break;
150,730,917✔
232
        }
214,606,044✔
233

234
        // Ensure 8-byte alignment
235
        num_bytes = (num_bytes + 7) & ~size_t(7);
214,725,891✔
236

237
        num_bytes += header_size;
214,725,891✔
238

239
        return num_bytes;
214,725,891✔
240
    }
214,606,044✔
241
};
242
} // namespace realm
243

244
#endif /* REALM_NODE_HEADER_HPP */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc