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

realm / realm-core / 2543

05 Aug 2024 04:04PM UTC coverage: 91.108%. Remained the same
2543

push

Evergreen

web-flow
Only track pending client resets done by the same core version (#7944)

If the previous attempt at performing a client reset was done with a different
core version then we should retry the client reset as the new version may have
fixed a bug that made the previous attempt fail (or may be a downgrade to a
version before when the bug was introduced). This also simplifies the tracking
as it means that we don't need to be able to read trackers created by different
versions.

This also means that we can freely change the schema of the table, which this
takes advantage of to drop the unused primary key and make the error required,
as we never actually stored null and the code reading it would have crashed if
it encountered a null error.

102732 of 181534 branches covered (56.59%)

138 of 153 new or added lines in 10 files covered. (90.2%)

60 existing lines in 12 files now uncovered.

216763 of 237919 relevant lines covered (91.11%)

5749223.09 hits per line

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

98.58
/src/realm/array_blobs_big.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 <algorithm>
20

21
#include <realm/array_blobs_big.hpp>
22
#include <realm/column_integer.hpp>
23

24

25
using namespace realm;
26

27
BinaryData ArrayBigBlobs::get_at(size_t ndx, size_t& pos) const noexcept
28
{
484,644✔
29
    ref_type ref = get_as_ref(ndx);
484,644✔
30
    if (ref == 0)
484,644✔
31
        return {}; // realm::null();
139,866✔
32

33
    ArrayBlob blob(m_alloc);
344,778✔
34
    blob.init_from_ref(ref);
344,778✔
35

36
    return blob.get_at(pos);
344,778✔
37
}
484,644✔
38

39

40
void ArrayBigBlobs::add(BinaryData value, bool add_zero_term)
41
{
81,609✔
42
    REALM_ASSERT_7(value.size(), ==, 0, ||, value.data(), !=, 0);
81,609✔
43

44
    if (value.is_null()) {
81,609✔
45
        Array::add(0); // Throws
34,740✔
46
    }
34,740✔
47
    else {
46,869✔
48
        ArrayBlob new_blob(m_alloc);
46,869✔
49
        new_blob.create();                                                      // Throws
46,869✔
50
        ref_type ref = new_blob.add(value.data(), value.size(), add_zero_term); // Throws
46,869✔
51
        Array::add(from_ref(ref));                                              // Throws
46,869✔
52
    }
46,869✔
53
}
81,609✔
54

55

56
void ArrayBigBlobs::set(size_t ndx, BinaryData value, bool add_zero_term)
57
{
5,494,911✔
58
    REALM_ASSERT_3(ndx, <, size());
5,494,911✔
59
    REALM_ASSERT_7(value.size(), ==, 0, ||, value.data(), !=, 0);
5,494,911✔
60

61
    ref_type ref = get_as_ref(ndx);
5,494,911✔
62

63
    if (ref == 0 && value.is_null()) {
5,494,911✔
64
        return;
2,007✔
65
    }
2,007✔
66
    else if (ref == 0 && value.data() != nullptr) {
5,492,904✔
67
        ArrayBlob new_blob(m_alloc);
1,391,817✔
68
        new_blob.create();                                             // Throws
1,391,817✔
69
        ref = new_blob.add(value.data(), value.size(), add_zero_term); // Throws
1,391,817✔
70
        Array::set_as_ref(ndx, ref);
1,391,817✔
71
        return;
1,391,817✔
72
    }
1,391,817✔
73
    else if (ref != 0 && value.data() != nullptr) {
4,101,861✔
74
        char* header = m_alloc.translate(ref);
4,093,560✔
75
        if (Array::get_context_flag_from_header(header)) {
4,093,560✔
76
            Array arr(m_alloc);
6✔
77
            arr.init_from_mem(MemRef(header, ref, m_alloc));
6✔
78
            arr.set_parent(this, ndx);
6✔
79
            ref_type new_ref =
6✔
80
                arr.blob_replace(0, arr.blob_size(), value.data(), value.size(), add_zero_term); // Throws
6✔
81
            if (new_ref != ref) {
6✔
UNCOV
82
                Array::set_as_ref(ndx, new_ref);
×
UNCOV
83
            }
×
84
        }
6✔
85
        else {
4,093,554✔
86
            ArrayBlob blob(m_alloc);
4,093,554✔
87
            blob.init_from_mem(MemRef(header, ref, m_alloc));
4,093,554✔
88
            blob.set_parent(this, ndx);
4,093,554✔
89
            ref_type new_ref = blob.replace(0, blob.blob_size(), value.data(), value.size(), add_zero_term); // Throws
4,093,554✔
90
            if (new_ref != ref) {
4,093,554✔
91
                Array::set_as_ref(ndx, new_ref);
3,725,181✔
92
            }
3,725,181✔
93
        }
4,093,554✔
94
        return;
4,093,560✔
95
    }
4,093,560✔
96
    else if (ref != 0 && value.is_null()) {
8,205✔
97
        Array::destroy_deep(ref, get_alloc());
7,956✔
98
        Array::set(ndx, 0);
7,956✔
99
        return;
7,956✔
100
    }
7,956✔
101
    REALM_ASSERT(false);
2,147,483,896✔
102
}
2,147,483,896✔
103

104

105
void ArrayBigBlobs::insert(size_t ndx, BinaryData value, bool add_zero_term)
106
{
2,436,903✔
107
    REALM_ASSERT_3(ndx, <=, size());
2,436,903✔
108
    REALM_ASSERT_7(value.size(), ==, 0, ||, value.data(), !=, 0);
2,436,903✔
109

110
    if (value.is_null()) {
2,436,903✔
111
        Array::insert(ndx, 0); // Throws
1,435,182✔
112
    }
1,435,182✔
113
    else {
1,001,721✔
114
        ArrayBlob new_blob(m_alloc);
1,001,721✔
115
        new_blob.create();                                                      // Throws
1,001,721✔
116
        ref_type ref = new_blob.add(value.data(), value.size(), add_zero_term); // Throws
1,001,721✔
117

118
        Array::insert(ndx, int64_t(ref)); // Throws
1,001,721✔
119
    }
1,001,721✔
120
}
2,436,903✔
121

122

123
size_t ArrayBigBlobs::count(BinaryData value, bool is_string, size_t begin, size_t end) const noexcept
124
{
12✔
125
    size_t num_matches = 0;
12✔
126

127
    size_t begin_2 = begin;
12✔
128
    for (;;) {
48✔
129
        size_t ndx = find_first(value, is_string, begin_2, end);
48✔
130
        if (ndx == not_found)
48✔
131
            break;
12✔
132
        ++num_matches;
36✔
133
        begin_2 = ndx + 1;
36✔
134
    }
36✔
135

136
    return num_matches;
12✔
137
}
12✔
138

139

140
size_t ArrayBigBlobs::find_first(BinaryData value, bool is_string, size_t begin, size_t end) const noexcept
141
{
256,410✔
142
    if (end == npos)
256,410✔
143
        end = m_size;
108✔
144
    REALM_ASSERT_11(begin, <=, m_size, &&, end, <=, m_size, &&, begin, <=, end);
256,410✔
145

146
    // When strings are stored as blobs, they are always zero-terminated
147
    // but the value we get as input might not be.
148
    size_t value_size = value.size();
256,410✔
149
    size_t full_size = is_string ? value_size + 1 : value_size;
256,410✔
150

151
    if (value.is_null()) {
256,410✔
152
        for (size_t i = begin; i != end; ++i) {
67,221✔
153
            ref_type ref = get_as_ref(i);
67,215✔
154
            if (ref == 0)
67,215✔
155
                return i;
67,167✔
156
        }
67,215✔
157
    }
67,173✔
158
    else {
189,237✔
159
        for (size_t i = begin; i != end; ++i) {
2,523,090✔
160
            ref_type ref = get_as_ref(i);
2,508,750✔
161
            if (ref) {
2,508,750✔
162
                const char* blob_header = get_alloc().translate(ref);
2,446,125✔
163
                size_t sz = get_size_from_header(blob_header);
2,446,125✔
164
                if (sz == full_size) {
2,446,125✔
165
                    const char* blob_value = ArrayBlob::get(blob_header, 0);
972,810✔
166
                    if (std::equal(blob_value, blob_value + value_size, value.data()))
972,810✔
167
                        return i;
174,897✔
168
                }
972,810✔
169
            }
2,446,125✔
170
        }
2,508,750✔
171
    }
189,237✔
172

173
    return not_found;
14,346✔
174
}
256,410✔
175

176

177
void ArrayBigBlobs::find_all(IntegerColumn& result, BinaryData value, bool is_string, size_t add_offset, size_t begin,
178
                             size_t end)
179
{
12✔
180
    size_t begin_2 = begin;
12✔
181
    for (;;) {
48✔
182
        size_t ndx = find_first(value, is_string, begin_2, end);
48✔
183
        if (ndx == not_found)
48✔
184
            break;
12✔
185
        result.add(add_offset + ndx); // Throws
36✔
186
        begin_2 = ndx + 1;
36✔
187
    }
36✔
188
}
12✔
189

190

191
void ArrayBigBlobs::verify() const
192
{
67,575✔
193
#ifdef REALM_DEBUG
67,575✔
194
    REALM_ASSERT(has_refs());
67,575✔
195
    for (size_t i = 0; i < size(); ++i) {
11,374,350✔
196
        ref_type blob_ref = Array::get_as_ref(i);
11,306,775✔
197
        // 0 is used to indicate realm::null()
198
        if (blob_ref != 0) {
11,306,775✔
199
            ArrayBlob blob(m_alloc);
11,306,742✔
200
            blob.init_from_ref(blob_ref);
11,306,742✔
201
            blob.verify();
11,306,742✔
202
        }
11,306,742✔
203
    }
11,306,775✔
204
#endif
67,575✔
205
}
67,575✔
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