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

realm / realm-core / thomas.goyne_120

20 Nov 2023 07:46PM UTC coverage: 92.066% (+0.4%) from 91.699%
thomas.goyne_120

push

Evergreen

web-flow
Fix client reset cycle detection for PBS recovery errors (#7149)

Tracking that a client reset was in progress was done in the same write
transaction as the recovery operation, so if recovery failed the tracking was
rolled back too. This worked for FLX due to that codepath committing before
beginning recovery.

85328 of 169122 branches covered (0.0%)

30 of 30 new or added lines in 3 files covered. (100.0%)

169 existing lines in 18 files now uncovered.

233147 of 253239 relevant lines covered (92.07%)

5776222.82 hits per line

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

98.72
/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
{
248,232✔
29
    ref_type ref = get_as_ref(ndx);
248,232✔
30
    if (ref == 0)
248,232✔
31
        return {}; // realm::null();
53,616✔
32

123,417✔
33
    ArrayBlob blob(m_alloc);
194,616✔
34
    blob.init_from_ref(ref);
194,616✔
35

123,417✔
36
    return blob.get_at(pos);
194,616✔
37
}
194,616✔
38

39

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

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

55

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

2,713,182✔
61
    ref_type ref = get_as_ref(ndx);
5,440,050✔
62

2,713,182✔
63
    if (ref == 0 && value.is_null()) {
5,440,050✔
64
        return;
1,584✔
65
    }
1,584✔
66
    else if (ref == 0 && value.data() != nullptr) {
5,438,466✔
67
        ArrayBlob new_blob(m_alloc);
1,387,242✔
68
        new_blob.create();                                             // Throws
1,387,242✔
69
        ref = new_blob.add(value.data(), value.size(), add_zero_term); // Throws
1,387,242✔
70
        Array::set_as_ref(ndx, ref);
1,387,242✔
71
        return;
1,387,242✔
72
    }
1,387,242✔
73
    else if (ref != 0 && value.data() != nullptr) {
4,054,062✔
74
        char* header = m_alloc.translate(ref);
4,046,019✔
75
        if (Array::get_context_flag_from_header(header)) {
4,046,019✔
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,046,013✔
86
            ArrayBlob blob(m_alloc);
4,046,013✔
87
            blob.init_from_mem(MemRef(header, ref, m_alloc));
4,046,013✔
88
            blob.set_parent(this, ndx);
4,046,013✔
89
            ref_type new_ref = blob.replace(0, blob.blob_size(), value.data(), value.size(), add_zero_term); // Throws
4,046,013✔
90
            if (new_ref != ref) {
4,046,013✔
91
                Array::set_as_ref(ndx, new_ref);
3,674,922✔
92
            }
3,674,922✔
93
        }
4,046,013✔
94
        return;
4,046,019✔
95
    }
4,046,019✔
96
    else if (ref != 0 && value.is_null()) {
7,944✔
97
        Array::destroy_deep(ref, get_alloc());
7,944✔
98
        Array::set(ndx, 0);
7,944✔
99
        return;
7,944✔
100
    }
7,944✔
101
    REALM_ASSERT(false);
4,294,967,294✔
102
}
4,294,967,294✔
103

104

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

1,130,928✔
110
    if (value.is_null()) {
2,263,512✔
111
        Array::insert(ndx, 0); // Throws
1,392,714✔
112
    }
1,392,714✔
113
    else {
870,798✔
114
        ArrayBlob new_blob(m_alloc);
870,798✔
115
        new_blob.create();                                                      // Throws
870,798✔
116
        ref_type ref = new_blob.add(value.data(), value.size(), add_zero_term); // Throws
870,798✔
117

444,042✔
118
        Array::insert(ndx, int64_t(ref)); // Throws
870,798✔
119
    }
870,798✔
120
}
2,263,512✔
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

6✔
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

6✔
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
{
255,069✔
142
    if (end == npos)
255,069✔
143
        end = m_size;
108✔
144
    REALM_ASSERT_11(begin, <=, m_size, &&, end, <=, m_size, &&, begin, <=, end);
255,069✔
145

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

127,638✔
151
    if (value.is_null()) {
255,069✔
152
        for (size_t i = begin; i != end; ++i) {
66,972✔
153
            ref_type ref = get_as_ref(i);
66,963✔
154
            if (ref == 0)
66,963✔
155
                return i;
66,915✔
156
        }
66,963✔
157
    }
66,924✔
158
    else {
188,145✔
159
        for (size_t i = begin; i != end; ++i) {
2,527,404✔
160
            ref_type ref = get_as_ref(i);
2,513,112✔
161
            if (ref) {
2,513,112✔
162
                const char* blob_header = get_alloc().translate(ref);
2,449,494✔
163
                size_t sz = get_size_from_header(blob_header);
2,449,494✔
164
                if (sz == full_size) {
2,449,494✔
165
                    const char* blob_value = ArrayBlob::get(blob_header, 0);
971,388✔
166
                    if (std::equal(blob_value, blob_value + value_size, value.data()))
971,388✔
167
                        return i;
173,853✔
168
                }
971,388✔
169
            }
2,449,494✔
170
        }
2,513,112✔
171
    }
188,145✔
172

127,638✔
173
    return not_found;
134,811✔
174
}
255,069✔
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

192
void ArrayBigBlobs::verify() const
193
{
16,854✔
194
#ifdef REALM_DEBUG
16,854✔
195
    REALM_ASSERT(has_refs());
16,854✔
196
    for (size_t i = 0; i < size(); ++i) {
64,164✔
197
        ref_type blob_ref = Array::get_as_ref(i);
47,310✔
198
        // 0 is used to indicate realm::null()
22,998✔
199
        if (blob_ref != 0) {
47,310✔
200
            ArrayBlob blob(m_alloc);
45,762✔
201
            blob.init_from_ref(blob_ref);
45,762✔
202
            blob.verify();
45,762✔
203
        }
45,762✔
204
    }
47,310✔
205
#endif
16,854✔
206
}
16,854✔
207

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