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_IMPL_SEQUENTIAL_GETTER_HPP
20 #define REALM_IMPL_SEQUENTIAL_GETTER_HPP
24 class SequentialGetterBase {
26 virtual ~SequentialGetterBase() noexcept
31 template <class ColType>
32 class SequentialGetter : public SequentialGetterBase {
34 using T = typename ColType::value_type;
35 using ArrayType = typename ColType::LeafType;
41 SequentialGetter(const Table& table, size_t column_ndx)
43 init(static_cast<const ColType*>(&table.get_column_base(column_ndx)));
46 SequentialGetter(const ColType* column)
51 ~SequentialGetter() noexcept override
55 void init(const ColType* column)
57 REALM_ASSERT(column != nullptr);
58 m_array_ptr.reset(); // Explicitly destroy the old one first, because we're reusing the memory.
59 m_array_ptr.reset(new (&m_leaf_accessor_storage) ArrayType(column->get_alloc()));
64 REALM_FORCEINLINE bool cache_next(size_t index)
66 // Set m_leaf_ptr to point at the leaf that contains the value at column row `index`. Return whether or not
67 // the leaf has changed (could be useful to know for caller).
69 // FIXME: Below line has been commented away because array leafs might relocate during the lifetime of the
70 // object that owns this SequentialGetter. Enable again when we have proper support for that.
71 // if (index >= m_leaf_end || index < m_leaf_start)
73 typename ColType::LeafInfo leaf{&m_leaf_ptr, m_array_ptr.get()};
75 m_column->get_leaf(index, ndx_in_leaf, leaf);
76 m_leaf_start = index - ndx_in_leaf;
77 const size_t leaf_size = m_leaf_ptr->size();
78 m_leaf_end = m_leaf_start + leaf_size;
85 REALM_FORCEINLINE T get_next(size_t index)
89 #pragma warning(disable : 4800) // Disable the Microsoft warning about bool performance issue.
91 return m_column->get(index);
93 // FIXME: Below optimization is skipped because array leafs might relocate during the lifetime of the
94 // object that owns this SequentialGetter. Enable again when we have proper support for that.
97 // T av = m_leaf_ptr->get(index - m_leaf_start);
105 size_t local_end(size_t global_end)
107 if (global_end > m_leaf_end)
108 return m_leaf_end - m_leaf_start;
110 return global_end - m_leaf_start;
113 size_t m_leaf_start = 0;
114 size_t m_leaf_end = 0;
115 const ColType* m_column = nullptr;
117 const ArrayType* m_leaf_ptr = nullptr;
120 // Leaf cache for when the root of the column is not a leaf.
121 // This dog and pony show is because Array has a reference to Allocator internally,
122 // but we need to be able to transfer queries between contexts, so init() reinitializes
123 // the leaf cache in the context of the current column.
124 typename std::aligned_storage<sizeof(ArrayType), alignof(ArrayType)>::type m_leaf_accessor_storage;
125 std::unique_ptr<ArrayType, PlacementDelete> m_array_ptr;
130 #endif // REALM_IMPL_SEQUENTIAL_GETTER_HPP