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

realm / realm-core / nicola.cabiddu_1040

26 Sep 2023 05:08PM UTC coverage: 91.056% (-1.9%) from 92.915%
nicola.cabiddu_1040

Pull #6766

Evergreen

nicola-cab
several fixes and final client reset algo for collection in mixed
Pull Request #6766: Client Reset for collections in mixed / nested collections

97128 of 178458 branches covered (0.0%)

1524 of 1603 new or added lines in 5 files covered. (95.07%)

4511 existing lines in 109 files now uncovered.

236619 of 259862 relevant lines covered (91.06%)

7169640.31 hits per line

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

91.4
/src/realm/array_decimal128.cpp
1
/*************************************************************************
2
 *
3
 * Copyright 2019 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_decimal128.hpp>
20
#include <realm/mixed.hpp>
21

22
namespace realm {
23

24
namespace {
25

26
uint8_t min_width(const Decimal128& value, bool zero_width_is_zero)
27
{
292,773✔
28
    Decimal128::Bid128 coefficient;
292,773✔
29
    int exponent;
292,773✔
30
    bool sign;
292,773✔
31

146,238✔
32
    if (value.is_null()) {
292,773✔
33
        return zero_width_is_zero ? 4 : 0;
58,983✔
34
    }
59,784✔
35

116,496✔
36
    value.unpack(coefficient, exponent, sign);
232,989✔
37
    if (coefficient.w[1] == 0) {
232,989✔
38
        if (coefficient.w[0] == 0 && exponent == 0) {
232,923✔
39
            return zero_width_is_zero ? 0 : 4;
43,386✔
40
        }
50,175✔
41
        if (coefficient.w[0] < (1ull << 23) && exponent > -91 && exponent < 91) {
182,748✔
42
            return 4;
161,088✔
43
        }
161,088✔
44
        if (coefficient.w[0] < (1ull << 53) && exponent > -370 && exponent < 370) {
21,660✔
45
            return 8;
222✔
46
        }
222✔
47
    }
21,504✔
48
    return 16;
21,504✔
49
}
21,504✔
50
} // namespace
51

52
void ArrayDecimal128::set(size_t ndx, Decimal128 value)
53
{
72,495✔
54
    REALM_ASSERT(ndx < m_size);
72,495✔
55
    copy_on_write();
72,495✔
56
    switch (upgrade_leaf(min_width(value, Array::get_context_flag()))) {
72,495✔
57
        case 0:
18✔
58
            break;
18✔
59
        case 4: {
66,663✔
60
            auto values = reinterpret_cast<Decimal::Bid32*>(m_data);
66,663✔
61
            auto val = value.to_bid32();
66,663✔
62
            REALM_ASSERT(val);
66,663✔
63
            values[ndx] = *val;
66,663✔
64
            break;
66,663✔
UNCOV
65
        }
×
66
        case 8: {
138✔
67
            auto values = reinterpret_cast<Decimal::Bid64*>(m_data);
138✔
68
            auto val = value.to_bid64();
138✔
69
            REALM_ASSERT(val);
138✔
70
            values[ndx] = *val;
138✔
71
            break;
138✔
UNCOV
72
        }
×
73
        case 16: {
5,676✔
74
            auto values = reinterpret_cast<Decimal128*>(m_data);
5,676✔
75
            values[ndx] = value;
5,676✔
76
            break;
5,676✔
UNCOV
77
        }
×
78
    }
72,495✔
79
}
72,495✔
80

81
void ArrayDecimal128::insert(size_t ndx, Decimal128 value)
82
{
220,002✔
83
    REALM_ASSERT(ndx <= m_size);
220,002✔
84
    if (m_size == 0 && value == Decimal128()) {
220,002✔
85
        // zero width should be interpreted as 0
1,998✔
86
        Array::copy_on_write();
3,996✔
87
        Array::set_context_flag(true);
3,996✔
88
    }
3,996✔
89
    // Allocate room for the new value
109,851✔
90
    switch (upgrade_leaf(min_width(value, Array::get_context_flag()))) {
220,002✔
91
        case 0:
22,398✔
92
            m_size += 1;
22,398✔
93
            Array::copy_on_write();
22,398✔
94
            set_header_size(m_size);
22,398✔
95
            break;
22,398✔
96
        case 4: {
153,924✔
97
            alloc(m_size + 1, 4); // Throws
153,924✔
98

76,962✔
99
            auto src = reinterpret_cast<Decimal::Bid32*>(m_data) + ndx;
153,924✔
100
            auto dst = src + 1;
153,924✔
101

76,962✔
102
            // Make gap for new value
76,962✔
103
            memmove(dst, src, sizeof(Decimal::Bid32) * (m_size - 1 - ndx));
153,924✔
104

76,962✔
105
            // Set new value
76,962✔
106
            auto val = value.to_bid32();
153,924✔
107
            REALM_ASSERT(val);
153,924✔
108
            *src = *val;
153,924✔
109
            break;
153,924✔
UNCOV
110
        }
×
111
        case 8: {
168✔
112
            alloc(m_size + 1, 8); // Throws
168✔
113

84✔
114
            auto src = reinterpret_cast<Decimal::Bid64*>(m_data) + ndx;
168✔
115
            auto dst = src + 1;
168✔
116

84✔
117
            // Make gap for new value
84✔
118
            memmove(dst, src, sizeof(Decimal::Bid64) * (m_size - 1 - ndx));
168✔
119

84✔
120
            // Set new value
84✔
121
            auto val = value.to_bid64();
168✔
122
            REALM_ASSERT(val);
168✔
123
            *src = *val;
168✔
124
            break;
168✔
UNCOV
125
        }
×
126
        case 16: {
43,512✔
127
            alloc(m_size + 1, sizeof(Decimal128)); // Throws
43,512✔
128

21,756✔
129
            auto src = reinterpret_cast<Decimal128*>(m_data) + ndx;
43,512✔
130
            auto dst = src + 1;
43,512✔
131

21,756✔
132
            // Make gap for new value
21,756✔
133
            memmove(dst, src, sizeof(Decimal128) * (m_size - 1 - ndx));
43,512✔
134

21,756✔
135
            // Set new value
21,756✔
136
            *src = value;
43,512✔
137
            break;
43,512✔
UNCOV
138
        }
×
139
    }
220,002✔
140
}
220,002✔
141

142
void ArrayDecimal128::erase(size_t ndx)
143
{
50,409✔
144

25,200✔
145
    REALM_ASSERT(ndx < m_size);
50,409✔
146

25,200✔
147
    copy_on_write();
50,409✔
148

25,200✔
149
    if (m_width) {
50,409✔
150
        auto dst = m_data + ndx * m_width;
50,262✔
151
        memmove(dst, dst + m_width, m_width * (m_size - ndx));
50,262✔
152
    }
50,262✔
153

25,200✔
154
    // Update size (also in header)
25,200✔
155
    m_size -= 1;
50,409✔
156
    set_header_size(m_size);
50,409✔
157
}
50,409✔
158

159
void ArrayDecimal128::move(ArrayDecimal128& dst_arr, size_t ndx)
160
{
72✔
161
    size_t elements_to_move = m_size - ndx;
72✔
162
    if (elements_to_move) {
72✔
163
        if (m_width >= dst_arr.m_width) {
72✔
164
            dst_arr.upgrade_leaf(m_width);
66✔
165
            const auto old_dst_size = dst_arr.m_size;
66✔
166
            dst_arr.alloc(old_dst_size + elements_to_move, m_width);
66✔
167
            auto dst = dst_arr.m_data + old_dst_size * m_width;
66✔
168
            auto src = m_data + ndx * m_width;
66✔
169
            memmove(dst, src, elements_to_move * m_width);
66✔
170
        }
66✔
171
        else {
6✔
172
            for (size_t i = 0; i < elements_to_move; i++) {
12✔
173
                dst_arr.add(get(ndx + i));
6✔
174
            }
6✔
175
        }
6✔
176
    }
72✔
177
    truncate(ndx);
72✔
178
}
72✔
179

180
size_t ArrayDecimal128::find_first(Decimal128 value, size_t start, size_t end) const noexcept
181
{
276✔
182
    auto sz = size();
276✔
183
    if (end == size_t(-1))
276✔
184
        end = sz;
24✔
185
    REALM_ASSERT(start <= sz && end <= sz && start <= end);
276✔
186

138✔
187
    bool zero_width_is_zero = Array::get_context_flag();
276✔
188
    auto width = min_width(value, zero_width_is_zero);
276✔
189
    switch (m_width) {
276✔
UNCOV
190
        case 0:
✔
UNCOV
191
            if (zero_width_is_zero) {
×
UNCOV
192
                if (value == Decimal128()) {
×
UNCOV
193
                    return 0;
×
UNCOV
194
                }
×
UNCOV
195
            }
×
UNCOV
196
            else {
×
UNCOV
197
                if (value.is_null()) {
×
UNCOV
198
                    return 0;
×
UNCOV
199
                }
×
UNCOV
200
            }
×
UNCOV
201
            break;
×
202
        case 4:
270✔
203
            if (width <= 4) {
270✔
204
                // Worth optimizing here
135✔
205
                auto optval32 = value.to_bid32();
270✔
206
                REALM_ASSERT(optval32);
270✔
207
                auto val32 = *optval32;
270✔
208
                auto values = reinterpret_cast<Decimal128::Bid32*>(this->m_data);
270✔
209
                for (size_t i = start; i < end; i++) {
528✔
210
                    if (values[i] == val32)
480✔
211
                        return i;
222✔
212
                }
480✔
213
            }
270✔
214
            break;
159✔
215
        case 8:
138✔
216
            if (width <= 8) {
6✔
217
                auto values = reinterpret_cast<Decimal128::Bid64*>(this->m_data);
6✔
218
                for (size_t i = start; i < end; i++) {
12✔
219
                    if (Decimal128(values[i]) == value)
12✔
220
                        return i;
6✔
221
                }
12✔
222
            }
6✔
223
            break;
3✔
224
        case 16: {
3✔
UNCOV
225
            auto values = reinterpret_cast<Decimal128*>(this->m_data);
×
UNCOV
226
            for (size_t i = start; i < end; i++) {
×
UNCOV
227
                if (values[i] == value)
×
UNCOV
228
                    return i;
×
UNCOV
229
            }
×
UNCOV
230
            break;
×
231
        }
48✔
232
    }
48✔
233

24✔
234
    return realm::npos;
48✔
235
}
48✔
236

237
Mixed ArrayDecimal128::get_any(size_t ndx) const
238
{
22,824✔
239
    return Mixed(get(ndx));
22,824✔
240
}
22,824✔
241

242

243
size_t ArrayDecimal128::upgrade_leaf(uint8_t width)
244
{
292,563✔
245
    if (m_width == 16) {
292,563✔
246
        return 16;
37,740✔
247
    }
37,740✔
248
    if (width <= m_width) {
254,823✔
249
        return m_width;
233,883✔
250
    }
233,883✔
251

10,470✔
252
    if (m_size == 0) {
20,940✔
253
        alloc(m_size, width);
9,828✔
254
        return width;
9,828✔
255
    }
9,828✔
256

5,556✔
257
    if (m_width == 8) {
11,112✔
258
        // Upgrade to 16 bytes
9✔
259
        alloc(m_size, 16);
18✔
260
        auto src = reinterpret_cast<Decimal::Bid64*>(m_data);
18✔
261
        auto dst = reinterpret_cast<Decimal::Bid128*>(m_data);
18✔
262
        for (size_t i = m_size; i > 0; --i) {
144✔
263
            auto val = Decimal128(src[i - 1]);
126✔
264
            dst[i - 1] = *val.raw();
126✔
265
        }
126✔
266
        return 16;
18✔
267
    }
18✔
268

5,547✔
269
    if (m_width == 4) {
11,094✔
270
        alloc(m_size, width);
5,952✔
271
        auto src = reinterpret_cast<Decimal::Bid32*>(m_data);
5,952✔
272
        if (width == 8) {
5,952✔
273
            // Upgrade to 8 bytes
15✔
274
            auto dst = reinterpret_cast<Decimal::Bid64*>(m_data);
30✔
275
            for (size_t i = m_size; i > 0; --i) {
102✔
276
                auto val = Decimal128(src[i - 1]);
72✔
277
                dst[i - 1] = *val.to_bid64();
72✔
278
            }
72✔
279
        }
30✔
280
        else if (width == 16) {
5,922✔
281
            // Upgrade to 16 bytes
2,961✔
282
            auto dst = reinterpret_cast<Decimal::Bid128*>(m_data);
5,922✔
283
            for (size_t i = m_size; i > 0; --i) {
21,108✔
284
                auto val = Decimal128(src[i - 1]);
15,186✔
285
                dst[i - 1] = *val.raw();
15,186✔
286
            }
15,186✔
287
        }
5,922✔
288
        return width;
5,952✔
289
    }
5,952✔
290

2,571✔
291
    // Upgrade from zero width. Fill with either 0 or null.
2,571✔
292
    Decimal128 fill_value = get_context_flag() ? Decimal128(0) : Decimal128(realm::null());
5,142✔
293

2,571✔
294
    if (width == 4) {
5,142✔
295
        // Upgrade to 4 bytes
1,764✔
296
        alloc(m_size, 4);
3,528✔
297
        auto values = reinterpret_cast<Decimal::Bid32*>(m_data);
3,528✔
298
        auto fill = *fill_value.to_bid32();
3,528✔
299
        for (size_t i = 0; i < m_size; i++) {
9,696✔
300
            values[i] = fill;
6,168✔
301
        }
6,168✔
302
        return 4;
3,528✔
303
    }
3,528✔
304
    else if (width == 8) {
1,614✔
305
        // Upgrade to 8 bytes
9✔
306
        alloc(m_size, 8);
18✔
307
        auto values = reinterpret_cast<Decimal::Bid64*>(m_data);
18✔
308
        auto fill = *fill_value.to_bid64();
18✔
309
        for (size_t i = 0; i < m_size; i++) {
84✔
310
            values[i] = fill;
66✔
311
        }
66✔
312
        return 8;
18✔
313
    }
18✔
314

798✔
315
    alloc(m_size, 16);
1,596✔
316
    auto values = reinterpret_cast<Decimal128*>(m_data);
1,596✔
317
    for (size_t i = 0; i < m_size; i++) {
6,264✔
318
        values[i] = fill_value;
4,668✔
319
    }
4,668✔
320
    return 16;
1,596✔
321
}
1,596✔
322

323

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