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_COLUMN_TPL_HPP
20 #define REALM_COLUMN_TPL_HPP
24 #include <realm/util/features.h>
25 #include <realm/array.hpp>
26 #include <realm/array_basic.hpp>
30 template <class T, class cond>
31 class FloatDoubleNode;
32 template <class ColType, class Cond>
35 class SequentialGetter;
37 template <class cond, class T>
38 struct ColumnTypeTraits2;
41 struct ColumnTypeTraits2<cond, int64_t> {
42 typedef IntegerColumn column_type;
43 typedef ArrayInteger array_type;
46 struct ColumnTypeTraits2<cond, bool> {
47 typedef IntegerColumn column_type;
48 typedef ArrayInteger array_type;
51 struct ColumnTypeTraits2<cond, float> {
52 typedef FloatColumn column_type;
53 typedef ArrayFloat array_type;
56 struct ColumnTypeTraits2<cond, double> {
57 typedef DoubleColumn column_type;
58 typedef ArrayDouble array_type;
64 template <class ColType>
66 using LeafType = typename ColType::LeafType;
68 template <Action action, class Condition, class T, class R>
69 static bool find(const LeafType& leaf, T target, size_t local_start, size_t local_end, size_t leaf_start,
74 // todo, make an additional loop with hard coded `false` instead of is_null(v) for non-nullable columns
75 bool null_target = null::is_null_float(target);
76 for (size_t local_index = local_start; cont && local_index < local_end; local_index++) {
77 auto v = leaf.get(local_index);
78 if (cond(v, target, null::is_null_float(v), null_target)) {
79 cont = state.template match<action, false>(leaf_start + local_index, 0, static_cast<R>(v));
87 struct FindInLeaf<IntegerColumn> {
88 using LeafType = IntegerColumn::LeafType;
90 template <Action action, class Condition, class T, class R>
91 static bool find(const LeafType& leaf, T target, size_t local_start, size_t local_end, size_t leaf_start,
94 const int c = Condition::condition;
95 return leaf.find(c, action, target, local_start, local_end, leaf_start, &state);
100 struct FindInLeaf<IntNullColumn> {
101 using LeafType = IntNullColumn::LeafType;
103 template <Action action, class Condition, class T, class R>
104 static bool find(const LeafType& leaf, T target, size_t local_start, size_t local_end, size_t leaf_start,
105 QueryState<R>& state)
107 constexpr int cond = Condition::condition;
108 return leaf.find(cond, action, target, local_start, local_end, leaf_start, &state);
114 template <class T, class R, Action action, class Condition, class ColType>
115 R aggregate(const ColType& column, T target, size_t start, size_t end, size_t limit, size_t* return_ndx)
121 state.init(action, nullptr, limit);
122 SequentialGetter<ColType> sg{&column};
125 for (size_t s = start; cont && s < end;) {
127 size_t start2 = s - sg.m_leaf_start;
128 size_t end2 = sg.local_end(end);
129 cont = _impl::FindInLeaf<ColType>::template find<action, Condition>(*sg.m_leaf_ptr, target, start2, end2,
130 sg.m_leaf_start, state);
131 s = sg.m_leaf_start + end2;
135 *return_ndx = action == act_Sum ? state.m_match_count : state.m_minmax_index;
137 return state.m_state;
143 #endif // REALM_COLUMN_TPL_HPP