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

realm / realm-core / jorgen.edelbo_390

12 Aug 2024 12:13PM UTC coverage: 91.108% (+0.02%) from 91.085%
jorgen.edelbo_390

Pull #7979

Evergreen

jedelbo
Create test file in file-format 24
Pull Request #7979: Create test file in file-format 24

102766 of 181590 branches covered (56.59%)

19 of 19 new or added lines in 1 file covered. (100.0%)

1020 existing lines in 55 files now uncovered.

217365 of 238579 relevant lines covered (91.11%)

5621116.99 hits per line

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

85.86
/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,465,787✔
27
    REALM_ASSERT_DEBUG(width > 0 || m_size == 0);
146,465,787!
28
    m_ubound = uint64_t(-1) >> (64 - width);
146,465,787✔
29
    m_width = width;
146,465,787✔
30
}
146,465,787✔
31

32
inline uint8_t ArrayUnsigned::bit_width(uint64_t value)
33
{
85,560✔
34
    if (value < 0x100) {
85,560✔
35
        return 8;
54,183✔
36
    }
54,183✔
37
    if (value < 0x10000) {
31,377✔
38
        return 16;
14,091✔
39
    }
14,091✔
40
    if (value < 0x100000000) {
17,286✔
41
        return 32;
14,739✔
42
    }
14,739✔
43
    return 64;
2,547✔
44
}
17,286✔
45

46
inline void ArrayUnsigned::_set(size_t ndx, uint8_t width, uint64_t value)
47
{
16,028,208✔
48
    if (width == 8) {
16,028,208✔
49
        reinterpret_cast<uint8_t*>(m_data)[ndx] = uint8_t(value);
5,963,052✔
50
    }
5,963,052✔
51
    else if (width == 16) {
10,065,156✔
52
        reinterpret_cast<uint16_t*>(m_data)[ndx] = uint16_t(value);
4,266,513✔
53
    }
4,266,513✔
54
    else if (width == 32) {
5,798,643✔
55
        reinterpret_cast<uint32_t*>(m_data)[ndx] = uint32_t(value);
5,752,713✔
56
    }
5,752,713✔
57
    else {
45,930✔
58
        reinterpret_cast<uint64_t*>(m_data)[ndx] = uint64_t(value);
45,930✔
59
    }
45,930✔
60
}
16,028,208✔
61

62
inline uint64_t ArrayUnsigned::_get(size_t ndx, uint8_t width) const
63
{
393,709,368✔
64
    if (width == 8) {
393,709,368✔
65
        return reinterpret_cast<uint8_t*>(m_data)[ndx];
22,543,680✔
66
    }
22,543,680✔
67
    if (width == 16) {
371,165,688✔
68
        return reinterpret_cast<uint16_t*>(m_data)[ndx];
65,248,557✔
69
    }
65,248,557✔
70
    if (width == 32) {
305,917,131✔
71
        return reinterpret_cast<uint32_t*>(m_data)[ndx];
284,926,398✔
72
    }
284,926,398✔
73
    return get_direct(m_data, width, ndx);
20,990,733✔
74
}
305,917,131✔
75

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

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

92
size_t ArrayUnsigned::lower_bound(uint64_t value) const noexcept
93
{
63,632,298✔
94
    if (m_width == 8) {
63,632,298✔
95
        uint8_t* arr = reinterpret_cast<uint8_t*>(m_data);
15,329,244✔
96
        uint8_t* pos = std::lower_bound(arr, arr + m_size, value);
15,329,244✔
97
        return pos - arr;
15,329,244✔
98
    }
15,329,244✔
99
    else if (m_width == 16) {
48,303,054✔
100
        uint16_t* arr = reinterpret_cast<uint16_t*>(m_data);
39,461,217✔
101
        uint16_t* pos = std::lower_bound(arr, arr + m_size, value);
39,461,217✔
102
        return pos - arr;
39,461,217✔
103
    }
39,461,217✔
104
    else if (m_width == 32) {
8,841,837✔
105
        uint32_t* arr = reinterpret_cast<uint32_t*>(m_data);
8,628,876✔
106
        uint32_t* pos = std::lower_bound(arr, arr + m_size, value);
8,628,876✔
107
        return pos - arr;
8,628,876✔
108
    }
8,628,876✔
109
    else if (m_width < 8) {
212,961✔
UNCOV
110
        switch (m_width) {
×
111
            case 0:
×
112
                return realm::lower_bound<0>(m_data, m_size, value);
×
113
            case 1:
×
114
                return realm::lower_bound<1>(m_data, m_size, value);
×
115
            case 2:
×
116
                return realm::lower_bound<2>(m_data, m_size, value);
×
117
            case 4:
×
118
                return realm::lower_bound<4>(m_data, m_size, value);
×
119
            default:
×
120
                REALM_UNREACHABLE();
UNCOV
121
                break;
×
122
        }
×
123
        return npos;
×
124
    }
×
125
    uint64_t* arr = reinterpret_cast<uint64_t*>(m_data);
212,961✔
126
    uint64_t* pos = std::lower_bound(arr, arr + m_size, value);
212,961✔
127
    return pos - arr;
212,961✔
128
}
63,632,298✔
129

130
size_t ArrayUnsigned::upper_bound(uint64_t value) const noexcept
131
{
232,584,903✔
132
    if (m_width == 8) {
232,584,903✔
133
        uint8_t* arr = reinterpret_cast<uint8_t*>(m_data);
1,548✔
134
        uint8_t* pos = std::upper_bound(arr, arr + m_size, value);
1,548✔
135
        return pos - arr;
1,548✔
136
    }
1,548✔
137
    else if (m_width == 16) {
232,583,355✔
138
        uint16_t* arr = reinterpret_cast<uint16_t*>(m_data);
22,072,302✔
139
        uint16_t* pos = std::upper_bound(arr, arr + m_size, value);
22,072,302✔
140
        return pos - arr;
22,072,302✔
141
    }
22,072,302✔
142
    else if (m_width == 32) {
210,511,053✔
143
        uint32_t* arr = reinterpret_cast<uint32_t*>(m_data);
188,184,645✔
144
        uint32_t* pos = std::upper_bound(arr, arr + m_size, value);
188,184,645✔
145
        return pos - arr;
188,184,645✔
146
    }
188,184,645✔
147
    else if (m_width < 8) {
22,326,408✔
UNCOV
148
        switch (m_width) {
×
149
            case 0:
×
150
                return realm::upper_bound<0>(m_data, m_size, value);
×
151
            case 1:
×
152
                return realm::upper_bound<1>(m_data, m_size, value);
×
153
            case 2:
×
154
                return realm::upper_bound<2>(m_data, m_size, value);
×
155
            case 4:
×
156
                return realm::upper_bound<4>(m_data, m_size, value);
×
157
            default:
×
158
                REALM_UNREACHABLE();
UNCOV
159
                break;
×
160
        }
×
161
        return npos;
×
162
    }
×
163
    uint64_t* arr = reinterpret_cast<uint64_t*>(m_data);
22,326,408✔
164
    uint64_t* pos = std::upper_bound(arr, arr + m_size, value);
22,326,408✔
165
    return pos - arr;
22,326,408✔
166
}
232,584,903✔
167

168
void ArrayUnsigned::insert(size_t ndx, uint64_t value)
169
{
3,058,548✔
170
    REALM_ASSERT_DEBUG(m_width >= 8);
3,058,548✔
171
    bool do_expand = value > m_ubound;
3,058,548✔
172
    const uint8_t old_width = m_width;
3,058,548✔
173
    const uint8_t new_width = do_expand ? bit_width(value) : m_width;
3,058,548✔
174
    const auto old_size = m_size;
3,058,548✔
175

176
    REALM_ASSERT_DEBUG(!do_expand || new_width > m_width);
3,058,548✔
177
    REALM_ASSERT_DEBUG(ndx <= m_size);
3,058,548✔
178

179
    // Check if we need to copy before modifying
180
    copy_on_write();              // Throws
3,058,548✔
181
    alloc(m_size + 1, new_width); // Throws
3,058,548✔
182

183
    // Move values above insertion (may expand)
184
    if (do_expand) {
3,058,548✔
185
        size_t i = old_size;
18,900✔
186
        while (i > ndx) {
18,912✔
187
            --i;
12✔
188
            auto tmp = _get(i, old_width);
12✔
189
            _set(i + 1, new_width, tmp);
12✔
190
        }
12✔
191
    }
18,900✔
192
    else if (ndx != m_size) {
3,039,702✔
193
        size_t w = (new_width >> 3);
3,039,429✔
194

195
        char* src_begin = m_data + ndx * w;
3,039,429✔
196
        char* src_end = m_data + old_size * w;
3,039,429✔
197
        char* dst = src_end + w;
3,039,429✔
198

199
        std::copy_backward(src_begin, src_end, dst);
3,039,429✔
200
    }
3,039,429✔
201

202
    // Insert the new value
203
    _set(ndx, new_width, value);
3,058,548✔
204

205
    // Expand values before insertion
206
    if (do_expand) {
3,058,548✔
207
        size_t i = ndx;
18,900✔
208
        while (i != 0) {
974,874✔
209
            --i;
955,974✔
210
            _set(i, new_width, _get(i, old_width));
955,974✔
211
        }
955,974✔
212
    }
18,900✔
213
}
3,058,548✔
214

215
void ArrayUnsigned::erase(size_t ndx)
216
{
5,317,161✔
217
    REALM_ASSERT_DEBUG(m_width >= 8);
5,317,161✔
218
    copy_on_write(); // Throws
5,317,161✔
219

220
    size_t w = m_width >> 3;
5,317,161✔
221

222
    char* dst = m_data + ndx * w;
5,317,161✔
223
    const char* src = dst + w;
5,317,161✔
224
    size_t num_bytes = (m_size - ndx - 1) * w;
5,317,161✔
225

226
    std::copy_n(src, num_bytes, dst);
5,317,161✔
227

228
    // Update size (also in header)
229
    --m_size;
5,317,161✔
230
    set_header_size(m_size);
5,317,161✔
231
}
5,317,161✔
232

233
uint64_t ArrayUnsigned::get(size_t index) const
234
{
390,202,503✔
235
    return _get(index, m_width);
390,202,503✔
236
}
390,202,503✔
237

238
void ArrayUnsigned::set(size_t ndx, uint64_t value)
239
{
8,935,992✔
240
    REALM_ASSERT_DEBUG(m_width >= 8);
8,935,992✔
241
    copy_on_write(); // Throws
8,935,992✔
242

243
    if (value > m_ubound) {
8,935,992✔
244
        const uint8_t old_width = m_width;
12,036✔
245
        const uint8_t new_width = bit_width(value);
12,036✔
246

247
        alloc(m_size, new_width); // Throws
12,036✔
248

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

257
    _set(ndx, m_width, value);
8,935,992✔
258
}
8,935,992✔
259

260
void ArrayUnsigned::truncate(size_t ndx)
261
{
12,750✔
262
    m_size = ndx;
12,750✔
263
    copy_on_write();
12,750✔
264
    set_header_size(m_size);
12,750✔
265
    if (ndx == 0) {
12,750✔
266
        set_width(8);
7,896✔
267
        set_width_in_header(8, get_header());
7,896✔
268
    }
7,896✔
269
}
12,750✔
270

271
} // 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

© 2026 Coveralls, Inc