X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/53b27422d140022594fc241cca91c3183be57bca..48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff:/iOS/Pods/Realm/include/core/realm/column_string_enum.hpp diff --git a/iOS/Pods/Realm/include/core/realm/column_string_enum.hpp b/iOS/Pods/Realm/include/core/realm/column_string_enum.hpp new file mode 100644 index 0000000..a73fe0c --- /dev/null +++ b/iOS/Pods/Realm/include/core/realm/column_string_enum.hpp @@ -0,0 +1,311 @@ +/************************************************************************* + * + * Copyright 2016 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + **************************************************************************/ + +#ifndef REALM_COLUMN_STRING_ENUM_HPP +#define REALM_COLUMN_STRING_ENUM_HPP + +#include + +namespace realm { + +// Pre-declarations +class StringIndex; + + +/// From the point of view of the application, an enumerated strings column +/// (StringEnumColumn) is like a string column (StringColumn), yet it manages +/// its strings in such a way that each unique string is stored only once. In +/// fact, an enumerated strings column is a combination of two subcolumns; a +/// regular string column (StringColumn) that stores the unique strings, and an +/// integer column that stores one unique string index for each entry in the +/// enumerated strings column. +/// +/// In terms of the underlying node structure, the subcolumn containing the +/// unique strings is not a true part of the enumerated strings column. Instead +/// it is a part of the spec structure that describes the table of which the +/// enumerated strings column is a part. This way, the unique strings can be +/// shared across enumerated strings columns of multiple subtables. This also +/// means that the root of an enumerated strings column coincides with the root +/// of the integer subcolumn, and in some sense, an enumerated strings column is +/// just the integer subcolumn. +/// +/// An enumerated strings column can optionally be equipped with a +/// search index. If it is, then the root ref of the index is stored +/// in Table::m_columns immediately after the root ref of the +/// enumerated strings column. +class StringEnumColumn : public IntegerColumn { +public: + typedef StringData value_type; + + StringEnumColumn(Allocator&, ref_type ref, ref_type keys_ref, bool nullable, size_t column_ndx = npos); + ~StringEnumColumn() noexcept override; + void destroy() noexcept override; + MemRef clone_deep(Allocator& alloc) const override; + + int compare_values(size_t row1, size_t row2) const noexcept override + { + StringData a = get(row1); + StringData b = get(row2); + + if (a.is_null() && !b.is_null()) + return 1; + else if (b.is_null() && !a.is_null()) + return -1; + else if (a.is_null() && b.is_null()) + return 0; + + if (a == b) + return 0; + + return utf8_compare(a, b) ? 1 : -1; + } + + StringData get(size_t ndx) const noexcept; + bool is_null(size_t ndx) const noexcept final; + void set(size_t ndx, StringData value); + void set_null(size_t ndx) override; + void add(); + void add(StringData value); + void insert(size_t ndx); + void insert(size_t ndx, StringData value); + void erase(size_t row_ndx); + void move_last_over(size_t row_ndx); + void swap_rows(size_t row_ndx_1, size_t row_ndx_2) override; + void clear(); + bool is_nullable() const noexcept final; + + size_t count(StringData value) const; + size_t find_first(StringData value, size_t begin = 0, size_t end = npos) const; + void find_all(IntegerColumn& res, StringData value, size_t begin = 0, size_t end = npos) const; + FindRes find_all_no_copy(StringData value, InternalFindResult& result) const; + + size_t count(size_t key_index) const; + size_t find_first(size_t key_index, size_t begin = 0, size_t end = -1) const; + void find_all(IntegerColumn& res, size_t key_index, size_t begin = 0, size_t end = -1) const; + + //@{ + /// Find the lower/upper bound for the specified value assuming + /// that the elements are already sorted in ascending order + /// according to StringData::operator<(). + size_t lower_bound_string(StringData value) const noexcept; + size_t upper_bound_string(StringData value) const noexcept; + //@} + + void set_string(size_t, StringData) override; + + void adjust_keys_ndx_in_parent(int diff) noexcept; + + // Search index + StringData get_index_data(size_t ndx, StringIndex::StringConversionBuffer& buffer) const noexcept final; + bool supports_search_index() const noexcept final + { + return true; + } + StringIndex* create_search_index() override; + void install_search_index(std::unique_ptr) noexcept; + void destroy_search_index() noexcept override; + + // Compare two string columns for equality + bool compare_string(const StringColumn&) const; + bool compare_string(const StringEnumColumn&) const; + + void insert_rows(size_t, size_t, size_t, bool) override; + void erase_rows(size_t, size_t, size_t, bool) override; + void move_last_row_over(size_t, size_t, bool) override; + void clear(size_t, bool) override; + void update_from_parent(size_t) noexcept override; + void refresh_accessor_tree(size_t, const Spec&) override; + + size_t get_key_ndx(StringData value) const; + size_t get_key_ndx_or_add(StringData value); + + StringColumn& get_keys(); + const StringColumn& get_keys() const; + +#ifdef REALM_DEBUG + void verify() const override; + void verify(const Table&, size_t) const override; + void do_dump_node_structure(std::ostream&, int) const override; + void to_dot(std::ostream&, StringData title) const override; +#endif + +private: + // Member variables + StringColumn m_keys; + bool m_nullable; + + /// If you are appending and have the size of the column readily available, + /// call the 4 argument version instead. If you are not appending, either + /// one is fine. + /// + /// \param row_ndx Must be `realm::npos` if appending. + void do_insert(size_t row_ndx, StringData value, size_t num_rows); + + /// If you are appending and you do not have the size of the column readily + /// available, call the 3 argument version instead. If you are not + /// appending, either one is fine. + /// + /// \param is_append Must be true if, and only if `row_ndx` is equal to the + /// size of the column (before insertion). + void do_insert(size_t row_ndx, StringData value, size_t num_rows, bool is_append); + + void do_erase(size_t row_ndx, bool is_last); + void do_move_last_over(size_t row_ndx, size_t last_row_ndx); + void do_clear(); +}; + + +// Implementation: + +inline StringData StringEnumColumn::get(size_t ndx) const noexcept +{ + REALM_ASSERT_3(ndx, <, IntegerColumn::size()); + size_t key_ndx = to_size_t(IntegerColumn::get(ndx)); + StringData sd = m_keys.get(key_ndx); + REALM_ASSERT_DEBUG(!(!m_nullable && sd.is_null())); + return sd; +} + +inline bool StringEnumColumn::is_null(size_t ndx) const noexcept +{ + return is_nullable() && get(ndx).is_null(); +} + +inline void StringEnumColumn::add() +{ + add(m_nullable ? realm::null() : StringData("")); +} + +inline void StringEnumColumn::add(StringData value) +{ + REALM_ASSERT_DEBUG(!(!m_nullable && value.is_null())); + size_t row_ndx = realm::npos; + size_t num_rows = 1; + do_insert(row_ndx, value, num_rows); // Throws +} + +inline void StringEnumColumn::insert(size_t row_ndx) +{ + insert(row_ndx, m_nullable ? realm::null() : StringData("")); +} + +inline void StringEnumColumn::insert(size_t row_ndx, StringData value) +{ + REALM_ASSERT_DEBUG(!(!m_nullable && value.is_null())); + size_t column_size = this->size(); + REALM_ASSERT_3(row_ndx, <=, column_size); + size_t num_rows = 1; + bool is_append = row_ndx == column_size; + do_insert(row_ndx, value, num_rows, is_append); // Throws +} + +inline void StringEnumColumn::erase(size_t row_ndx) +{ + size_t last_row_ndx = size() - 1; // Note that size() is slow + bool is_last = row_ndx == last_row_ndx; + do_erase(row_ndx, is_last); // Throws +} + +inline void StringEnumColumn::move_last_over(size_t row_ndx) +{ + size_t last_row_ndx = size() - 1; // Note that size() is slow + do_move_last_over(row_ndx, last_row_ndx); // Throws +} + +inline void StringEnumColumn::clear() +{ + do_clear(); // Throws +} + +// Overriding virtual method of Column. +inline void StringEnumColumn::insert_rows(size_t row_ndx, size_t num_rows_to_insert, size_t prior_num_rows, + bool insert_nulls) +{ + REALM_ASSERT_DEBUG(prior_num_rows == size()); + REALM_ASSERT(row_ndx <= prior_num_rows); + REALM_ASSERT(!insert_nulls || m_nullable); + + StringData value = m_nullable ? realm::null() : StringData(""); + bool is_append = (row_ndx == prior_num_rows); + do_insert(row_ndx, value, num_rows_to_insert, is_append); // Throws +} + +// Overriding virtual method of Column. +inline void StringEnumColumn::erase_rows(size_t row_ndx, size_t num_rows_to_erase, size_t prior_num_rows, bool) +{ + REALM_ASSERT_DEBUG(prior_num_rows == size()); + REALM_ASSERT(num_rows_to_erase <= prior_num_rows); + REALM_ASSERT(row_ndx <= prior_num_rows - num_rows_to_erase); + + bool is_last = (row_ndx + num_rows_to_erase == prior_num_rows); + for (size_t i = num_rows_to_erase; i > 0; --i) { + size_t row_ndx_2 = row_ndx + i - 1; + do_erase(row_ndx_2, is_last); // Throws + } +} + +// Overriding virtual method of Column. +inline void StringEnumColumn::move_last_row_over(size_t row_ndx, size_t prior_num_rows, bool) +{ + REALM_ASSERT_DEBUG(prior_num_rows == size()); + REALM_ASSERT(row_ndx < prior_num_rows); + + size_t last_row_ndx = prior_num_rows - 1; + do_move_last_over(row_ndx, last_row_ndx); // Throws +} + +// Overriding virtual method of Column. +inline void StringEnumColumn::clear(size_t, bool) +{ + do_clear(); // Throws +} + +inline size_t StringEnumColumn::lower_bound_string(StringData value) const noexcept +{ + return ColumnBase::lower_bound(*this, value); +} + +inline size_t StringEnumColumn::upper_bound_string(StringData value) const noexcept +{ + return ColumnBase::upper_bound(*this, value); +} + +inline void StringEnumColumn::set_string(size_t row_ndx, StringData value) +{ + set(row_ndx, value); // Throws +} + +inline void StringEnumColumn::set_null(size_t row_ndx) +{ + set(row_ndx, realm::null{}); +} + +inline StringColumn& StringEnumColumn::get_keys() +{ + return m_keys; +} + +inline const StringColumn& StringEnumColumn::get_keys() const +{ + return m_keys; +} + + +} // namespace realm + +#endif // REALM_COLUMN_STRING_ENUM_HPP