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

realm / realm-core / nicola.cabiddu_1042

27 Sep 2023 06:04PM UTC coverage: 91.085% (-1.8%) from 92.915%
nicola.cabiddu_1042

Pull #6766

Evergreen

nicola-cab
Fix logic for dictionaries
Pull Request #6766: Client Reset for collections in mixed / nested collections

97276 of 178892 branches covered (0.0%)

1994 of 2029 new or added lines in 7 files covered. (98.28%)

4556 existing lines in 112 files now uncovered.

237059 of 260260 relevant lines covered (91.09%)

6321099.55 hits per line

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

92.32
/src/realm/array_mixed.cpp
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
#include <realm/array_mixed.hpp>
20
#include <realm/array_basic.hpp>
21

22
using namespace realm;
23

24
ArrayMixed::ArrayMixed(Allocator& a)
25
    : Array(a)
26
    , m_composite(a)
27
    , m_ints(a)
28
    , m_int_pairs(a)
29
    , m_strings(a)
30
    , m_refs(a)
31
{
578,115✔
32
    m_composite.set_parent(this, payload_idx_type);
578,115✔
33
}
578,115✔
34

35
void ArrayMixed::create()
36
{
39,516✔
37
    Array::create(type_HasRefs, false, payload_idx_size);
39,516✔
38
    m_composite.create(type_Normal);
39,516✔
39
    m_composite.update_parent();
39,516✔
40
}
39,516✔
41

42
void ArrayMixed::init_from_mem(MemRef mem) noexcept
43
{
341,958✔
44
    Array::init_from_mem(mem);
341,958✔
45
    m_composite.init_from_parent();
341,958✔
46
    m_ints.detach();
341,958✔
47
    m_int_pairs.detach();
341,958✔
48
    m_strings.detach();
341,958✔
49
    m_refs.detach();
341,958✔
50
}
341,958✔
51

52
void ArrayMixed::add(Mixed value)
53
{
174✔
54
    if (value.is_null()) {
174✔
55
        m_composite.add(0);
60✔
56
        return;
60✔
57
    }
60✔
58
    m_composite.add(store(value));
114✔
59
}
114✔
60

61

62
void ArrayMixed::set(size_t ndx, Mixed value)
63
{
24,444✔
64
    auto old_type = get_type(ndx);
24,444✔
65
    // If we replace a collections ref value with one of the
12,216✔
66
    // same type, then it is just an update of of the
12,216✔
67
    // ref stored in the parent. If the new type is a different
12,216✔
68
    // type then it means that we are overwriting a collection
12,216✔
69
    // with some other value and hence the collection must be
12,216✔
70
    // destroyed as well as the possible key.
12,216✔
71
    bool destroy_collection = !value.is_type(old_type);
24,444✔
72

12,216✔
73
    if (value.is_null()) {
24,444✔
74
        set_null(ndx);
1,662✔
75
    }
1,662✔
76
    else {
22,782✔
77
        erase_linked_payload(ndx, destroy_collection);
22,782✔
78
        m_composite.set(ndx, store(value));
22,782✔
79
    }
22,782✔
80

12,216✔
81
    if (destroy_collection && Array::size() > payload_idx_key) {
24,444✔
82
        if (auto ref = Array::get_as_ref(payload_idx_key)) {
12,576✔
83
            Array keys(Array::get_alloc());
384✔
84
            keys.set_parent(const_cast<ArrayMixed*>(this), payload_idx_key);
384✔
85
            keys.init_from_ref(ref);
384✔
86
            if (ndx < keys.size())
384✔
87
                keys.set(ndx, 0);
366✔
88
        }
384✔
89
    }
12,576✔
90
}
24,444✔
91

92
void ArrayMixed::insert(size_t ndx, Mixed value)
93
{
133,953✔
94
    if (value.is_null()) {
133,953✔
95
        m_composite.insert(ndx, 0);
20,616✔
96
    }
20,616✔
97
    else {
113,337✔
98
        m_composite.insert(ndx, store(value));
113,337✔
99
    }
113,337✔
100
    if (Array::size() > payload_idx_key) {
133,953✔
101
        if (auto ref = Array::get_as_ref(payload_idx_key)) {
133,944✔
102
            Array keys(Array::get_alloc());
2,148✔
103
            keys.set_parent(const_cast<ArrayMixed*>(this), payload_idx_key);
2,148✔
104
            keys.init_from_ref(ref);
2,148✔
105
            keys.insert(ndx, 0);
2,148✔
106
        }
2,148✔
107
    }
133,944✔
108
}
133,953✔
109

110
void ArrayMixed::set_null(size_t ndx)
111
{
1,662✔
112
    auto val = m_composite.get(ndx);
1,662✔
113
    if (val) {
1,662✔
114
        erase_linked_payload(ndx, true);
1,332✔
115
        m_composite.set(ndx, 0);
1,332✔
116
    }
1,332✔
117
}
1,662✔
118

119
Mixed ArrayMixed::get(size_t ndx) const
120
{
1,573,407✔
121
    int64_t val = m_composite.get(ndx);
1,573,407✔
122

787,749✔
123
    if (val) {
1,573,407✔
124
        int64_t int_val = val >> s_data_shift;
1,536,429✔
125
        size_t payload_ndx = size_t(int_val);
1,536,429✔
126
        DataType type = DataType((val & s_data_type_mask) - 1);
1,536,429✔
127
        switch (type) {
1,536,429✔
128
            case type_Int: {
277,866✔
129
                if (val & s_payload_idx_mask) {
277,866✔
130
                    ensure_int_array();
4,584✔
131
                    return Mixed(m_ints.get(payload_ndx));
4,584✔
132
                }
4,584✔
133
                return Mixed(int_val);
273,282✔
134
            }
273,282✔
135
            case type_Bool:
142,008✔
136
                return Mixed(int_val != 0);
10,770✔
137
            case type_Float:
149,829✔
138
                ensure_int_array();
27,387✔
139
                return Mixed(type_punning<float>(m_ints.get(payload_ndx)));
27,387✔
140
            case type_Double:
153,702✔
141
                ensure_int_array();
34,101✔
142
                return Mixed(type_punning<double>(m_ints.get(payload_ndx)));
34,101✔
143
            case type_String: {
189,249✔
144
                ensure_string_array();
105,378✔
145
                REALM_ASSERT(size_t(int_val) < m_strings.size());
105,378✔
146
                return Mixed(m_strings.get(payload_ndx));
105,378✔
147
            }
273,282✔
148
            case type_Binary: {
145,743✔
149
                ensure_string_array();
18,879✔
150
                REALM_ASSERT(size_t(int_val) < m_strings.size());
18,879✔
151
                auto s = m_strings.get(payload_ndx);
18,879✔
152
                return Mixed(BinaryData(s.data(), s.size()));
18,879✔
153
            }
273,282✔
154
            case type_Timestamp: {
141,699✔
155
                ensure_int_pair_array();
10,170✔
156
                payload_ndx <<= 1;
10,170✔
157
                REALM_ASSERT(payload_ndx + 1 < m_int_pairs.size());
10,170✔
158
                return Mixed(Timestamp(m_int_pairs.get(payload_ndx), int32_t(m_int_pairs.get(payload_ndx + 1))));
10,170✔
159
            }
273,282✔
160
            case type_ObjectId: {
146,133✔
161
                ensure_string_array();
18,843✔
162
                REALM_ASSERT(size_t(int_val) < m_strings.size());
18,843✔
163
                auto s = m_strings.get(payload_ndx);
18,843✔
164
                ObjectId id;
18,843✔
165
                memcpy(&id, s.data(), sizeof(ObjectId));
18,843✔
166
                return Mixed(id);
18,843✔
167
            }
273,282✔
168
            case type_Decimal: {
150,456✔
169
                ensure_int_pair_array();
28,029✔
170
                Decimal128::Bid128 raw;
28,029✔
171
                payload_ndx <<= 1;
28,029✔
172
                REALM_ASSERT(payload_ndx + 1 < m_int_pairs.size());
28,029✔
173
                raw.w[0] = m_int_pairs.get(payload_ndx);
28,029✔
174
                raw.w[1] = m_int_pairs.get(payload_ndx + 1);
28,029✔
175
                return Mixed(Decimal128(raw));
28,029✔
176
            }
273,282✔
177
            case type_Link:
136,623✔
UNCOV
178
                ensure_int_array();
×
UNCOV
179
                return Mixed(ObjKey(m_ints.get(payload_ndx)));
×
180
            case type_TypedLink: {
954,249✔
181
                ensure_int_pair_array();
954,249✔
182
                payload_ndx <<= 1;
954,249✔
183
                REALM_ASSERT(payload_ndx + 1 < m_int_pairs.size());
954,249✔
184
                ObjLink ret{TableKey(uint32_t(m_int_pairs.get(payload_ndx))),
954,249✔
185
                            ObjKey(m_int_pairs.get(payload_ndx + 1))};
954,249✔
186
                return Mixed(ret);
954,249✔
187
            }
273,282✔
188
            case type_UUID: {
147,498✔
189
                ensure_string_array();
21,360✔
190
                REALM_ASSERT(size_t(int_val) < m_strings.size());
21,360✔
191
                auto s = m_strings.get(payload_ndx);
21,360✔
192
                UUID::UUIDBytes bytes{};
21,360✔
193
                std::copy_n(s.data(), bytes.size(), bytes.begin());
21,360✔
194
                return Mixed(UUID(bytes));
21,360✔
195
            }
273,282✔
196
            default:
151,347✔
197
                if (size_t((val & s_payload_idx_mask) >> s_payload_idx_shift) == payload_idx_ref) {
29,448✔
198
                    ensure_ref_array();
29,448✔
199
                    return Mixed(m_refs.get(payload_ndx), CollectionType(int(type)));
29,448✔
200
                }
29,448✔
UNCOV
201
                break;
×
202
        }
1,536,429✔
203
    }
1,536,429✔
204

18,894✔
205
    return {};
36,978✔
206
}
36,978✔
207

208
void ArrayMixed::clear()
209
{
12✔
210
    m_composite.clear();
12✔
211
    m_ints.destroy();
12✔
212
    m_int_pairs.destroy();
12✔
213
    m_strings.destroy();
12✔
214
    m_refs.destroy_deep();
12✔
215
    Array::set(payload_idx_int, 0);
12✔
216
    Array::set(payload_idx_pair, 0);
12✔
217
    Array::set(payload_idx_str, 0);
12✔
218
    Array::set(payload_idx_ref, 0);
12✔
219
}
12✔
220

221
void ArrayMixed::erase(size_t ndx)
222
{
20,907✔
223
    erase_linked_payload(ndx, true);
20,907✔
224
    m_composite.erase(ndx);
20,907✔
225
    if (Array::size() > payload_idx_key) {
20,907✔
226
        if (auto ref = Array::get_as_ref(payload_idx_key)) {
20,895✔
227
            Array keys(Array::get_alloc());
180✔
228
            keys.set_parent(const_cast<ArrayMixed*>(this), payload_idx_key);
180✔
229
            keys.init_from_ref(ref);
180✔
230
            keys.erase(ndx);
180✔
231
        }
180✔
232
    }
20,895✔
233
}
20,907✔
234

235
void ArrayMixed::move(ArrayMixed& dst, size_t ndx)
236
{
6✔
237
    auto sz = size();
6✔
238
    size_t i = ndx;
6✔
239
    while (i < sz) {
60✔
240
        auto val = get(i++);
54✔
241
        dst.add(val);
54✔
242
    }
54✔
243
    if (Array::size() > payload_idx_key) {
6✔
244
        if (auto ref = Array::get_as_ref(payload_idx_key)) {
6✔
UNCOV
245
            dst.ensure_keys();
×
UNCOV
246
            Array keys(Array::get_alloc());
×
UNCOV
247
            keys.set_parent(const_cast<ArrayMixed*>(this), payload_idx_key);
×
UNCOV
248
            keys.init_from_ref(ref);
×
UNCOV
249
            for (size_t j = 0, i = ndx; i < sz; i++, j++) {
×
UNCOV
250
                dst.set_key(j, keys.get(i));
×
UNCOV
251
            }
×
UNCOV
252
            keys.truncate(ndx);
×
UNCOV
253
        }
×
254
    }
6✔
255
    while (i > ndx) {
60✔
256
        erase_linked_payload(--i, false);
54✔
257
    }
54✔
258
    m_composite.truncate(ndx);
6✔
259
}
6✔
260

261
size_t ArrayMixed::find_first(Mixed value, size_t begin, size_t end) const noexcept
262
{
49,392✔
263
    if (value.is_null()) {
49,392✔
264
        return m_composite.find_first(0, begin, end);
462✔
265
    }
462✔
266
    DataType type = value.get_type();
48,930✔
267
    if (end == realm::npos)
48,930✔
268
        end = size();
6✔
269
    for (size_t i = begin; i < end; i++) {
126,204✔
270
        if (Mixed::data_types_are_comparable(this->get_type(i), type) && get(i) == value) {
125,928✔
271
            return i;
48,654✔
272
        }
48,654✔
273
    }
125,928✔
274
    return realm::npos;
24,567✔
275
}
48,930✔
276

277
bool ArrayMixed::ensure_keys()
278
{
1,734✔
279
    if (Array::size() < payload_idx_key + 1 || Array::get(payload_idx_key) == 0) {
1,734✔
280
        Array keys(Array::get_alloc());
816✔
281
        keys.set_parent(const_cast<ArrayMixed*>(this), payload_idx_key);
816✔
282
        keys.create(type_Normal, false, size(), 0);
816✔
283
        keys.update_parent();
816✔
284

408✔
285
        return false;
816✔
286
    }
816✔
287
    return true;
918✔
288
}
918✔
289

290
size_t ArrayMixed::find_key(int64_t key) const noexcept
291
{
15,201✔
292
    Array keys(Array::get_alloc());
15,201✔
293
    ensure_array_accessor(keys, payload_idx_key);
15,201✔
294
    return keys.find_first(key);
15,201✔
295
}
15,201✔
296

297
void ArrayMixed::set_key(size_t ndx, int64_t key)
298
{
2,694✔
299
    Array keys(Array::get_alloc());
2,694✔
300
    ensure_array_accessor(keys, payload_idx_key);
2,694✔
301
    while (keys.size() <= ndx) {
3,456✔
302
        keys.add(0);
762✔
303
    }
762✔
304
    keys.set(ndx, key);
2,694✔
305
}
2,694✔
306

307
int64_t ArrayMixed::get_key(size_t ndx) const
308
{
19,800✔
309
    Array keys(Array::get_alloc());
19,800✔
310
    if (ref_type ref = get_as_ref(payload_idx_key)) {
19,800✔
311
        keys.init_from_ref(ref);
19,692✔
312
        return (ndx < keys.size()) ? keys.get(ndx) : 0;
19,692✔
313
    }
19,692✔
314
    return 0;
108✔
315
}
108✔
316

317
void ArrayMixed::verify() const
318
{
12,222✔
319
    // TODO: Implement
6,114✔
320
}
12,222✔
321

322
void ArrayMixed::ensure_array_accessor(Array& arr, size_t ndx_in_parent) const
323
{
1,187,706✔
324
    if (!arr.is_attached()) {
1,187,706✔
325
        ref_type ref = get_as_ref(ndx_in_parent);
184,362✔
326
        arr.set_parent(const_cast<ArrayMixed*>(this), ndx_in_parent);
184,362✔
327
        if (ref) {
184,362✔
328
            arr.init_from_ref(ref);
166,656✔
329
        }
166,656✔
330
        else {
17,706✔
331
            arr.create(ndx_in_parent == payload_idx_ref ? type_HasRefs : type_Normal);
16,914✔
332
            arr.update_parent();
17,706✔
333
        }
17,706✔
334
    }
184,362✔
335
}
1,187,706✔
336

337
void ArrayMixed::ensure_int_array() const
338
{
88,125✔
339
    ensure_array_accessor(m_ints, payload_idx_int);
88,125✔
340
}
88,125✔
341

342
void ArrayMixed::ensure_int_pair_array() const
343
{
1,042,464✔
344
    ensure_array_accessor(m_int_pairs, payload_idx_pair);
1,042,464✔
345
}
1,042,464✔
346

347
void ArrayMixed::ensure_string_array() const
348
{
212,700✔
349
    if (!m_strings.is_attached()) {
212,700✔
350
        ref_type ref = get_as_ref(payload_idx_str);
66,612✔
351
        m_strings.set_parent(const_cast<ArrayMixed*>(this), payload_idx_str);
66,612✔
352
        if (ref) {
66,612✔
353
            m_strings.init_from_ref(ref);
50,142✔
354
        }
50,142✔
355
        else {
16,470✔
356
            m_strings.create();
16,470✔
357
            m_strings.update_parent();
16,470✔
358
        }
16,470✔
359
    }
66,612✔
360
}
212,700✔
361

362
void ArrayMixed::ensure_ref_array() const
363
{
39,222✔
364
    while (Array::size() < payload_idx_ref + 1) {
39,222✔
UNCOV
365
        const_cast<ArrayMixed*>(this)->Array::add(0);
×
366
    }
×
367
    ensure_array_accessor(m_refs, payload_idx_ref);
39,222✔
368
}
39,222✔
369

370
void ArrayMixed::replace_index(size_t old_ndx, size_t new_ndx, size_t payload_arr_index)
371
{
12,507✔
372
    if (old_ndx != new_ndx) {
12,507✔
373
        size_t sz = m_composite.size();
12,507✔
374
        for (size_t i = 0; i != sz; i++) {
749,319✔
375
            int64_t val = m_composite.get(i);
749,319✔
376
            if (size_t((val & s_payload_idx_mask) >> s_payload_idx_shift) == payload_arr_index &&
749,319✔
377
                (val >> s_data_shift) == int64_t(old_ndx)) {
661,890✔
378
                m_composite.set(i, int64_t(new_ndx << s_data_shift) | (val & 0xff));
12,507✔
379
                return;
12,507✔
380
            }
12,507✔
381
        }
749,319✔
382
    }
12,507✔
383
}
12,507✔
384

385
void ArrayMixed::erase_linked_payload(size_t ndx, bool free_linked_arrays)
386
{
45,075✔
387
    auto val = m_composite.get(ndx);
45,075✔
388
    auto payload_arr_index = size_t((val & s_payload_idx_mask) >> s_payload_idx_shift);
45,075✔
389

22,572✔
390
    if (payload_arr_index) {
45,075✔
391
        // A value is stored in one of the payload arrays
13,776✔
392
        size_t last_ndx = 0;
27,450✔
393
        size_t erase_ndx = size_t(val >> s_data_shift);
27,450✔
394
        // Clean up current value by moving last over
13,776✔
395
        switch (payload_arr_index) {
27,450✔
396
            case payload_idx_int: {
5,334✔
397
                ensure_int_array();
5,334✔
398
                last_ndx = m_ints.size() - 1;
5,334✔
399
                if (erase_ndx != last_ndx) {
5,334✔
400
                    m_ints.set(erase_ndx, m_ints.get(last_ndx));
3,627✔
401
                    replace_index(last_ndx, erase_ndx, payload_arr_index);
3,627✔
402
                }
3,627✔
403
                m_ints.erase(last_ndx);
5,334✔
404
                break;
5,334✔
UNCOV
405
            }
×
406
            case payload_idx_str: {
7,404✔
407
                ensure_string_array();
7,404✔
408
                last_ndx = m_strings.size() - 1;
7,404✔
409
                if (erase_ndx != last_ndx) {
7,404✔
410
                    StringData tmp = m_strings.get(last_ndx);
3,936✔
411
                    std::string tmp_val(tmp.data(), tmp.size());
3,936✔
412
                    m_strings.set(erase_ndx, StringData(tmp_val));
3,936✔
413
                    replace_index(last_ndx, erase_ndx, payload_arr_index);
3,936✔
414
                }
3,936✔
415
                m_strings.erase(last_ndx);
7,404✔
416
                break;
7,404✔
417
            }
×
418
            case payload_idx_pair: {
11,016✔
419
                ensure_int_pair_array();
11,016✔
420
                last_ndx = m_int_pairs.size() - 2;
11,016✔
421
                erase_ndx <<= 1;
11,016✔
422
                if (erase_ndx != last_ndx) {
11,016✔
423
                    m_int_pairs.set(erase_ndx, m_int_pairs.get(last_ndx));
4,320✔
424
                    m_int_pairs.set(erase_ndx + 1, m_int_pairs.get(last_ndx + 1));
4,320✔
425
                    replace_index(last_ndx >> 1, erase_ndx >> 1, payload_arr_index);
4,320✔
426
                }
4,320✔
427
                m_int_pairs.truncate(last_ndx);
11,016✔
428
                break;
11,016✔
UNCOV
429
            }
×
430
            case payload_idx_ref: {
3,696✔
431
                ensure_ref_array();
3,696✔
432
                last_ndx = m_refs.size() - 1;
3,696✔
433
                auto old_ref = m_refs.get(erase_ndx);
3,696✔
434
                if (erase_ndx != last_ndx) {
3,696✔
435
                    m_refs.set(erase_ndx, m_refs.get(last_ndx));
624✔
436
                    replace_index(last_ndx, erase_ndx, payload_arr_index);
624✔
437
                }
624✔
438
                m_refs.erase(last_ndx);
3,696✔
439
                if (old_ref && free_linked_arrays)
3,696✔
440
                    Array::destroy_deep(old_ref, m_composite.get_alloc());
330✔
441
                break;
3,696✔
442
            }
×
443
            default:
✔
444
                break;
×
445
        }
27,450✔
446
    }
27,450✔
447
}
45,075✔
448

449
int64_t ArrayMixed::store(const Mixed& value)
450
{
136,230✔
451
    DataType type = value.get_type();
136,230✔
452
    int64_t val;
136,230✔
453
    switch (type) {
136,230✔
454
        case type_Int: {
35,016✔
455
            int64_t int_val = value.get_int();
35,016✔
456
            if (std::numeric_limits<int32_t>::min() <= int_val && int_val <= std::numeric_limits<int32_t>::max()) {
35,016✔
457
                val = (static_cast<uint64_t>(int_val) << s_data_shift);
30,879✔
458
            }
30,879✔
459
            else {
4,137✔
460
                ensure_int_array();
4,137✔
461
                size_t ndx = m_ints.size();
4,137✔
462
                m_ints.add(int_val);
4,137✔
463
                val = int64_t(ndx << s_data_shift) | (payload_idx_int << s_payload_idx_shift);
4,137✔
464
            }
4,137✔
465
            break;
35,016✔
UNCOV
466
        }
×
467
        case type_Bool:
2,724✔
468
            val = (value.get_bool() << s_data_shift);
2,724✔
469
            break;
2,724✔
470
        case type_Float: {
6,222✔
471
            ensure_int_array();
6,222✔
472
            size_t ndx = m_ints.size();
6,222✔
473
            m_ints.add(type_punning<int64_t>(value.get_float()));
6,222✔
474
            val = int64_t(ndx << s_data_shift) | (payload_idx_int << s_payload_idx_shift);
6,222✔
475
            break;
6,222✔
UNCOV
476
        }
×
477
        case type_Double: {
6,360✔
478
            ensure_int_array();
6,360✔
479
            size_t ndx = m_ints.size();
6,360✔
480
            m_ints.add(type_punning<int64_t>(value.get_double()));
6,360✔
481
            val = int64_t(ndx << s_data_shift) | (payload_idx_int << s_payload_idx_shift);
6,360✔
482
            break;
6,360✔
UNCOV
483
        }
×
484
        case type_String: {
26,838✔
485
            ensure_string_array();
26,838✔
486
            size_t ndx = m_strings.size();
26,838✔
487
            m_strings.add(value.get_string());
26,838✔
488
            val = int64_t(ndx << s_data_shift) | (payload_idx_str << s_payload_idx_shift);
26,838✔
489
            break;
26,838✔
UNCOV
490
        }
×
491
        case type_Binary: {
5,172✔
492
            ensure_string_array();
5,172✔
493
            size_t ndx = m_strings.size();
5,172✔
494
            auto bin = value.get<Binary>();
5,172✔
495
            m_strings.add(StringData(bin.data(), bin.size()));
5,172✔
496
            val = int64_t(ndx << s_data_shift) | (payload_idx_str << s_payload_idx_shift);
5,172✔
497
            break;
5,172✔
UNCOV
498
        }
×
499
        case type_Timestamp: {
3,420✔
500
            ensure_int_pair_array();
3,420✔
501
            size_t ndx = m_int_pairs.size() / 2;
3,420✔
502
            auto t = value.get_timestamp();
3,420✔
503
            m_int_pairs.add(t.get_seconds());
3,420✔
504
            m_int_pairs.add(t.get_nanoseconds());
3,420✔
505
            val = int64_t(ndx << s_data_shift) | (payload_idx_pair << s_payload_idx_shift);
3,420✔
506
            break;
3,420✔
UNCOV
507
        }
×
508
        case type_ObjectId: {
3,576✔
509
            ensure_string_array();
3,576✔
510
            size_t ndx = m_strings.size();
3,576✔
511
            auto id = value.get<ObjectId>();
3,576✔
512
            char buffer[sizeof(ObjectId)];
3,576✔
513
            memcpy(buffer, &id, sizeof(ObjectId));
3,576✔
514
            m_strings.add(StringData(buffer, sizeof(ObjectId)));
3,576✔
515
            val = int64_t(ndx << s_data_shift) | (payload_idx_str << s_payload_idx_shift);
3,576✔
516
            break;
3,576✔
UNCOV
517
        }
×
518
        case type_Decimal: {
5,442✔
519
            ensure_int_pair_array();
5,442✔
520
            size_t ndx = m_int_pairs.size() / 2;
5,442✔
521
            auto t = value.get<Decimal128>();
5,442✔
522
            m_int_pairs.add(t.raw()->w[0]);
5,442✔
523
            m_int_pairs.add(t.raw()->w[1]);
5,442✔
524
            val = int64_t(ndx << s_data_shift) | (payload_idx_pair << s_payload_idx_shift);
5,442✔
525
            break;
5,442✔
UNCOV
526
        }
×
UNCOV
527
        case type_Link: {
✔
UNCOV
528
            ensure_int_array();
×
UNCOV
529
            size_t ndx = m_ints.size();
×
UNCOV
530
            m_ints.add(value.get<ObjKey>().value);
×
UNCOV
531
            val = int64_t(ndx << s_data_shift) | (payload_idx_int << s_payload_idx_shift);
×
UNCOV
532
            break;
×
UNCOV
533
        }
×
534
        case type_TypedLink: {
30,138✔
535
            ensure_int_pair_array();
30,138✔
536
            size_t ndx = m_int_pairs.size() / 2;
30,138✔
537
            auto t = value.get<ObjLink>();
30,138✔
538
            m_int_pairs.add(int64_t(t.get_table_key().value));
30,138✔
539
            m_int_pairs.add(t.get_obj_key().value);
30,138✔
540
            val = int64_t(ndx << s_data_shift) | (payload_idx_pair << s_payload_idx_shift);
30,138✔
541
            break;
30,138✔
UNCOV
542
        }
×
543
        case type_UUID: {
5,250✔
544
            ensure_string_array();
5,250✔
545
            size_t ndx = m_strings.size();
5,250✔
546
            auto id = value.get<UUID>();
5,250✔
547
            const auto uuid_bytes = id.to_bytes();
5,250✔
548
            m_strings.add(StringData(reinterpret_cast<const char*>(uuid_bytes.data()), uuid_bytes.size()));
5,250✔
549
            val = int64_t(ndx << s_data_shift) | (payload_idx_str << s_payload_idx_shift);
5,250✔
550
            break;
5,250✔
UNCOV
551
        }
×
552
        default:
6,078✔
553
            REALM_ASSERT(type == type_List || type == type_Dictionary || type == type_Set);
6,078✔
554
            ensure_ref_array();
6,078✔
555
            size_t ndx = m_refs.size();
6,078✔
556
            m_refs.add(value.get_ref());
6,078✔
557
            val = int64_t(ndx << s_data_shift) | (payload_idx_ref << s_payload_idx_shift);
6,078✔
558
            break;
6,078✔
559
    }
136,233✔
560
    return val + int(type) + 1;
136,233✔
561
}
136,233✔
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