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

realm / realm-core / 1786

28 Oct 2023 12:35PM UTC coverage: 91.562% (-0.02%) from 91.582%
1786

push

Evergreen

web-flow
Improve configurations for sanitized builds (#6911)

* Refactor sanitizer flags for different build types:

** Enable address sanitizer for msvc
** Allow to build with sanitizer for diffent optimized build (also Debug)
** Make RelASAN, RelTSAN, RelUSAN, RelUSAN just shortcuts for half-optimized builds

* Fix usage of moved object for fuzz tester
* Check asan/tsan on macos x64/arm64
* Check asan with msvc 2019
* Remove Jenkins sanitized builders replaced by evergreen configs
* Work-around stack-use-after-scope with msvc2019 and mpark
* Fix crash on check with staled ColKeys
* fix a buffer overrun in a test
* fix a race in async_open_realm test util
* Add some logger related test fixes
* Work around catch2 limmitation with not thread safe asserts and TSAN races
* Run multiprocesses tests under sanitizers
* add assert for an error reported by undefined sanitizer
* Workaround uv scheduler main thread only constraint for callbacks called from non main thread and requesting a realm

---------

Co-authored-by: James Stone <james.stone@mongodb.com>

94310 of 173648 branches covered (0.0%)

54 of 63 new or added lines in 15 files covered. (85.71%)

2212 existing lines in 52 files now uncovered.

230602 of 251853 relevant lines covered (91.56%)

6943670.77 hits per line

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

78.85
/src/realm/array_integer.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_ARRAY_INTEGER_HPP
20
#define REALM_ARRAY_INTEGER_HPP
21

22
#include <realm/array.hpp>
23
#include <realm/util/safe_int_ops.hpp>
24
#include <realm/util/optional.hpp>
25
#include <realm/array_key.hpp>
26

27
namespace realm {
28

29
class ArrayInteger : public Array, public ArrayPayload {
30
public:
31
    using value_type = int64_t;
32

33
    using Array::add;
34
    using Array::find_first;
35
    using Array::get;
36
    using Array::insert;
37
    using Array::move;
38
    using Array::set;
39

40
    explicit ArrayInteger(Allocator&) noexcept;
41
    ~ArrayInteger() noexcept override {}
65,555,253✔
42

43
    static value_type default_value(bool)
44
    {
24,001,431✔
45
        return 0;
24,001,431✔
46
    }
24,001,431✔
47

48
    void init_from_ref(ref_type ref) noexcept override
49
    {
15,055,236✔
50
        Array::init_from_ref(ref);
15,055,236✔
51
    }
15,055,236✔
52
    void set_parent(ArrayParent* parent, size_t ndx_in_parent) noexcept override
53
    {
71,913,531✔
54
        Array::set_parent(parent, ndx_in_parent);
71,913,531✔
55
    }
71,913,531✔
56

57
    // Disable copying, this is not allowed.
58
    ArrayInteger& operator=(const ArrayInteger&) = delete;
59
    ArrayInteger(const ArrayInteger&) = delete;
60

61
    void create()
62
    {
503,904✔
63
        Array::create(type_Normal, false, 0, 0);
503,904✔
64
    }
503,904✔
65
    Mixed get_any(size_t ndx) const override;
66

67
    bool is_null(size_t) const
68
    {
×
69
        return false;
×
70
    }
×
71
    template <class cond, class Callback>
72
    bool find(value_type value, size_t start, size_t end, QueryStateBase* state, Callback callback) const;
73
};
74

75
class ArrayIntNull : public Array, public ArrayPayload {
76
public:
77
    using value_type = util::Optional<int64_t>;
78

79
    explicit ArrayIntNull(Allocator&) noexcept;
80
    ~ArrayIntNull() noexcept override;
81

82
    static value_type default_value(bool nullable)
83
    {
1,549,623✔
84
        return nullable ? util::none : util::Optional<int64_t>(0);
1,474,794✔
85
    }
1,549,623✔
86

87
    /// Construct an array of the specified type and size, and return just the
88
    /// reference to the underlying memory. All elements will be initialized to
89
    /// the specified value.
90
    static MemRef create_array(Type, bool context_flag, size_t size, Allocator&);
91
    void create()
92
    {
45,084✔
93
        MemRef r = create_array(type_Normal, false, 0, m_alloc);
45,084✔
94
        init_from_mem(r);
45,084✔
95
    }
45,084✔
96

97
    void init_from_ref(ref_type) noexcept override;
98
    void set_parent(ArrayParent* parent, size_t ndx_in_parent) noexcept override
99
    {
9,614,631✔
100
        Array::set_parent(parent, ndx_in_parent);
9,614,631✔
101
    }
9,614,631✔
102
    void init_from_mem(MemRef) noexcept;
103
    void init_from_parent() noexcept;
104

105
    size_t size() const noexcept;
106
    bool is_empty() const noexcept;
107

108
    void insert(size_t ndx, value_type value);
109
    void add(value_type value);
110
    void set(size_t ndx, value_type value);
111
    value_type get(size_t ndx) const noexcept;
112
    Mixed get_any(size_t ndx) const override;
113
    static value_type get(const char* header, size_t ndx) noexcept;
114
    void get_chunk(size_t ndx, value_type res[8]) const noexcept;
115
    void set_null(size_t ndx);
116
    bool is_null(size_t ndx) const noexcept;
117
    int64_t null_value() const noexcept;
118

119
    void erase(size_t ndx);
120
    void erase(size_t begin, size_t end);
121
    void move(ArrayIntNull& dst, size_t ndx);
122
    void clear();
123

124
    void move(size_t begin, size_t end, size_t dest_begin);
125

126
    bool find(int cond, value_type value, size_t start, size_t end, QueryStateBase* state) const;
127

128
    template <class cond, class Callback>
129
    bool find(value_type value, size_t start, size_t end, QueryStateBase* state, Callback callback) const;
130

131
    // Wrappers for backwards compatibility and for simple use without
132
    // setting up state initialization etc
133
    template <class cond>
134
    size_t find_first(value_type value, size_t start = 0, size_t end = npos) const;
135

136
    void find_all(IntegerColumn* result, value_type value, size_t col_offset = 0, size_t begin = 0,
137
                  size_t end = npos) const;
138

139

140
    size_t find_first(value_type value, size_t begin = 0, size_t end = npos) const;
141

142
protected:
143
    void avoid_null_collision(int64_t value);
144

145
private:
146
    int_fast64_t choose_random_null(int64_t incoming) const;
147
    void replace_nulls_with(int64_t new_null);
148
    bool can_use_as_null(int64_t value) const;
149

150
    template <class Callback>
151
    bool find_impl(int cond, value_type value, size_t start, size_t end, QueryStateBase* state,
152
                   Callback callback) const;
153
    template <class cond, class Callback>
154
    bool find_impl(value_type value, size_t start, size_t end, QueryStateBase* state, Callback callback) const;
155
};
156

157

158
// Implementation:
159

160
inline ArrayInteger::ArrayInteger(Allocator& allocator) noexcept
161
    : Array(allocator)
162
{
65,415,699✔
163
    m_is_inner_bptree_node = false;
65,415,699✔
164
}
65,415,699✔
165

166
inline ArrayIntNull::ArrayIntNull(Allocator& allocator) noexcept
167
    : Array(allocator)
168
{
80,446,791✔
169
}
80,446,791✔
170

171
inline ArrayIntNull::~ArrayIntNull() noexcept {}
80,460,531✔
172

173
inline size_t ArrayIntNull::size() const noexcept
174
{
2,847,327✔
175
    return Array::size() - 1;
2,847,327✔
176
}
2,847,327✔
177

178
inline bool ArrayIntNull::is_empty() const noexcept
179
{
×
UNCOV
180
    return size() == 0;
×
UNCOV
181
}
×
182

183
inline void ArrayIntNull::insert(size_t ndx, value_type value)
184
{
1,884,138✔
185
    if (value) {
1,884,138✔
186
        avoid_null_collision(*value);
369,477✔
187
        Array::insert(ndx + 1, *value);
369,477✔
188
    }
369,477✔
189
    else {
1,514,661✔
190
        Array::insert(ndx + 1, null_value());
1,514,661✔
191
    }
1,514,661✔
192
}
1,884,138✔
193

194
inline void ArrayIntNull::add(value_type value)
195
{
1,132,992✔
196
    if (value) {
1,132,992✔
197
        avoid_null_collision(*value);
1,116,831✔
198
        Array::add(*value);
1,116,831✔
199
    }
1,116,831✔
200
    else {
16,161✔
201
        Array::add(null_value());
16,161✔
202
    }
16,161✔
203
}
1,132,992✔
204

205
inline void ArrayIntNull::set(size_t ndx, value_type value)
206
{
2,701,032✔
207
    if (value) {
2,701,032✔
208
        avoid_null_collision(*value);
2,700,915✔
209
        Array::set(ndx + 1, *value);
2,700,915✔
210
    }
2,700,915✔
211
    else {
117✔
212
        Array::set(ndx + 1, null_value());
117✔
213
    }
117✔
214
}
2,701,032✔
215

216
inline void ArrayIntNull::set_null(size_t ndx)
217
{
12,132✔
218
    Array::set(ndx + 1, null_value());
12,132✔
219
}
12,132✔
220

221
inline ArrayIntNull::value_type ArrayIntNull::get(size_t ndx) const noexcept
222
{
78,817,317✔
223
    int64_t value = Array::get(ndx + 1);
78,817,317✔
224
    if (value == null_value()) {
78,817,317✔
225
        return util::none;
1,618,557✔
226
    }
1,618,557✔
227
    return util::some<int64_t>(value);
77,198,760✔
228
}
77,198,760✔
229

230
inline ArrayIntNull::value_type ArrayIntNull::get(const char* header, size_t ndx) noexcept
231
{
×
232
    int64_t null_value = Array::get(header, 0);
×
233
    int64_t value = Array::get(header, ndx + 1);
×
234
    if (value == null_value) {
×
235
        return util::none;
×
236
    }
×
237
    else {
×
238
        return util::some<int64_t>(value);
×
UNCOV
239
    }
×
UNCOV
240
}
×
241

242
inline bool ArrayIntNull::is_null(size_t ndx) const noexcept
243
{
1,454,451✔
244
    return !get(ndx);
1,454,451✔
245
}
1,454,451✔
246

247
inline int64_t ArrayIntNull::null_value() const noexcept
248
{
80,603,049✔
249
    return Array::get(0);
80,603,049✔
250
}
80,603,049✔
251

252
inline void ArrayIntNull::erase(size_t ndx)
253
{
1,356,057✔
254
    Array::erase(ndx + 1);
1,356,057✔
255
}
1,356,057✔
256

257
inline void ArrayIntNull::erase(size_t begin, size_t end)
258
{
×
UNCOV
259
    Array::erase(begin + 1, end + 1);
×
UNCOV
260
}
×
261

262
inline void ArrayIntNull::clear()
263
{
498✔
264
    Array::truncate(0);
498✔
265
    Array::add(0);
498✔
266
}
498✔
267

268
inline void ArrayIntNull::move(size_t begin, size_t end, size_t dest_begin)
269
{
×
UNCOV
270
    Array::move(begin + 1, end + 1, dest_begin + 1);
×
UNCOV
271
}
×
272

273
} // namespace realm
274

275
#endif // REALM_ARRAY_INTEGER_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

© 2025 Coveralls, Inc