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

realm / realm-core / github_pull_request_281750

30 Oct 2023 03:37PM UTC coverage: 90.528% (-1.0%) from 91.571%
github_pull_request_281750

Pull #6073

Evergreen

jedelbo
Log free space and history sizes when opening file
Pull Request #6073: Merge next-major

95488 of 175952 branches covered (0.0%)

8973 of 12277 new or added lines in 149 files covered. (73.09%)

622 existing lines in 51 files now uncovered.

233503 of 257934 relevant lines covered (90.53%)

6533720.56 hits per line

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

89.7
/src/realm/obj.hpp
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
#ifndef REALM_OBJ_HPP
20
#define REALM_OBJ_HPP
21

22
#include <realm/node.hpp>
23
#include <realm/collection_parent.hpp>
24
#include <realm/mixed.hpp>
25
#include "realm/column_type_traits.hpp"
26

27
#include <map>
28

29
#define REALM_CLUSTER_IF
30

31
namespace realm {
32

33
class ClusterTree;
34
class TableView;
35
class CascadeState;
36
class ObjList;
37
struct GlobalKey;
38

39
template <class>
40
class Lst;
41
template <class>
42
class Set;
43
template <class T>
44
using LstPtr = std::unique_ptr<Lst<T>>;
45
template <class T>
46
using SetPtr = std::unique_ptr<Set<T>>;
47

48
using LinkCollectionPtr = std::unique_ptr<ObjList>;
49

50
class LnkLst;
51
using LnkLstPtr = std::unique_ptr<LnkLst>;
52
class LnkSet;
53
using LnkSetPtr = std::unique_ptr<LnkSet>;
54

55
namespace _impl {
56
class DeepChangeChecker;
57
}
58

59
// 'Object' would have been a better name, but it clashes with a class in ObjectStore
60
class Obj : public CollectionParent {
61
public:
62
    constexpr Obj()
63
        : m_table(nullptr)
64
        , m_row_ndx(size_t(-1))
65
        , m_storage_version(-1)
66
        , m_valid(false)
67
    {
14,630,904✔
68
    }
14,630,904✔
69
    Obj(TableRef table, MemRef mem, ObjKey key, size_t row_ndx);
70

71
    // Overriding members of CollectionParent:
72
    UpdateStatus update_if_needed_with_status() const final;
73
    // Get the path in a minimal format without including object accessors.
74
    // If you need to obtain additional information for each object in the path,
75
    // you should use get_fat_path() or traverse_path() instead (see below).
76
    FullPath get_path() const final;
77
    std::string get_id() const;
78
    Path get_short_path() const noexcept final;
79
    StablePath get_stable_path() const noexcept final;
80
    void add_index(Path& path, const Index& ndx) const final;
81
    size_t find_index(const Index&) const final
UNCOV
82
    {
×
NEW
83
        return realm::npos;
×
UNCOV
84
    }
×
85

86
    bool update_if_needed() const final;
87
    TableRef get_table() const noexcept final
88
    {
71,913,663✔
89
        return m_table.cast_away_const();
71,913,663✔
90
    }
71,913,663✔
91
    const Obj& get_object() const noexcept final
92
    {
6,862,851✔
93
        return *this;
6,862,851✔
94
    }
6,862,851✔
95
    ref_type get_collection_ref(Index, CollectionType) const final;
96
    bool check_collection_ref(Index, CollectionType) const noexcept final;
97
    void set_collection_ref(Index, ref_type, CollectionType) final;
98
    StableIndex build_index(ColKey) const;
99
    bool check_index(StableIndex) const;
100

101
    // Operator overloads
102
    bool operator==(const Obj& other) const;
103

104
    // Check if this object is default constructed
105
    explicit operator bool() const noexcept
106
    {
11,834,223✔
107
        return m_table != nullptr;
11,834,223✔
108
    }
11,834,223✔
109

110
    // Simple getters
111
    Allocator& get_alloc() const;
112
    Replication* get_replication() const;
113
    ObjKey get_key() const noexcept
114
    {
45,290,082✔
115
        return m_key;
45,290,082✔
116
    }
45,290,082✔
117
    GlobalKey get_object_id() const;
118
    ObjLink get_link() const;
119

120
    /// Check if the object is still alive
121
    bool is_valid() const noexcept;
122

123
    /// Delete object from table. Object is invalid afterwards.
124
    void remove();
125
    /// Invalidate
126
    ///  - this turns the object into a tombstone if links to the object exist.
127
    ///  - deletes the object is no links to the object exist.
128
    ///  - To be used by the Sync client.
129
    void invalidate();
130

131
    template <typename U>
132
    U get(ColKey col_key) const;
133

134
    Mixed get_any(ColKey col_key) const;
135
    Mixed get_any(StringData col_name) const
136
    {
12,762✔
137
        return get_any(get_column_key(col_name));
12,762✔
138
    }
12,762✔
139
    Mixed get_primary_key() const;
140

141
    template <typename U>
142
    U get(StringData col_name) const
143
    {
975,167✔
144
        return get<U>(get_column_key(col_name));
975,167✔
145
    }
975,167✔
146
    bool is_unresolved(ColKey col_key) const;
147

148
    size_t get_link_count(ColKey col_key) const;
149
    TableRef get_target_table(ColKey col_key) const;
150

151
    bool is_null(ColKey col_key) const;
152
    bool is_null(StringData col_name) const
153
    {
3,692✔
154
        return is_null(get_column_key(col_name));
3,692✔
155
    }
3,692✔
156
    bool has_backlinks(bool only_strong_links) const;
157
    size_t get_backlink_count() const;
158
    size_t get_backlink_count(const Table& origin, ColKey origin_col_key) const;
159
    ObjKey get_backlink(const Table& origin, ColKey origin_col_key, size_t backlink_ndx) const;
160
    TableView get_backlink_view(TableRef src_table, ColKey src_col_key) const;
161
    void verify_backlink(const Table& origin, ColKey origin_col_key, ObjKey origin_key) const;
162

163
    // To be used by the query system when a single object should
164
    // be tested. Will allow a function to be called in the context
165
    // of the owning cluster.
166
    template <class T>
167
    bool evaluate(T func) const;
168

169
    void to_json(std::ostream& out, size_t link_depth, const std::map<std::string, std::string>& renames,
170
                 std::vector<ObjLink>& followed, JSONOutputMode output_mode) const;
171
    void to_json(std::ostream& out, size_t link_depth, const std::map<std::string, std::string>& renames,
172
                 JSONOutputMode output_mode = output_mode_json) const
173
    {
1,410✔
174
        std::vector<ObjLink> followed;
1,410✔
175
        to_json(out, link_depth, renames, followed, output_mode);
1,410✔
176
    }
1,410✔
177

178
    std::string to_string() const;
179

180
    // Get the fat path to this object expressed as a vector of fat path elements.
181
    // each Fat path elements include a Obj allowing for low cost access to the
182
    // objects data.
183
    // For a top-level object, the returned vector will be empty.
184
    // For an embedded object, the vector has the top object as first element,
185
    // and the embedded object itself is not included in the path.
186
    struct FatPathElement;
187
    using FatPath = std::vector<FatPathElement>;
188
    FatPath get_fat_path() const;
189

190
    // For an embedded object, traverse the path leading to this object.
191
    // The PathSizer is called first to set the size of the path
192
    // Then there is one call for each object on that path, starting with the top level object
193
    // The embedded object itself is not considered part of the path.
194
    // Note: You should never provide the path_index for calls to traverse_path.
195
    using Visitor = util::FunctionRef<void(const Obj&, ColKey, Mixed)>;
196
    using PathSizer = util::FunctionRef<void(size_t)>;
197
    void traverse_path(Visitor v, PathSizer ps, size_t path_index = 0) const;
198

199
    template <typename U>
200
    Obj& set(ColKey col_key, U value, bool is_default = false);
201
    // Create a new object and link it. If an embedded object
202
    // is already set, it will be removed. If a non-embedded
203
    // object is already set, we throw LogicError (to prevent
204
    // dangling objects, since they do not delete automatically
205
    // if they are not embedded...)
206
    Obj create_and_set_linked_object(ColKey col_key, bool is_default = false);
207
    // Clear all fields of a linked object returning it to its
208
    // default state. If the object does not exist, create a
209
    // new object and link it. (To Be Implemented)
210
    Obj clear_linked_object(ColKey col_key);
211
    Obj& set_any(ColKey col_key, Mixed value, bool is_default = false);
212
    Obj& set_any(StringData col_name, Mixed value, bool is_default = false)
213
    {
2✔
214
        return set_any(get_column_key(col_name), value, is_default);
2✔
215
    }
2✔
216

217
    template <typename U>
218
    Obj& set(StringData col_name, U value, bool is_default = false)
219
    {
2,719,705✔
220
        return set(get_column_key(col_name), value, is_default);
2,719,705✔
221
    }
2,719,705✔
222

223
    Obj& set_null(ColKey col_key, bool is_default = false);
224
    Obj& set_null(StringData col_name, bool is_default = false)
225
    {
30✔
226
        return set_null(get_column_key(col_name), is_default);
30✔
227
    }
30✔
228
    Obj& set_json(ColKey col_key, StringData json);
229

230
    Obj& add_int(ColKey col_key, int64_t value);
231
    Obj& add_int(StringData col_name, int64_t value)
232
    {
1,316✔
233
        return add_int(get_column_key(col_name), value);
1,316✔
234
    }
1,316✔
235

236
    template <typename U>
237
    Obj& set_list_values(ColKey col_key, const std::vector<U>& values);
238

239
    template <typename U>
240
    std::vector<U> get_list_values(ColKey col_key) const;
241

242
    template <class Head, class... Tail>
243
    Obj& set_all(Head v, Tail... tail);
244

245
    // The main algorithm for handling schema migrations if we try to convert
246
    // from TopLevel* to Embedded, in this case all the orphan objects are deleted
247
    // and all the objects with multiple backlinks are cloned in order to avoid to
248
    // get schema violations during the migration.
249
    // By default this alogirithm is disabled. RealmConfig contains a boolean flag
250
    // to enable it.
251
    void handle_multiple_backlinks_during_schema_migration();
252

253
    Obj get_linked_object(ColKey link_col_key) const
254
    {
24,831✔
255
        return _get_linked_object(link_col_key, get_any(link_col_key));
24,831✔
256
    }
24,831✔
257
    Obj get_linked_object(StringData link_col_name) const
258
    {
645✔
259
        return get_linked_object(get_column_key(link_col_name));
645✔
260
    }
645✔
261
    Obj get_parent_object() const;
262

263
    template <typename U>
264
    Lst<U> get_list(ColKey col_key) const;
265
    template <typename U>
266
    LstPtr<U> get_list_ptr(ColKey col_key) const;
267
    template <typename U>
268
    std::shared_ptr<Lst<U>> get_list_ptr(const Path& path) const
269
    {
60✔
270
        return std::dynamic_pointer_cast<Lst<U>>(get_collection_ptr(path));
60✔
271
    }
60✔
272

273
    template <typename U>
274
    Lst<U> get_list(StringData col_name) const
275
    {
298✔
276
        return get_list<U>(get_column_key(col_name));
298✔
277
    }
298✔
278

279
    LnkLst get_linklist(ColKey col_key) const;
280
    LnkLstPtr get_linklist_ptr(ColKey col_key) const;
281
    LnkLst get_linklist(StringData col_name) const;
282

283
    /// Get a type-erased list instance for the given list column.
284
    ///
285
    /// Note: For lists of links, this always returns a `LnkLst`, rather than a
286
    /// `Lst<ObjKey>`. Use `get_list_ptr<ObjKey>(col_key)` to get a list of
287
    /// links with uncondensed indices.
288
    LstBasePtr get_listbase_ptr(ColKey col_key) const;
289

290
    template <typename U>
291
    Set<U> get_set(StringData col_name) const
292
    {
4,786✔
293
        return get_set<U>(get_column_key(col_name));
4,786✔
294
    }
4,786✔
295
    template <typename U>
296
    Set<U> get_set(ColKey col_key) const;
297
    template <typename U>
298
    SetPtr<U> get_set_ptr(ColKey col_key) const;
299
    template <typename U>
300
    std::shared_ptr<Set<U>> get_set_ptr(const Path& path) const
301
    {
302
        return std::dynamic_pointer_cast<Set<U>>(get_collection_ptr(path));
303
    }
304

305
    LnkSet get_linkset(ColKey col_key) const;
306
    LnkSet get_linkset(StringData col_name) const;
307
    LnkSetPtr get_linkset_ptr(ColKey col_key) const;
308
    SetBasePtr get_setbase_ptr(ColKey col_key) const;
309
    Dictionary get_dictionary(ColKey col_key) const;
310
    Dictionary get_dictionary(StringData col_name) const;
311

312
    Obj& set_collection(ColKey col_key, CollectionType type);
313
    DictionaryPtr get_dictionary_ptr(ColKey col_key) const;
314
    DictionaryPtr get_dictionary_ptr(const Path& path) const;
315

316
    CollectionBasePtr get_collection_ptr(ColKey col_key) const;
317
    CollectionBasePtr get_collection_ptr(StringData col_name) const;
318
    CollectionPtr get_collection_ptr(const Path& path) const;
319
    CollectionPtr get_collection_by_stable_path(const StablePath& path) const;
320
    LinkCollectionPtr get_linkcollection_ptr(ColKey col_key) const;
321

322
    void assign_pk_and_backlinks(const Obj& other);
323

324
    class Internal {
325
        friend class _impl::DeepChangeChecker;
326

327
        static ref_type get_ref(const Obj& obj, ColKey col_key);
328
    };
329

330
private:
331
    friend class ArrayBacklink;
332
    friend class CascadeState;
333
    friend class Cluster;
334
    friend class ColumnListBase;
335
    friend class CollectionBase;
336
    friend class TableView;
337
    template <class>
338
    friend class CollectionBaseImpl;
339
    template <class>
340
    friend class Lst;
341
    friend class LnkLst;
342
    friend class LinkCount;
343
    friend class Dictionary;
344
    friend class LinkMap;
345
    template <class>
346
    friend class Set;
347
    friend class Table;
348
    friend class Transaction;
349
    friend class CollectionParent;
350

351
    mutable TableRef m_table;
352
    ObjKey m_key;
353
    mutable MemRef m_mem;
354
    mutable size_t m_row_ndx;
355
    mutable uint64_t m_storage_version;
356
    mutable bool m_valid;
357

358
    Allocator& _get_alloc() const noexcept;
359

360

361
    /// Update the accessor. Returns true when the accessor was updated to
362
    /// reflect new changes to the underlying state.
363
    bool update() const;
364
    bool _update_if_needed() const; // no check, use only when already checked
365

366
    template <class T>
367
    bool do_is_null(ColKey::Idx col_ndx) const;
368

369
    const ClusterTree* get_tree_top() const;
370
    ColKey get_column_key(StringData col_name) const;
371
    ColKey get_primary_key_column() const;
372
    TableKey get_table_key() const;
373
    TableRef get_target_table(ObjLink link) const;
374
    const Spec& get_spec() const;
375

376
    template <typename U>
377
    U _get(ColKey::Idx col_ndx) const;
378

379
    ObjKey get_backlink(ColKey backlink_col, size_t backlink_ndx) const;
380
    // Return all backlinks from a specific backlink column
381
    std::vector<ObjKey> get_all_backlinks(ColKey backlink_col) const;
382
    // Return number of backlinks from a specific backlink column
383
    size_t get_backlink_cnt(ColKey backlink_col) const;
384
    ObjKey get_unfiltered_link(ColKey col_key) const;
385

386
    template <class Val>
387
    Obj& _set(size_t col_ndx, Val v);
388
    template <class Head, class... Tail>
389
    Obj& _set(size_t col_ndx, Head v, Tail... tail);
390
    ColKey spec_ndx2colkey(size_t col_ndx);
391
    size_t colkey2spec_ndx(ColKey);
392
    bool ensure_writeable();
393
    void sync(Node& arr);
394
    int_fast64_t bump_content_version();
395
    void bump_both_versions();
396
    template <class T>
397
    void do_set_null(ColKey col_key);
398

399
    // Dictionary support
400
    size_t get_row_ndx() const
UNCOV
401
    {
×
UNCOV
402
        return m_row_ndx;
×
UNCOV
403
    }
×
404

405
    Obj _get_linked_object(ColKey link_col_key, Mixed link) const;
406
    Obj _get_linked_object(StringData link_col_name, Mixed link) const
407
    {
228✔
408
        return _get_linked_object(get_column_key(link_col_name), link);
228✔
409
    }
228✔
410

411
    void set_int(ColKey::Idx col_ndx, int64_t value);
412
    void set_ref(ColKey::Idx col_ndx, ref_type value, CollectionType type);
413
    void add_backlink(ColKey backlink_col, ObjKey origin_key);
414
    bool remove_one_backlink(ColKey backlink_col, ObjKey origin_key);
415
    void nullify_link(ColKey origin_col, ObjLink target_key) &&;
416
    template <class T>
417
    inline void set_spec(T&, ColKey);
418
    template <class ValueType>
419
    inline void nullify_single_link(ColKey col, ValueType target);
420

421
    void fix_linking_object_during_schema_migration(Obj linking_obj, Obj obj, ColKey opposite_col_key) const;
422

423
    bool compare_values(Mixed, Mixed, ColKey, Obj, StringData) const;
424
    bool compare_list_in_mixed(Lst<Mixed>&, Lst<Mixed>&, ColKey, Obj, StringData) const;
425
    bool compare_dict_in_mixed(Dictionary&, Dictionary&, ColKey, Obj, StringData) const;
426
};
427

428
std::ostream& operator<<(std::ostream&, const Obj& obj);
429

430
template <>
431
int64_t Obj::get(ColKey) const;
432
template <>
433
bool Obj::get(ColKey) const;
434

435
template <>
436
int64_t Obj::_get(ColKey::Idx col_ndx) const;
437
template <>
438
StringData Obj::_get(ColKey::Idx col_ndx) const;
439
template <>
440
BinaryData Obj::_get(ColKey::Idx col_ndx) const;
441
template <>
442
ObjKey Obj::_get(ColKey::Idx col_ndx) const;
443

444
struct Obj::FatPathElement {
445
    Obj obj;        // Object which embeds...
446
    ColKey col_key; // Column holding link or link list which embeds...
447
    Mixed index;    // index into link list or dictionary (or null)
448
};
449

450
template <>
451
Obj& Obj::set(ColKey, int64_t value, bool is_default);
452

453
template <>
454
Obj& Obj::set(ColKey, ObjKey value, bool is_default);
455

456
template <>
457
Obj& Obj::set(ColKey, ObjLink value, bool is_default);
458

459

460
template <>
461
inline Obj& Obj::set(ColKey col_key, int value, bool is_default)
462
{
15,399,018✔
463
    return set(col_key, int_fast64_t(value), is_default);
15,399,018✔
464
}
15,399,018✔
465

466
template <>
467
inline Obj& Obj::set(ColKey col_key, uint_fast64_t value, bool is_default)
468
{
1,284✔
469
    int_fast64_t value_2 = 0;
1,284✔
470
    if (REALM_UNLIKELY(util::int_cast_with_overflow_detect(value, value_2))) {
1,284✔
471
        REALM_TERMINATE("Unsigned integer too big.");
×
472
    }
×
473
    return set(col_key, value_2, is_default);
1,284✔
474
}
1,284✔
475

476
template <>
477
inline Obj& Obj::set(ColKey col_key, const char* str, bool is_default)
478
{
1,377,660✔
479
    return set(col_key, StringData(str), is_default);
1,377,660✔
480
}
1,377,660✔
481

482
template <>
483
inline Obj& Obj::set(ColKey col_key, char* str, bool is_default)
484
{
99✔
485
    return set(col_key, StringData(str), is_default);
99✔
486
}
99✔
487

488
template <>
489
inline Obj& Obj::set(ColKey col_key, std::string str, bool is_default)
490
{
419,400✔
491
    return set(col_key, StringData(str), is_default);
419,400✔
492
}
419,400✔
493

494
template <>
495
inline Obj& Obj::set(ColKey col_key, realm::null, bool is_default)
496
{
52✔
497
    return set_null(col_key, is_default);
52✔
498
}
52✔
499

500
template <>
501
inline Obj& Obj::set(ColKey col_key, util::Optional<bool> value, bool is_default)
502
{
20,728✔
503
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
19,600✔
504
}
20,728✔
505

506
template <>
507
inline Obj& Obj::set(ColKey col_key, util::Optional<int64_t> value, bool is_default)
508
{
36,672✔
509
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
35,139✔
510
}
36,672✔
511

512
template <>
513
inline Obj& Obj::set(ColKey col_key, util::Optional<float> value, bool is_default)
514
{
20,880✔
515
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
19,788✔
516
}
20,880✔
517

518
template <>
519
inline Obj& Obj::set(ColKey col_key, util::Optional<double> value, bool is_default)
520
{
20,880✔
521
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
19,820✔
522
}
20,880✔
523

524
template <>
525
inline Obj& Obj::set(ColKey col_key, util::Optional<ObjectId> value, bool is_default)
526
{
20,736✔
527
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
19,640✔
528
}
20,736✔
529

530
template <>
531
inline Obj& Obj::set(ColKey col_key, util::Optional<UUID> value, bool is_default)
532
{
8,456✔
533
    return value ? set(col_key, *value, is_default) : set_null(col_key, is_default);
6,352✔
534
}
8,456✔
535

536
template <typename U>
537
Obj& Obj::set_list_values(ColKey col_key, const std::vector<U>& values)
538
{
11,164✔
539
    size_t sz = values.size();
11,164✔
540
    auto list = get_list<U>(col_key);
11,164✔
541
    size_t list_sz = list.size();
11,164✔
542
    if (sz < list_sz) {
11,164✔
543
        list.resize(sz);
752✔
544
        list_sz = sz;
752✔
545
    }
752✔
546
    size_t i = 0;
11,164✔
547
    while (i < list_sz) {
14,356✔
548
        list.set(i, values[i]);
3,192✔
549
        i++;
3,192✔
550
    }
3,192✔
551
    while (i < sz) {
33,232✔
552
        list.add(values[i]);
22,068✔
553
        i++;
22,068✔
554
    }
22,068✔
555

5,582✔
556
    return *this;
11,164✔
557
}
11,164✔
558

559
template <typename U>
560
std::vector<U> Obj::get_list_values(ColKey col_key) const
561
{
7,518✔
562
    std::vector<U> values;
7,518✔
563
    auto list = get_list<U>(col_key);
7,518✔
564
    for (auto v : list)
7,518✔
565
        values.push_back(v);
10,700✔
566

3,759✔
567
    return values;
7,518✔
568
}
7,518✔
569

570
template <class Val>
571
inline Obj& Obj::_set(size_t col_ndx, Val v)
572
{
3,965,207✔
573
    return set(spec_ndx2colkey(col_ndx), v);
3,965,207✔
574
}
3,965,207✔
575

576
template <class Head, class... Tail>
577
inline Obj& Obj::_set(size_t col_ndx, Head v, Tail... tail)
578
{
1,528,566✔
579
    set(spec_ndx2colkey(col_ndx), v);
1,528,566✔
580
    return _set(col_ndx + 1, tail...);
1,528,566✔
581
}
1,528,566✔
582

583
template <class Head, class... Tail>
584
inline Obj& Obj::set_all(Head v, Tail... tail)
585
{
2,875,367✔
586
    size_t start_index = 0;
2,875,367✔
587

1,439,048✔
588
    // Avoid trying to set the PK column.
1,439,048✔
589
    if (get_primary_key_column()) {
2,875,367✔
590
        REALM_ASSERT(colkey2spec_ndx(get_primary_key_column()) == 0);
767!
591
        start_index = 1;
767✔
592
    }
767✔
593

1,439,048✔
594
    return _set(start_index, v, tail...);
2,875,367✔
595
}
2,875,367✔
596

597
inline bool Obj::update_if_needed() const
598
{
43,943,004✔
599
    auto current_version = get_alloc().get_storage_version();
43,943,004✔
600
    if (current_version != m_storage_version) {
43,943,004✔
601
        return update();
647,913✔
602
    }
647,913✔
603
    return false;
43,295,091✔
604
}
43,295,091✔
605

606
inline int_fast64_t Obj::bump_content_version()
UNCOV
607
{
×
UNCOV
608
    Allocator& alloc = get_alloc();
×
UNCOV
609
    return alloc.bump_content_version();
×
UNCOV
610
}
×
611

612
inline void Obj::bump_both_versions()
UNCOV
613
{
×
UNCOV
614
    Allocator& alloc = get_alloc();
×
UNCOV
615
    alloc.bump_content_version();
×
UNCOV
616
    alloc.bump_storage_version();
×
UNCOV
617
}
×
618

619
} // namespace realm
620

621
#endif // REALM_OBJ_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

© 2026 Coveralls, Inc