X-Git-Url: https://git.mdrn.pl/wl-app.git/blobdiff_plain/53b27422d140022594fc241cca91c3183be57bca..48b2fe9f7c2dc3d9aeaaa6dbfb27c7da4f3235ff:/iOS/Pods/Realm/include/core/realm/column_mixed_tpl.hpp?ds=sidebyside diff --git a/iOS/Pods/Realm/include/core/realm/column_mixed_tpl.hpp b/iOS/Pods/Realm/include/core/realm/column_mixed_tpl.hpp new file mode 100644 index 0000000..5afdddc --- /dev/null +++ b/iOS/Pods/Realm/include/core/realm/column_mixed_tpl.hpp @@ -0,0 +1,514 @@ +/************************************************************************* + * + * 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. + * + **************************************************************************/ + +#include +#include + +namespace realm { + +inline MixedColumn::MixedColumn(Allocator& alloc, ref_type ref, Table* table, size_t column_ndx) + : ColumnBaseSimple(column_ndx) +{ + create(alloc, ref, table, column_ndx); +} + +inline void MixedColumn::adj_acc_insert_rows(size_t row_ndx, size_t num_rows) noexcept +{ + m_data->adj_acc_insert_rows(row_ndx, num_rows); +} + +inline void MixedColumn::adj_acc_erase_row(size_t row_ndx) noexcept +{ + m_data->adj_acc_erase_row(row_ndx); +} + +inline void MixedColumn::adj_acc_swap_rows(size_t row_ndx_1, size_t row_ndx_2) noexcept +{ + m_data->adj_acc_swap_rows(row_ndx_1, row_ndx_2); +} + +inline void MixedColumn::adj_acc_move_row(size_t from_ndx, size_t to_ndx) noexcept +{ + m_data->adj_acc_move_row(from_ndx, to_ndx); +} + +inline void MixedColumn::adj_acc_move_over(size_t from_row_ndx, size_t to_row_ndx) noexcept +{ + m_data->adj_acc_move_over(from_row_ndx, to_row_ndx); +} + +inline void MixedColumn::adj_acc_clear_root_table() noexcept +{ + m_data->adj_acc_clear_root_table(); +} + +inline ref_type MixedColumn::get_subtable_ref(size_t row_ndx) const noexcept +{ + REALM_ASSERT_3(row_ndx, <, m_types->size()); + if (m_types->get(row_ndx) != type_Table) + return 0; + return m_data->get_as_ref(row_ndx); +} + +inline size_t MixedColumn::get_subtable_size(size_t row_ndx) const noexcept +{ + ref_type top_ref = get_subtable_ref(row_ndx); + if (top_ref == 0) + return 0; + return _impl::TableFriend::get_size_from_ref(top_ref, m_data->get_alloc()); +} + +inline TableRef MixedColumn::get_subtable_accessor(size_t row_ndx) const noexcept +{ + return m_data->get_subtable_accessor(row_ndx); +} + +inline void MixedColumn::discard_subtable_accessor(size_t row_ndx) noexcept +{ + m_data->discard_subtable_accessor(row_ndx); +} + +inline TableRef MixedColumn::get_subtable_tableref(size_t row_ndx) +{ + REALM_ASSERT_3(row_ndx, <, m_types->size()); + if (m_types->get(row_ndx) != type_Table) + return {}; + return m_data->get_subtable_tableref(row_ndx); // Throws +} + +inline ConstTableRef MixedColumn::get_subtable_tableref(size_t subtable_ndx) const +{ + return const_cast(this)->get_subtable_tableref(subtable_ndx); +} + +inline void MixedColumn::discard_child_accessors() noexcept +{ + m_data->discard_child_accessors(); +} + + +// +// Getters +// + +#define REALM_BIT63 0x8000000000000000ULL + +inline int64_t MixedColumn::get_value(size_t ndx) const noexcept +{ + REALM_ASSERT_3(ndx, <, m_types->size()); + + // Shift the unsigned value right - ensuring 0 gets in from left. + // Shifting signed integers right doesn't ensure 0's. + uint64_t value = uint64_t(m_data->get(ndx)) >> 1; + return int64_t(value); +} + +inline int64_t MixedColumn::get_int(size_t ndx) const noexcept +{ + // Get first 63 bits of the integer value + int64_t value = get_value(ndx); + + // restore 'sign'-bit from the column-type + MixedColType col_type = MixedColType(m_types->get(ndx)); + if (col_type == mixcol_IntNeg) { + // FIXME: Bad cast of result of '|' from unsigned to signed + value |= REALM_BIT63; // set sign bit (63) + } + else { + REALM_ASSERT_3(col_type, ==, mixcol_Int); + } + return value; +} + +inline bool MixedColumn::get_bool(size_t ndx) const noexcept +{ + REALM_ASSERT_3(m_types->get(ndx), ==, mixcol_Bool); + + return (get_value(ndx) != 0); +} + +inline OldDateTime MixedColumn::get_olddatetime(size_t ndx) const noexcept +{ + REALM_ASSERT_3(m_types->get(ndx), ==, mixcol_OldDateTime); + + return OldDateTime(get_value(ndx)); +} + +inline float MixedColumn::get_float(size_t ndx) const noexcept +{ + static_assert(std::numeric_limits::is_iec559, "'float' is not IEEE"); + static_assert((sizeof(float) * CHAR_BIT == 32), "Assume 32 bit float."); + REALM_ASSERT_3(m_types->get(ndx), ==, mixcol_Float); + + return type_punning(get_value(ndx)); +} + +inline double MixedColumn::get_double(size_t ndx) const noexcept +{ + static_assert(std::numeric_limits::is_iec559, "'double' is not IEEE"); + static_assert((sizeof(double) * CHAR_BIT == 64), "Assume 64 bit double."); + + int64_t int_val = get_value(ndx); + + // restore 'sign'-bit from the column-type + MixedColType col_type = MixedColType(m_types->get(ndx)); + if (col_type == mixcol_DoubleNeg) + int_val |= REALM_BIT63; // set sign bit (63) + else { + REALM_ASSERT_3(col_type, ==, mixcol_Double); + } + return type_punning(int_val); +} + +inline StringData MixedColumn::get_string(size_t ndx) const noexcept +{ + REALM_ASSERT_3(ndx, <, m_types->size()); + REALM_ASSERT_3(m_types->get(ndx), ==, mixcol_String); + REALM_ASSERT(m_binary_data); + + size_t data_ndx = size_t(int64_t(m_data->get(ndx)) >> 1); + return m_binary_data->get_string(data_ndx); +} + +inline BinaryData MixedColumn::get_binary(size_t ndx) const noexcept +{ + REALM_ASSERT_3(ndx, <, m_types->size()); + REALM_ASSERT_3(m_types->get(ndx), ==, mixcol_Binary); + REALM_ASSERT(m_binary_data); + + size_t data_ndx = size_t(uint64_t(m_data->get(ndx)) >> 1); + return m_binary_data->get(data_ndx); +} + +inline Timestamp MixedColumn::get_timestamp(size_t ndx) const noexcept +{ + REALM_ASSERT_3(ndx, <, m_types->size()); + REALM_ASSERT_3(m_types->get(ndx), ==, mixcol_Timestamp); + REALM_ASSERT(m_timestamp_data); + size_t data_ndx = size_t(uint64_t(m_data->get(ndx)) >> 1); + return m_timestamp_data->get(data_ndx); +} + +// +// Setters +// + +// Set a int64 value. +// Store 63 bit of the value in m_data. Store sign bit in m_types. + +inline void MixedColumn::set_int64(size_t ndx, int64_t value, MixedColType pos_type, MixedColType neg_type) +{ + REALM_ASSERT_3(ndx, <, m_types->size()); + + // If sign-bit is set in value, 'store' it in the column-type + MixedColType coltype = ((value & REALM_BIT63) == 0) ? pos_type : neg_type; + + // Remove refs or binary data (sets type to double) + clear_value_and_discard_subtab_acc(ndx, coltype); // Throws + + // Shift value one bit and set lowest bit to indicate that this is not a ref + value = (value << 1) + 1; + m_data->set(ndx, value); +} + +inline void MixedColumn::set_int(size_t ndx, int64_t value) +{ + set_int64(ndx, value, mixcol_Int, mixcol_IntNeg); // Throws +} + +inline void MixedColumn::set_double(size_t ndx, double value) +{ + int64_t val64 = type_punning(value); + set_int64(ndx, val64, mixcol_Double, mixcol_DoubleNeg); // Throws +} + +inline void MixedColumn::set_value(size_t ndx, int64_t value, MixedColType coltype) +{ + REALM_ASSERT_3(ndx, <, m_types->size()); + + // Remove refs or binary data (sets type to float) + clear_value_and_discard_subtab_acc(ndx, coltype); // Throws + + // Shift value one bit and set lowest bit to indicate that this is not a ref + int64_t v = (value << 1) + 1; + m_data->set(ndx, v); // Throws +} + +inline void MixedColumn::set_float(size_t ndx, float value) +{ + int64_t val64 = type_punning(value); + set_value(ndx, val64, mixcol_Float); // Throws +} + +inline void MixedColumn::set_bool(size_t ndx, bool value) +{ + set_value(ndx, (value ? 1 : 0), mixcol_Bool); // Throws +} + +inline void MixedColumn::set_olddatetime(size_t ndx, OldDateTime value) +{ + set_value(ndx, int64_t(value.get_olddatetime()), mixcol_OldDateTime); // Throws +} + +inline void MixedColumn::set_subtable(size_t ndx, const Table* t) +{ + REALM_ASSERT_3(ndx, <, m_types->size()); + typedef _impl::TableFriend tf; + ref_type ref; + if (t) { + ref = tf::clone(*t, get_alloc()); // Throws + } + else { + ref = tf::create_empty_table(get_alloc()); // Throws + } + // Remove any previous refs or binary data + clear_value_and_discard_subtab_acc(ndx, mixcol_Table); // Throws + m_data->set(ndx, ref); // Throws +} + +// +// Inserts +// + +inline void MixedColumn::insert_value(size_t row_ndx, int_fast64_t types_value, int_fast64_t data_value) +{ + size_t types_size = m_types->size(); // Slow + bool is_append = row_ndx == types_size; + size_t row_ndx_2 = is_append ? realm::npos : row_ndx; + size_t num_rows = 1; + m_types->insert_without_updating_index(row_ndx_2, types_value, num_rows); // Throws + m_data->do_insert(row_ndx_2, data_value, num_rows); // Throws +} + +// Insert a int64 value. +// Store 63 bit of the value in m_data. Store sign bit in m_types. + +inline void MixedColumn::insert_int(size_t ndx, int_fast64_t value, MixedColType type) +{ + int_fast64_t types_value = type; + // Shift value one bit and set lowest bit to indicate that this is not a ref + int_fast64_t data_value = 1 + (value << 1); + insert_value(ndx, types_value, data_value); // Throws +} + +inline void MixedColumn::insert_pos_neg(size_t ndx, int_fast64_t value, MixedColType pos_type, MixedColType neg_type) +{ + // 'store' the sign-bit in the integer-type + MixedColType type = (value & REALM_BIT63) == 0 ? pos_type : neg_type; + int_fast64_t types_value = type; + // Shift value one bit and set lowest bit to indicate that this is not a ref + int_fast64_t data_value = 1 + (value << 1); + insert_value(ndx, types_value, data_value); // Throws +} + +inline void MixedColumn::insert_int(size_t ndx, int_fast64_t value) +{ + insert_pos_neg(ndx, value, mixcol_Int, mixcol_IntNeg); // Throws +} + +inline void MixedColumn::insert_double(size_t ndx, double value) +{ + int_fast64_t value_2 = type_punning(value); + insert_pos_neg(ndx, value_2, mixcol_Double, mixcol_DoubleNeg); // Throws +} + +inline void MixedColumn::insert_float(size_t ndx, float value) +{ + int_fast64_t value_2 = type_punning(value); + insert_int(ndx, value_2, mixcol_Float); // Throws +} + +inline void MixedColumn::insert_bool(size_t ndx, bool value) +{ + int_fast64_t value_2 = int_fast64_t(value); + insert_int(ndx, value_2, mixcol_Bool); // Throws +} + +inline void MixedColumn::insert_olddatetime(size_t ndx, OldDateTime value) +{ + int_fast64_t value_2 = int_fast64_t(value.get_olddatetime()); + insert_int(ndx, value_2, mixcol_OldDateTime); // Throws +} + +inline void MixedColumn::insert_timestamp(size_t ndx, Timestamp value) +{ + ensure_timestamp_column(); + size_t data_ndx = m_timestamp_data->size(); + m_timestamp_data->add(value); // Throws + insert_int(ndx, int_fast64_t(data_ndx), mixcol_Timestamp); +} + +inline void MixedColumn::insert_string(size_t ndx, StringData value) +{ + ensure_binary_data_column(); + size_t blob_ndx = m_binary_data->size(); + m_binary_data->add_string(value); // Throws + + int_fast64_t value_2 = int_fast64_t(blob_ndx); + insert_int(ndx, value_2, mixcol_String); // Throws +} + +inline void MixedColumn::insert_binary(size_t ndx, BinaryData value) +{ + ensure_binary_data_column(); + size_t blob_ndx = m_binary_data->size(); + m_binary_data->add(value); // Throws + + int_fast64_t value_2 = int_fast64_t(blob_ndx); + insert_int(ndx, value_2, mixcol_Binary); // Throws +} + +inline void MixedColumn::insert_subtable(size_t ndx, const Table* t) +{ + typedef _impl::TableFriend tf; + ref_type ref; + if (t) { + ref = tf::clone(*t, get_alloc()); // Throws + } + else { + ref = tf::create_empty_table(get_alloc()); // Throws + } + int_fast64_t types_value = mixcol_Table; + int_fast64_t data_value = int_fast64_t(ref); + insert_value(ndx, types_value, data_value); // Throws +} + +inline void MixedColumn::erase(size_t row_ndx) +{ + size_t num_rows_to_erase = 1; + size_t prior_num_rows = size(); // Note that size() is slow + do_erase(row_ndx, num_rows_to_erase, prior_num_rows); // Throws +} + +inline void MixedColumn::move_last_over(size_t row_ndx) +{ + size_t prior_num_rows = size(); // Note that size() is slow + do_move_last_over(row_ndx, prior_num_rows); // Throws +} + +inline void MixedColumn::swap_rows(size_t row_ndx_1, size_t row_ndx_2) +{ + do_swap_rows(row_ndx_1, row_ndx_2); +} + +inline void MixedColumn::clear() +{ + size_t num_rows = size(); // Note that size() is slow + do_clear(num_rows); // Throws +} + +inline size_t MixedColumn::get_size_from_ref(ref_type root_ref, Allocator& alloc) noexcept +{ + const char* root_header = alloc.translate(root_ref); + ref_type types_ref = to_ref(Array::get(root_header, 0)); + return IntegerColumn::get_size_from_ref(types_ref, alloc); +} + +inline void MixedColumn::clear_value_and_discard_subtab_acc(size_t row_ndx, MixedColType new_type) +{ + MixedColType old_type = clear_value(row_ndx, new_type); + if (old_type == mixcol_Table) + m_data->discard_subtable_accessor(row_ndx); +} + +// Implementing pure virtual method of ColumnBase. +inline void MixedColumn::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); + + size_t row_ndx_2 = (row_ndx == prior_num_rows ? realm::npos : row_ndx); + + int_fast64_t type_value = mixcol_Int; + m_types->insert_without_updating_index(row_ndx_2, type_value, num_rows_to_insert); // Throws + + // The least significant bit indicates that the rest of the bits form an + // integer value, so 1 is actually zero. + int_fast64_t data_value = 1; + m_data->do_insert(row_ndx_2, data_value, num_rows_to_insert); // Throws +} + +// Implementing pure virtual method of ColumnBase. +inline void MixedColumn::erase_rows(size_t row_ndx, size_t num_rows_to_erase, size_t prior_num_rows, bool) +{ + do_erase(row_ndx, num_rows_to_erase, prior_num_rows); // Throws +} + +// Implementing pure virtual method of ColumnBase. +inline void MixedColumn::move_last_row_over(size_t row_ndx, size_t prior_num_rows, bool) +{ + do_move_last_over(row_ndx, prior_num_rows); // Throws +} + +// Implementing pure virtual method of ColumnBase. +inline void MixedColumn::clear(size_t num_rows, bool) +{ + do_clear(num_rows); // Throws +} + +inline void MixedColumn::mark(int type) noexcept +{ + m_data->mark(type); +} + +inline void MixedColumn::refresh_accessor_tree(size_t col_ndx, const Spec& spec) +{ + ColumnBaseSimple::refresh_accessor_tree(col_ndx, spec); + + get_root_array()->init_from_parent(); + m_types->refresh_accessor_tree(col_ndx, spec); // Throws + m_data->refresh_accessor_tree(col_ndx, spec); // Throws + + m_binary_data.reset(); + // See if m_binary_data needs to be created. + if (get_root_array()->size() >= 3) { + ref_type ref = get_root_array()->get_as_ref(2); + m_binary_data.reset(new BinaryColumn(get_alloc(), ref)); // Throws + m_binary_data->set_parent(get_root_array(), 2); + } + + m_timestamp_data.reset(); + // See if m_timestamp_data needs to be created. + if (get_root_array()->size() >= 4) { + ref_type ref = get_root_array()->get_as_ref(3); + // When adding/creating a Mixed column the user cannot specify nullability, so the "true" below + // makes it implicitly nullable, which may not be wanted. But it's OK since Mixed columns are not + // publicly supported + m_timestamp_data.reset(new TimestampColumn(true /*fixme*/, get_alloc(), ref)); // Throws + m_timestamp_data->set_parent(get_root_array(), 3); + } + + if (m_binary_data) { + REALM_ASSERT_3(get_root_array()->size(), >=, 3); + m_binary_data->refresh_accessor_tree(col_ndx, spec); // Throws + } + if (m_timestamp_data) { + REALM_ASSERT_3(get_root_array()->size(), >=, 4); + m_timestamp_data->refresh_accessor_tree(col_ndx, spec); // Throws + } +} + +inline void MixedColumn::RefsColumn::refresh_accessor_tree(size_t col_ndx, const Spec& spec) +{ + SubtableColumnBase::refresh_accessor_tree(col_ndx, spec); // Throws + m_subtable_map.refresh_accessor_tree(); // Throws +} + +} // namespace realm