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

realm / realm-core / jorgen.edelbo_337

03 Jul 2024 01:04PM UTC coverage: 90.864% (-0.1%) from 90.984%
jorgen.edelbo_337

Pull #7826

Evergreen

nicola-cab
Merge branch 'master' of github.com:realm/realm-core into next-major
Pull Request #7826: Merge Next major

102968 of 181176 branches covered (56.83%)

3131 of 3738 new or added lines in 54 files covered. (83.76%)

106 existing lines in 23 files now uncovered.

217725 of 239616 relevant lines covered (90.86%)

6844960.2 hits per line

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

85.35
/src/realm/array_unsigned.cpp
1
/*************************************************************************
2
 *
3
 * Copyright 2016 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
#include <realm/array_unsigned.hpp>
20
#include <realm/array_direct.hpp>
21
#include <algorithm>
22

23
namespace realm {
24

25
void ArrayUnsigned::set_width(uint8_t width)
26
{
146,309,814✔
27
    REALM_ASSERT_DEBUG(width > 0 || m_size == 0);
146,309,814!
28
    m_ubound = uint64_t(-1) >> (64 - width);
146,309,814✔
29
    m_width = width;
146,309,814✔
30
}
146,309,814✔
31

32
inline uint8_t ArrayUnsigned::bit_width(uint64_t value)
33
{
83,571✔
34
    if (value < 0x100) {
83,571✔
35
        return 8;
52,566✔
36
    }
52,566✔
37
    if (value < 0x10000) {
31,005✔
38
        return 16;
13,980✔
39
    }
13,980✔
40
    if (value < 0x100000000) {
17,025✔
41
        return 32;
14,739✔
42
    }
14,739✔
43
    return 64;
2,286✔
44
}
17,025✔
45

46
inline void ArrayUnsigned::_set(size_t ndx, uint8_t width, uint64_t value)
47
{
15,945,111✔
48
    if (width == 8) {
15,945,111✔
49
        reinterpret_cast<uint8_t*>(m_data)[ndx] = uint8_t(value);
5,933,796✔
50
    }
5,933,796✔
51
    else if (width == 16) {
10,011,315✔
52
        reinterpret_cast<uint16_t*>(m_data)[ndx] = uint16_t(value);
4,242,978✔
53
    }
4,242,978✔
54
    else if (width == 32) {
5,768,337✔
55
        reinterpret_cast<uint32_t*>(m_data)[ndx] = uint32_t(value);
5,749,179✔
56
    }
5,749,179✔
57
    else {
19,158✔
58
        reinterpret_cast<uint64_t*>(m_data)[ndx] = uint64_t(value);
19,158✔
59
    }
19,158✔
60
}
15,945,111✔
61

62
inline uint64_t ArrayUnsigned::_get(size_t ndx, uint8_t width) const
63
{
497,852,640✔
64
    if (width == 8) {
497,852,640✔
65
        return reinterpret_cast<uint8_t*>(m_data)[ndx];
22,378,749✔
66
    }
22,378,749✔
67
    if (width == 16) {
475,473,891✔
68
        return reinterpret_cast<uint16_t*>(m_data)[ndx];
64,950,537✔
69
    }
64,950,537✔
70
    if (width == 32) {
410,523,354✔
71
        return reinterpret_cast<uint32_t*>(m_data)[ndx];
390,147,732✔
72
    }
390,147,732✔
73
    return get_direct(m_data, width, ndx);
20,375,622✔
74
    REALM_UNREACHABLE();
UNCOV
75
}
×
76

77
void ArrayUnsigned::create(size_t initial_size, uint64_t ubound_value)
78
{
53,013✔
79
    MemRef mem = create_node(initial_size, get_alloc(), false, Node::type_Normal, wtype_Bits,
53,013✔
80
                             bit_width(ubound_value)); // Throws
53,013✔
81
    init_from_mem(mem);
53,013✔
82
}
53,013✔
83

84
void ArrayUnsigned::update_from_parent() noexcept
85
{
106,725✔
86
    REALM_ASSERT_DEBUG(is_attached());
106,725✔
87
    ArrayParent* parent = get_parent();
106,725✔
88
    REALM_ASSERT_DEBUG(parent);
106,725✔
89
    ref_type new_ref = get_ref_from_parent();
106,725✔
90
    init_from_ref(new_ref);
106,725✔
91
}
106,725✔
92

93
size_t ArrayUnsigned::lower_bound(uint64_t value) const noexcept
94
{
63,276,792✔
95
    if (m_width == 8) {
63,276,792✔
96
        uint8_t* arr = reinterpret_cast<uint8_t*>(m_data);
15,197,121✔
97
        uint8_t* pos = std::lower_bound(arr, arr + m_size, value);
15,197,121✔
98
        return pos - arr;
15,197,121✔
99
    }
15,197,121✔
100
    else if (m_width == 16) {
48,079,671✔
101
        uint16_t* arr = reinterpret_cast<uint16_t*>(m_data);
39,313,626✔
102
        uint16_t* pos = std::lower_bound(arr, arr + m_size, value);
39,313,626✔
103
        return pos - arr;
39,313,626✔
104
    }
39,313,626✔
105
    else if (m_width == 32) {
8,767,968✔
106
        uint32_t* arr = reinterpret_cast<uint32_t*>(m_data);
8,738,565✔
107
        uint32_t* pos = std::lower_bound(arr, arr + m_size, value);
8,738,565✔
108
        return pos - arr;
8,738,565✔
109
    }
8,738,565✔
110
    else if (m_width < 8) {
2,147,513,050✔
111
        switch (m_width) {
×
112
            case 0:
×
113
                return realm::lower_bound<0>(m_data, m_size, value);
×
114
            case 1:
×
115
                return realm::lower_bound<1>(m_data, m_size, value);
×
116
            case 2:
×
117
                return realm::lower_bound<2>(m_data, m_size, value);
×
118
            case 4:
×
119
                return realm::lower_bound<4>(m_data, m_size, value);
×
120
            default:
×
121
                REALM_UNREACHABLE();
122
                break;
×
123
        }
×
124
        return npos;
×
125
    }
×
126
    uint64_t* arr = reinterpret_cast<uint64_t*>(m_data);
2,147,513,050✔
127
    uint64_t* pos = std::lower_bound(arr, arr + m_size, value);
2,147,513,050✔
128
    return pos - arr;
2,147,513,050✔
129
}
63,276,792✔
130

131
size_t ArrayUnsigned::upper_bound(uint64_t value) const noexcept
132
{
340,145,148✔
133
    if (m_width == 8) {
340,145,148✔
134
        uint8_t* arr = reinterpret_cast<uint8_t*>(m_data);
1,548✔
135
        uint8_t* pos = std::upper_bound(arr, arr + m_size, value);
1,548✔
136
        return pos - arr;
1,548✔
137
    }
1,548✔
138
    else if (m_width == 16) {
340,143,600✔
139
        uint16_t* arr = reinterpret_cast<uint16_t*>(m_data);
21,941,094✔
140
        uint16_t* pos = std::upper_bound(arr, arr + m_size, value);
21,941,094✔
141
        return pos - arr;
21,941,094✔
142
    }
21,941,094✔
143
    else if (m_width == 32) {
318,202,506✔
144
        uint32_t* arr = reinterpret_cast<uint32_t*>(m_data);
295,489,860✔
145
        uint32_t* pos = std::upper_bound(arr, arr + m_size, value);
295,489,860✔
146
        return pos - arr;
295,489,860✔
147
    }
295,489,860✔
148
    else if (m_width < 8) {
22,712,646✔
149
        switch (m_width) {
×
150
            case 0:
×
151
                return realm::upper_bound<0>(m_data, m_size, value);
×
152
            case 1:
×
153
                return realm::upper_bound<1>(m_data, m_size, value);
×
154
            case 2:
×
155
                return realm::upper_bound<2>(m_data, m_size, value);
×
156
            case 4:
×
157
                return realm::upper_bound<4>(m_data, m_size, value);
×
158
            default:
×
159
                REALM_UNREACHABLE();
160
                break;
×
161
        }
×
162
        return npos;
×
163
    }
×
164
    uint64_t* arr = reinterpret_cast<uint64_t*>(m_data);
22,712,646✔
165
    uint64_t* pos = std::upper_bound(arr, arr + m_size, value);
22,712,646✔
166
    return pos - arr;
22,712,646✔
167
}
340,145,148✔
168

169
void ArrayUnsigned::insert(size_t ndx, uint64_t value)
170
{
2,993,061✔
171
    REALM_ASSERT_DEBUG(m_width >= 8);
2,993,061✔
172

173
    bool do_expand = value > (uint64_t)m_ubound;
2,993,061✔
174
    const uint8_t old_width = m_width;
2,993,061✔
175
    const uint8_t new_width = do_expand ? bit_width(value) : m_width;
2,993,061✔
176
    const auto old_size = m_size;
2,993,061✔
177

178
    REALM_ASSERT_DEBUG(!do_expand || new_width > m_width);
2,993,061✔
179
    REALM_ASSERT_DEBUG(ndx <= m_size);
2,993,061✔
180

181
    // Check if we need to copy before modifying
182
    copy_on_write();              // Throws
2,993,061✔
183
    alloc(m_size + 1, new_width); // Throws
2,993,061✔
184

185
    // Move values above insertion (may expand)
186
    if (do_expand) {
2,993,061✔
187
        size_t i = old_size;
18,522✔
188
        while (i > ndx) {
18,534✔
189
            --i;
12✔
190
            auto tmp = _get(i, old_width);
12✔
191
            _set(i + 1, new_width, tmp);
12✔
192
        }
12✔
193
    }
18,522✔
194
    else if (ndx != m_size) {
2,974,539✔
195
        size_t w = (new_width >> 3);
2,974,182✔
196

197
        char* src_begin = m_data + ndx * w;
2,974,182✔
198
        char* src_end = m_data + old_size * w;
2,974,182✔
199
        char* dst = src_end + w;
2,974,182✔
200

201
        std::copy_backward(src_begin, src_end, dst);
2,974,182✔
202
    }
2,974,182✔
203

204
    // Insert the new value
205
    _set(ndx, new_width, value);
2,993,061✔
206

207
    // Expand values before insertion
208
    if (do_expand) {
2,993,061✔
209
        size_t i = ndx;
18,522✔
210
        while (i != 0) {
970,845✔
211
            --i;
952,323✔
212
            _set(i, new_width, _get(i, old_width));
952,323✔
213
        }
952,323✔
214
    }
18,522✔
215
}
2,993,061✔
216

217
void ArrayUnsigned::erase(size_t ndx)
218
{
5,277,585✔
219
    REALM_ASSERT_DEBUG(m_width >= 8);
5,277,585✔
220

221
    copy_on_write(); // Throws
5,277,585✔
222

223
    size_t w = m_width >> 3;
5,277,585✔
224

225
    char* dst = m_data + ndx * w;
5,277,585✔
226
    const char* src = dst + w;
5,277,585✔
227
    size_t num_bytes = (m_size - ndx - 1) * w;
5,277,585✔
228

229
    std::copy_n(src, num_bytes, dst);
5,277,585✔
230

231
    // Update size (also in header)
232
    --m_size;
5,277,585✔
233
    set_header_size(m_size);
5,277,585✔
234
}
5,277,585✔
235

236
uint64_t ArrayUnsigned::get(size_t index) const
237
{
493,836,246✔
238
    return _get(index, m_width);
493,836,246✔
239
}
493,836,246✔
240

241
void ArrayUnsigned::set(size_t ndx, uint64_t value)
242
{
8,921,346✔
243
    REALM_ASSERT_DEBUG(m_width >= 8);
8,921,346✔
244
    copy_on_write(); // Throws
8,921,346✔
245

246
    if (value > m_ubound) {
8,921,346✔
247
        const uint8_t old_width = m_width;
12,036✔
248
        const uint8_t new_width = bit_width(value);
12,036✔
249

250
        alloc(m_size, new_width); // Throws
12,036✔
251

252
        size_t i = m_size;
12,036✔
253
        while (i) {
3,090,930✔
254
            i--;
3,078,894✔
255
            auto v = _get(i, old_width);
3,078,894✔
256
            _set(i, new_width, v);
3,078,894✔
257
        }
3,078,894✔
258
    }
12,036✔
259

260
    _set(ndx, m_width, value);
8,921,346✔
261
}
8,921,346✔
262

263
void ArrayUnsigned::truncate(size_t ndx)
264
{
12,561✔
265
    m_size = ndx;
12,561✔
266
    copy_on_write();
12,561✔
267
    set_header_size(m_size);
12,561✔
268
    if (ndx == 0) {
12,561✔
269
        set_width(8);
7,797✔
270
        set_width_in_header(8, get_header());
7,797✔
271
    }
7,797✔
272
}
12,561✔
273

274
} // namespace realm
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