1 /*************************************************************************
3 * Copyright 2016 Realm Inc.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 **************************************************************************/
19 #ifndef REALM_VIEWS_HPP
20 #define REALM_VIEWS_HPP
22 #include <realm/column.hpp>
23 #include <realm/handover_defs.hpp>
29 const int64_t detached_ref = -1;
33 // Forward declaration needed for deleted CommonDescriptor constructor
36 // CommonDescriptor encapsulates a reference to a set of columns (possibly over
37 // links), which is used to indicate the criteria columns for sort and distinct.
38 // Although the input is column indices, it does not rely on those indices
39 // remaining stable as long as the columns continue to exist.
40 class CommonDescriptor {
42 CommonDescriptor() = default;
43 // Enforce type saftey to prevent automatic conversion of derived class
44 // SortDescriptor into CommonDescriptor at compile time.
45 CommonDescriptor(const SortDescriptor&) = delete;
46 virtual ~CommonDescriptor() = default;
48 // Create a descriptor for the given columns on the given table.
49 // Each vector in `column_indices` represents a chain of columns, where
50 // all but the last are Link columns (n.b.: LinkList and Backlink are not
51 // supported), and the final is any column type that can be sorted on.
52 // `column_indices` must be non-empty, and each vector within it must also
54 CommonDescriptor(Table const& table, std::vector<std::vector<size_t>> column_indices);
55 virtual std::unique_ptr<CommonDescriptor> clone() const;
57 // returns whether this descriptor is valid and can be used to sort
58 bool is_valid() const noexcept
60 return !m_columns.empty();
64 virtual Sorter sorter(IntegerColumn const& row_indexes) const;
67 std::vector<std::vector<size_t>> export_column_indices() const;
68 virtual std::vector<bool> export_order() const
74 std::vector<std::vector<const ColumnBase*>> m_columns;
77 class SortDescriptor : public CommonDescriptor {
79 // Create a sort descriptor for the given columns on the given table.
80 // See CommonDescriptor for restrictions on `column_indices`.
81 // The sort order can be specified by using `ascending` which must either be
82 // empty or have one entry for each column index chain.
83 SortDescriptor(Table const& table, std::vector<std::vector<size_t>> column_indices,
84 std::vector<bool> ascending = {});
85 SortDescriptor() = default;
86 ~SortDescriptor() = default;
87 std::unique_ptr<CommonDescriptor> clone() const override;
89 void merge_with(SortDescriptor&& other);
91 Sorter sorter(IntegerColumn const& row_indexes) const override;
94 std::vector<bool> export_order() const override;
97 std::vector<bool> m_ascending;
100 // Distinct uses the same syntax as sort except that the order is meaningless.
101 typedef CommonDescriptor DistinctDescriptor;
103 class DescriptorOrdering {
105 DescriptorOrdering() = default;
106 DescriptorOrdering(const DescriptorOrdering&);
107 DescriptorOrdering(DescriptorOrdering&&) = default;
108 DescriptorOrdering& operator=(const DescriptorOrdering&);
109 DescriptorOrdering& operator=(DescriptorOrdering&&) = default;
111 void append_sort(SortDescriptor sort);
112 void append_distinct(DistinctDescriptor distinct);
113 bool descriptor_is_sort(size_t index) const;
114 bool descriptor_is_distinct(size_t index) const;
115 bool is_empty() const { return m_descriptors.empty(); }
116 size_t size() const { return m_descriptors.size(); }
117 const CommonDescriptor* operator[](size_t ndx) const;
118 bool will_apply_sort() const;
119 bool will_apply_distinct() const;
122 using HandoverPatch = std::unique_ptr<DescriptorOrderingHandoverPatch>;
123 static void generate_patch(DescriptorOrdering const&, HandoverPatch&);
124 static DescriptorOrdering create_from_and_consume_patch(HandoverPatch&, Table const&);
127 std::vector<std::unique_ptr<CommonDescriptor>> m_descriptors;
130 // This class is for common functionality of ListView and LinkView which inherit from it. Currently it only
131 // supports sorting and distinct.
134 RowIndexes(IntegerColumn::unattached_root_tag urt, realm::Allocator& alloc);
135 RowIndexes(IntegerColumn&& col);
136 RowIndexes(const RowIndexes& source, ConstSourcePayload mode);
137 RowIndexes(RowIndexes& source, MutableSourcePayload mode);
139 virtual ~RowIndexes()
141 #ifdef REALM_COOKIE_CHECK
142 m_debug_cookie = 0x7765697633333333; // 0x77656976 = 'view'; 0x33333333 = '3333' = destructed
146 // Disable copying, this is not supported.
147 RowIndexes& operator=(const RowIndexes&) = delete;
148 RowIndexes(const RowIndexes&) = delete;
150 // Return a column of the table that m_row_indexes are pointing at (which is the target table for LinkList and
151 // parent table for TableView)
152 virtual const ColumnBase& get_column_base(size_t index) const = 0;
154 virtual size_t size() const = 0;
156 // These two methods are overridden by TableView and LinkView.
157 virtual uint_fast64_t sync_if_needed() const = 0;
158 virtual bool is_in_sync() const
163 void check_cookie() const
165 #ifdef REALM_COOKIE_CHECK
166 REALM_ASSERT_RELEASE(m_debug_cookie == cookie_expected);
170 IntegerColumn m_row_indexes;
173 void do_sort(const DescriptorOrdering& ordering);
175 static const uint64_t cookie_expected = 0x7765697677777777ull; // 0x77656976 = 'view'; 0x77777777 = '7777' = alive
176 uint64_t m_debug_cookie;
181 #endif // REALM_VIEWS_HPP