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

realm / realm-core / finn.schiermer-andersen_89

04 Jun 2024 02:04PM UTC coverage: 90.651% (-0.03%) from 90.685%
finn.schiermer-andersen_89

Pull #7654

Evergreen

finnschiermer
optimized string cache gc
Pull Request #7654: Fsa/string interning

102644 of 180648 branches covered (56.82%)

1005 of 1125 new or added lines in 15 files covered. (89.33%)

154 existing lines in 21 files now uncovered.

217953 of 240431 relevant lines covered (90.65%)

7671710.15 hits per line

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

58.62
/src/realm/array_string.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_HPP
20
#define REALM_ARRAY_STRING_HPP
21

22
#include <realm/array_string_short.hpp>
23
#include <realm/array_blobs_small.hpp>
24
#include <realm/array_blobs_big.hpp>
25

26
namespace realm {
27

28
class Spec;
29

30
class ArrayString : public ArrayPayload {
31
public:
32
    using value_type = StringData;
33

34
    explicit ArrayString(Allocator&);
35

36
    static StringData default_value(bool nullable)
37
    {
3,715,380✔
38
        return nullable ? StringData{} : StringData{""};
3,715,380✔
39
    }
3,715,380✔
40

41
    // This is only used in the upgrade process
42
    void set_nullability(bool n)
43
    {
×
44
        m_nullable = n;
×
45
    }
×
46
    void create();
47

48
    bool is_attached() const
49
    {
252,360✔
50
        return m_arr->is_attached();
252,360✔
51
    }
252,360✔
52

53
    ref_type get_ref() const
54
    {
177,645✔
55
        return m_arr->get_ref();
177,645✔
56
    }
177,645✔
57
    ArrayParent* get_parent() const
58
    {
×
59
        return m_arr->get_parent();
×
60
    }
×
61
    size_t get_ndx_in_parent() const
62
    {
×
63
        return m_arr->get_ndx_in_parent();
×
64
    }
×
65
    void set_parent(ArrayParent* p, size_t n) noexcept override
66
    {
11,729,166✔
67
        m_arr->set_parent(p, n);
11,729,166✔
68
    }
11,729,166✔
69
    bool need_string_interner() const override
70
    {
138,351✔
71
        return true;
138,351✔
72
    }
138,351✔
73
    void set_string_interner(StringInterner* string_interner) const override
74
    {
71,578,005✔
75
        m_string_interner = string_interner;
71,578,005✔
76
    }
71,578,005✔
77
    bool need_spec() const override
78
    {
138,354✔
79
        return true;
138,354✔
80
    }
138,354✔
81
    void set_spec(Spec* spec, size_t col_ndx) const override
82
    {
8,384,328✔
83
        m_spec = spec;
8,384,328✔
84
        m_col_ndx = col_ndx;
8,384,328✔
85
    }
8,384,328✔
86

87
    void update_parent()
88
    {
63,261✔
89
        m_arr->update_parent();
63,261✔
90
    }
63,261✔
91

92
    void init_from_mem(MemRef mem) noexcept;
93
    void init_from_ref(ref_type ref) noexcept override
94
    {
77,173,599✔
95
        init_from_mem(MemRef(m_alloc.translate(ref), ref, m_alloc));
77,173,599✔
96
    }
77,173,599✔
97
    void init_from_parent();
98
    void destroy() noexcept;
99
    void detach() noexcept;
100

101
    size_t size() const;
102

103
    void add(StringData value);
104
    void set(size_t ndx, StringData value);
105
    void set_null(size_t ndx)
106
    {
2,502✔
107
        set(ndx, StringData{});
2,502✔
108
    }
2,502✔
109
    void insert(size_t ndx, StringData value);
110
    StringData get(size_t ndx) const;
111
    StringData get_legacy(size_t ndx) const;
112
    Mixed get_any(size_t ndx) const override;
113
    bool is_null(size_t ndx) const;
114
    void erase(size_t ndx);
115
    void move(ArrayString& dst, size_t ndx);
116
    void clear();
117

118
    size_t find_first(StringData value, size_t begin, size_t end) const noexcept;
119

120
    size_t lower_bound(StringData value);
121

122
    /// Get the specified element without the cost of constructing an
123
    /// array instance. If an array instance is already available, or
124
    /// you need to get multiple values, then this method will be
125
    /// slower.
126
    static StringData get(const char* header, size_t ndx, Allocator& alloc) noexcept;
127

128
    void verify() const;
129
    // Write to 'out', if needed using 'interner' to intern any strings.
130
    // An interner of 0 will disable interning. Interned values may be further
131
    // compressed using leaf compression for integer arrays.
132
    ref_type write(_impl::ArrayWriterBase& out, StringInterner* interner);
133

134
private:
135
    static constexpr size_t small_string_max_size = 15;  // ArrayStringShort
136
    static constexpr size_t medium_string_max_size = 63; // ArrayStringLong
137
    static constexpr size_t storage_alignment =
138
        std::max({alignof(ArrayStringShort), alignof(ArraySmallBlobs), alignof(ArrayBigBlobs), alignof(Array)});
139
    static constexpr size_t storage_size =
140
        std::max({sizeof(ArrayStringShort), sizeof(ArraySmallBlobs), sizeof(ArrayBigBlobs), sizeof(Array)});
141

142
    enum class Type { small_strings, medium_strings, big_strings, enum_strings, interned_strings };
143

144
    Type m_type = Type::small_strings;
145

146
    Allocator& m_alloc;
147
    alignas(storage_alignment) std::byte m_storage[storage_size];
148
    Array* m_arr;
149
    bool m_nullable = true;
150
    mutable Spec* m_spec = nullptr;
151
    mutable size_t m_col_ndx = realm::npos;
152
    std::unique_ptr<ArrayString> m_string_enum_values;
153
    mutable StringInterner* m_string_interner = nullptr;
154

155
    Type upgrade_leaf(size_t value_size);
156
};
157

158
inline StringData ArrayString::get(const char* header, size_t ndx, Allocator& alloc) noexcept
UNCOV
159
{
×
UNCOV
160
    bool long_strings = Array::get_hasrefs_from_header(header);
×
UNCOV
161
    if (!long_strings) {
×
UNCOV
162
        return ArrayStringShort::get(header, ndx, true);
×
UNCOV
163
    }
×
UNCOV
164
    else {
×
UNCOV
165
        bool is_big = Array::get_context_flag_from_header(header);
×
UNCOV
166
        if (!is_big) {
×
UNCOV
167
            return ArraySmallBlobs::get_string(header, ndx, alloc);
×
UNCOV
168
        }
×
UNCOV
169
        else {
×
UNCOV
170
            return ArrayBigBlobs::get_string(header, ndx, alloc);
×
UNCOV
171
        }
×
UNCOV
172
    }
×
UNCOV
173
}
×
174

175
} // namespace realm
176

177
#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

© 2025 Coveralls, Inc