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

realm / realm-core / jorgen.edelbo_402

21 Aug 2024 11:10AM UTC coverage: 91.054% (-0.03%) from 91.085%
jorgen.edelbo_402

Pull #7803

Evergreen

jedelbo
Small fix to Table::typed_write

When writing the realm to a new file from a write transaction,
the Table may be COW so that the top ref is changed. So don't
use the ref that is present in the group when the operation starts.
Pull Request #7803: Feature/string compression

103494 of 181580 branches covered (57.0%)

1929 of 1999 new or added lines in 46 files covered. (96.5%)

695 existing lines in 51 files now uncovered.

220142 of 241772 relevant lines covered (91.05%)

7344461.76 hits per line

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

69.39
/src/realm/array_string_short.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_STRING_SHORT_HPP
20
#define REALM_ARRAY_STRING_SHORT_HPP
21

22
#include <realm/array.hpp>
23
#include <realm/string_data.hpp>
24

25
namespace realm {
26

27
/*
28
ArrayStringShort stores strings as a concecutive list of fixed-length blocks of m_width bytes. The
29
longest string it can store is (m_width - 1) bytes before it needs to expand.
30

31
An example of the format for m_width = 4 is following sequence of bytes, where x is payload:
32

33
xxx0 xx01 x002 0003 0004 (strings "xxx",. "xx", "x", "", realm::null())
34

35
So each string is 0 terminated, and the last byte in a block tells how many 0s are present, except
36
for a realm::null() which has the byte set to m_width (4). The byte is used to compute the length of a string
37
in various functions.
38

39
New: If m_witdh = 0, then all elements are realm::null(). So to add an empty string we must expand m_width
40
New: StringData is null() if-and-only-if StringData::data() == 0.
41
*/
42

43
class ArrayStringShort : public Array {
44
public:
45
    static const size_t max_width = 64;
46

47
    typedef StringData value_type;
48
    // Constructor defaults to non-nullable because we use non-nullable ArrayStringShort so many places internally
49
    // in core (data which isn't user payload) where null isn't needed.
50
    explicit ArrayStringShort(Allocator&, bool nullable = false) noexcept;
51
    ~ArrayStringShort() noexcept override {}
1,935,288✔
52

53
    bool is_null(size_t ndx) const;
54
    void set_null(size_t ndx);
55
    StringData get(size_t ndx) const noexcept;
56
    void add();
57
    void add(StringData value);
58
    void set(size_t ndx, StringData value);
59
    void insert(size_t ndx, StringData value);
60
    void erase(size_t ndx);
61

62
    size_t count(StringData value, size_t begin = 0, size_t end = npos) const noexcept;
63
    size_t find_first(StringData value, size_t begin = 0, size_t end = npos) const noexcept;
64
    void find_all(IntegerColumn& result, StringData value, size_t add_offset = 0, size_t begin = 0,
65
                  size_t end = npos);
66

67
    /// Compare two string arrays for equality.
68
    bool compare_string(const ArrayStringShort&) const noexcept;
69

70
    /// Get the specified element without the cost of constructing an
71
    /// array instance. If an array instance is already available, or
72
    /// you need to get multiple values, then this method will be
73
    /// slower.
74
    static StringData get(const char* header, size_t ndx, bool nullable) noexcept;
75

76
    /// Construct a string array of the specified size and return just
77
    /// the reference to the underlying memory. All elements will be
78
    /// initialized to the empty string.
79
    static MemRef create_array(size_t size, Allocator&);
80

81
    /// Create a new empty string array and attach this accessor to
82
    /// it. This does not modify the parent reference information of
83
    /// this accessor.
84
    ///
85
    /// Note that the caller assumes ownership of the allocated
86
    /// underlying node. It is not owned by the accessor.
87
    void create();
88

89
#ifdef REALM_DEBUG
90
    void string_stats() const;
91
#endif
92

93
private:
94
    size_t calc_byte_len(size_t num_items, size_t width) const override;
95
    size_t calc_item_count(size_t bytes, size_t width) const noexcept override;
96

97
    bool m_nullable;
98
};
99

100

101
// Implementation:
102

103
// Creates new array (but invalid, call init_from_ref() to init)
104
inline ArrayStringShort::ArrayStringShort(Allocator& allocator, bool nullable) noexcept
105
    : Array(allocator)
135,329,697✔
106
    , m_nullable(nullable)
135,329,697✔
107
{
269,894,574✔
108
}
269,894,574✔
109

110
inline void ArrayStringShort::create()
111
{
624,690✔
112
    size_t init_size = 0;
624,690✔
113
    MemRef mem = create_array(init_size, get_alloc()); // Throws
624,690✔
114
    init_from_mem(mem);
624,690✔
115
}
624,690✔
116

117
inline MemRef ArrayStringShort::create_array(size_t init_size, Allocator& allocator)
118
{
910,245✔
119
    bool context_flag = false;
910,245✔
120
    int_fast64_t value = 0;
910,245✔
121
    return Array::create(type_Normal, context_flag, wtype_Multiply, init_size, value, allocator); // Throws
910,245✔
122
}
910,245✔
123

124
inline StringData ArrayStringShort::get(size_t ndx) const noexcept
125
{
137,103,159✔
126
    REALM_ASSERT_3(ndx, <, m_size);
137,103,159✔
127
    if (m_width == 0)
137,103,159✔
128
        return m_nullable ? realm::null() : StringData("");
27,048✔
129

130
    const char* data = m_data + (ndx * m_width);
137,076,111✔
131
    size_t array_size = (m_width - 1) - data[m_width - 1];
137,076,111✔
132

133
    if (array_size == static_cast<size_t>(-1))
137,076,111✔
134
        return m_nullable ? realm::null() : StringData("");
607,224✔
135

136
    REALM_ASSERT_EX(data[array_size] == 0, data[array_size],
136,468,887✔
137
                    array_size); // Realm guarantees 0 terminated return strings
136,468,887✔
138
    return StringData(data, array_size);
136,468,887✔
139
}
137,076,111✔
140

141
inline void ArrayStringShort::add(StringData value)
142
{
676,443✔
143
    REALM_ASSERT(!(!m_nullable && value.is_null()));
676,443✔
144
    insert(m_size, value); // Throws
676,443✔
145
}
676,443✔
146

147
inline void ArrayStringShort::add()
148
{
2✔
149
    add(m_nullable ? realm::null() : StringData("")); // Throws
2✔
150
}
2✔
151

152
inline StringData ArrayStringShort::get(const char* header, size_t ndx, bool nullable) noexcept
UNCOV
153
{
×
UNCOV
154
    REALM_ASSERT(ndx < get_size_from_header(header));
×
UNCOV
155
    uint_least8_t width = get_width_from_header(header);
×
UNCOV
156
    const char* data = get_data_from_header(header) + (ndx * width);
×
UNCOV
157

×
UNCOV
158
    if (width == 0)
×
UNCOV
159
        return nullable ? realm::null() : StringData("");
×
UNCOV
160

×
UNCOV
161
    size_t size = (width - 1) - data[width - 1];
×
UNCOV
162

×
UNCOV
163
    if (size == static_cast<size_t>(-1))
×
UNCOV
164
        return nullable ? realm::null() : StringData("");
×
UNCOV
165

×
UNCOV
166
    return StringData(data, size);
×
UNCOV
167
}
×
168

169

170
} // namespace realm
171

172
#endif // REALM_ARRAY_STRING_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