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

realm / realm-core / nicola.cabiddu_1040

26 Sep 2023 05:08PM CUT 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

92.57
/src/realm/array_blobs_small.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 <utility> // pair
20

21
#include <realm/array_blobs_small.hpp>
22
#include <realm/array_blob.hpp>
23
#include <realm/impl/destroy_guard.hpp>
24

25
using namespace realm;
26

27
void ArraySmallBlobs::init_from_mem(MemRef mem) noexcept
28
{
2,801,082✔
29
    Array::init_from_mem(mem);
2,801,082✔
30
    ref_type offsets_ref = get_as_ref(0);
2,801,082✔
31
    ref_type blob_ref = get_as_ref(1);
2,801,082✔
32

1,455,354✔
33
    m_offsets.init_from_ref(offsets_ref);
2,801,082✔
34
    m_blob.init_from_ref(blob_ref);
2,801,082✔
35

1,455,354✔
36
    // In theory you could have an array that survived from ancient days where this array was not present
1,455,354✔
37
    if (Array::size() > 2) {
2,801,082✔
38
        ref_type nulls_ref = get_as_ref(2);
2,798,691✔
39
        m_nulls.init_from_ref(nulls_ref);
2,798,691✔
40
    }
2,798,691✔
41
}
2,801,082✔
42

43
void ArraySmallBlobs::add(BinaryData value, bool add_zero_term)
44
{
77,211✔
45
    REALM_ASSERT_7(value.size(), ==, 0, ||, value.data(), !=, 0);
77,211✔
46

38,778✔
47
    m_blob.add(value.data(), value.size(), add_zero_term);
77,211✔
48
    size_t end = value.size();
77,211✔
49
    if (add_zero_term)
77,211✔
50
        ++end;
61,827✔
51
    if (!m_offsets.is_empty())
77,211✔
52
        end += to_size_t(m_offsets.back());
48,561✔
53
    m_offsets.add(end);
77,211✔
54
    m_nulls.add(value.is_null());
77,211✔
55
}
77,211✔
56

57
void ArraySmallBlobs::set(size_t ndx, BinaryData value, bool add_zero_term)
58
{
321,414✔
59
    REALM_ASSERT_3(ndx, <, m_offsets.size());
321,414✔
60
    REALM_ASSERT_3(value.size(), == 0 ||, value.data());
321,414✔
61

160,263✔
62
    int_fast64_t start = ndx ? m_offsets.get(ndx - 1) : 0;
304,182✔
63
    int_fast64_t current_end = m_offsets.get(ndx);
321,414✔
64
    size_t stored_size = value.size();
321,414✔
65
    if (add_zero_term)
321,414✔
66
        ++stored_size;
246,876✔
67
    int_fast64_t diff = (start + stored_size) - current_end;
321,414✔
68
    m_blob.replace(to_size_t(start), to_size_t(current_end), value.data(), value.size(), add_zero_term);
321,414✔
69
    m_offsets.adjust(ndx, m_offsets.size(), diff);
321,414✔
70
    m_nulls.set(ndx, value.is_null());
321,414✔
71
}
321,414✔
72

73
void ArraySmallBlobs::insert(size_t ndx, BinaryData value, bool add_zero_term)
74
{
1,206,543✔
75
    REALM_ASSERT_3(ndx, <=, m_offsets.size());
1,206,543✔
76
    REALM_ASSERT_3(value.size(), == 0 ||, value.data());
1,206,543✔
77

617,127✔
78
    size_t pos = ndx ? to_size_t(m_offsets.get(ndx - 1)) : 0;
1,128,687✔
79
    m_blob.insert(pos, value.data(), value.size(), add_zero_term);
1,206,543✔
80

617,127✔
81
    size_t stored_size = value.size();
1,206,543✔
82
    if (add_zero_term)
1,206,543✔
83
        ++stored_size;
281,778✔
84
    m_offsets.insert(ndx, pos + stored_size);
1,206,543✔
85
    m_offsets.adjust(ndx + 1, m_offsets.size(), stored_size);
1,206,543✔
86
    m_nulls.insert(ndx, value.is_null());
1,206,543✔
87
}
1,206,543✔
88

89
void ArraySmallBlobs::erase(size_t ndx)
90
{
732,636✔
91
    REALM_ASSERT_3(ndx, <, m_offsets.size());
732,636✔
92

382,617✔
93
    size_t start = ndx ? to_size_t(m_offsets.get(ndx - 1)) : 0;
631,488✔
94
    size_t end = to_size_t(m_offsets.get(ndx));
732,636✔
95

382,617✔
96
    m_blob.erase(start, end);
732,636✔
97
    m_offsets.erase(ndx);
732,636✔
98
    m_offsets.adjust(ndx, m_offsets.size(), int64_t(start) - end);
732,636✔
99
    m_nulls.erase(ndx);
732,636✔
100
}
732,636✔
101

102
BinaryData ArraySmallBlobs::get(const char* header, size_t ndx, Allocator& alloc) noexcept
103
{
328,350✔
104
    int64_t ref_val = Array::get(header, 2);
328,350✔
105
    const char* nulls_header = alloc.translate(to_ref(ref_val));
328,350✔
106
    int64_t n = Array::get(nulls_header, ndx);
328,350✔
107
    // 0 or 1 is all that is ever written to m_nulls; any other content would be a bug
163,590✔
108
    REALM_ASSERT_3(n == 1, ||, n == 0);
328,350✔
109
    bool null = (n != 0);
328,350✔
110
    if (null)
328,350✔
111
        return BinaryData{};
20,676✔
112

154,065✔
113
    std::pair<int64_t, int64_t> p = Array::get_two(header, 0);
307,674✔
114
    const char* offsets_header = alloc.translate(to_ref(p.first));
307,674✔
115
    const char* blob_header = alloc.translate(to_ref(p.second));
307,674✔
116
    size_t begin, end;
307,674✔
117
    if (ndx) {
307,674✔
118
        p = get_two(offsets_header, ndx - 1);
289,995✔
119
        begin = to_size_t(p.first);
289,995✔
120
        end = to_size_t(p.second);
289,995✔
121
    }
289,995✔
122
    else {
17,679✔
123
        begin = 0;
17,679✔
124
        end = to_size_t(Array::get(offsets_header, ndx));
17,679✔
125
    }
17,679✔
126
    BinaryData bd = BinaryData(ArrayBlob::get(blob_header, begin), end - begin);
307,674✔
127
    return bd;
307,674✔
128
}
307,674✔
129

130
MemRef ArraySmallBlobs::create_array(size_t size, Allocator& alloc, BinaryData values)
131
{
164,349✔
132
    // Only null and zero-length non-null allowed as initialization value
80,637✔
133
    REALM_ASSERT(values.size() == 0);
164,349✔
134
    Array top(alloc);
164,349✔
135
    _impl::DeepArrayDestroyGuard dg(&top);
164,349✔
136
    top.create(type_HasRefs); // Throws
164,349✔
137

80,637✔
138
    _impl::DeepArrayRefDestroyGuard dg_2(alloc);
164,349✔
139
    {
164,349✔
140
        bool context_flag = false;
164,349✔
141
        int64_t value = 0;
164,349✔
142
        MemRef mem = Array::create_array(type_Normal, context_flag, size, value, alloc); // Throws
164,349✔
143
        dg_2.reset(mem.get_ref());
164,349✔
144
        int64_t v = from_ref(mem.get_ref());
164,349✔
145
        top.add(v); // Throws
164,349✔
146
        dg_2.release();
164,349✔
147
    }
164,349✔
148
    {
164,349✔
149
        size_t blobs_size = 0;
164,349✔
150
        MemRef mem = ArrayBlob::create_array(blobs_size, alloc); // Throws
164,349✔
151
        dg_2.reset(mem.get_ref());
164,349✔
152
        int64_t v = from_ref(mem.get_ref());
164,349✔
153
        top.add(v); // Throws
164,349✔
154
        dg_2.release();
164,349✔
155
    }
164,349✔
156
    {
164,349✔
157
        // Always create a m_nulls array, regardless if its column is marked as nullable or not.
80,637✔
158
        bool context_flag = false;
164,349✔
159
        int64_t value = values.is_null() ? 1 : 0;
164,349✔
160
        MemRef mem = Array::create_array(type_Normal, context_flag, size, value, alloc); // Throws
164,349✔
161
        dg_2.reset(mem.get_ref());
164,349✔
162
        int64_t v = from_ref(mem.get_ref());
164,349✔
163
        top.add(v); // Throws
164,349✔
164
        dg_2.release();
164,349✔
165
    }
164,349✔
166

80,637✔
167
    dg.release();
164,349✔
168
    return top.get_mem();
164,349✔
169
}
164,349✔
170

171
size_t ArraySmallBlobs::find_first(BinaryData value, bool is_string, size_t begin, size_t end) const noexcept
172
{
104,976✔
173
    size_t sz = size();
104,976✔
174
    if (end == npos)
104,976✔
175
        end = sz;
×
176
    REALM_ASSERT_11(begin, <=, sz, &&, end, <=, sz, &&, begin, <=, end);
104,976✔
177

63,096✔
178
    if (value.is_null()) {
104,976✔
179
        for (size_t i = begin; i != end; ++i) {
1,884✔
180
            if (m_nulls.get(i))
1,878✔
181
                return i;
1,740✔
182
        }
1,878✔
183
    }
1,746✔
184
    else {
103,230✔
185
        // When strings are stored as blobs, they are always zero-terminated
62,160✔
186
        // but the value we get as input might not be.
62,160✔
187
        size_t value_size = value.size();
103,230✔
188
        size_t full_size = is_string ? value_size + 1 : value_size;
103,098✔
189

62,160✔
190
        size_t start_ofs = begin ? to_size_t(m_offsets.get(begin - 1)) : 0;
96,324✔
191
        for (size_t i = begin; i != end; ++i) {
378,951✔
192
            size_t end_ofs = to_size_t(m_offsets.get(i));
360,417✔
193
            size_t this_size = end_ofs - start_ofs;
360,417✔
194
            if (!m_nulls.get(i) && this_size == full_size) {
360,417✔
195
                const char* blob_value = m_blob.get(start_ofs);
126,279✔
196
                if (std::equal(blob_value, blob_value + value_size, value.data()))
126,279✔
197
                    return i;
84,696✔
198
            }
275,721✔
199
            start_ofs = end_ofs;
275,721✔
200
        }
275,721✔
201
    }
103,230✔
202

63,096✔
203
    return not_found;
70,149✔
204
}
104,976✔
205

206
StringData ArraySmallBlobs::get_string_legacy(size_t ndx) const
UNCOV
207
{
×
UNCOV
208
    REALM_ASSERT_3(ndx, <, m_offsets.size());
×
209

210
    // In file format versions prior to 10 a true value means that the element is not null
UNCOV
211
    if (Array::size() == 3 && !m_nulls.get(ndx)) {
×
UNCOV
212
        return {};
×
UNCOV
213
    }
×
UNCOV
214
    else {
×
UNCOV
215
        size_t begin = ndx ? to_size_t(m_offsets.get(ndx - 1)) : 0;
×
UNCOV
216
        size_t end = to_size_t(m_offsets.get(ndx));
×
UNCOV
217
        StringData str = StringData(m_blob.get(begin), (end - begin) - 1);
×
UNCOV
218
        return str;
×
UNCOV
219
    }
×
UNCOV
220
}
×
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