views.hpp
3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifndef REALM_VIEWS_HPP
#define REALM_VIEWS_HPP
#include <realm/column.hpp>
#include <realm/column_string_enum.hpp>
#include <realm/handover_defs.hpp>
#include <realm/index_string.hpp>
namespace realm {
const size_t detached_ref = size_t(-1);
// This class is for common functionality of ListView and LinkView which inherit from it. Currently it only
// supports sorting.
class RowIndexes
{
public:
RowIndexes(IntegerColumn::unattached_root_tag urt, realm::Allocator& alloc) :
#ifdef REALM_COOKIE_CHECK
cookie(cookie_expected),
#endif
m_row_indexes(urt, alloc)
{}
RowIndexes(IntegerColumn&& col) :
#ifdef REALM_COOKIE_CHECK
cookie(cookie_expected),
#endif
m_row_indexes(std::move(col))
{}
RowIndexes(const RowIndexes& source, ConstSourcePayload mode);
RowIndexes(RowIndexes& source, MutableSourcePayload mode);
virtual ~RowIndexes()
{
#ifdef REALM_COOKIE_CHECK
cookie = 0x7765697633333333; // 0x77656976 = 'view'; 0x33333333 = '3333' = destructed
#endif
}
// Return a column of the table that m_row_indexes are pointing at (which is the target table for LinkList and
// parent table for TableView)
virtual const ColumnBase& get_column_base(size_t index) const = 0;
virtual size_t size() const = 0;
// These two methods are overridden by TableView. They are no-ops for LinkView because sync'ed automatically
virtual uint_fast64_t sync_if_needed() const { return 0; }
virtual bool is_in_sync() const { return true; }
void check_cookie() const
{
#ifdef REALM_COOKIE_CHECK
REALM_ASSERT_RELEASE(cookie == cookie_expected);
#endif
}
// Predicate for std::sort
struct Sorter
{
Sorter(){}
Sorter(const std::vector<size_t>& columns, const std::vector<bool>& ascending)
: m_column_indexes(columns), m_ascending(ascending) {}
bool operator()(size_t i, size_t j) const
{
for (size_t t = 0; t < m_columns.size(); t++) {
// todo/fixme, special treatment of StringEnumColumn by calling StringEnumColumn::compare_values()
// instead of the general ColumnTemplate::compare_values() becuse it cannot overload inherited
// `int64_t get_val()` of Column. Such column inheritance needs to be cleaned up
int c;
if (const StringEnumColumn* cse = m_string_enum_columns[t])
c = cse->compare_values(i, j);
else
c = m_columns[t]->compare_values(i, j);
if (c != 0)
return m_ascending[t] ? c > 0 : c < 0;
}
return false; // row i == row j
}
void init(RowIndexes* row_indexes)
{
m_columns.clear();
m_string_enum_columns.clear();
m_columns.resize(m_column_indexes.size(), 0);
m_string_enum_columns.resize(m_column_indexes.size(), 0);
for (size_t i = 0; i < m_column_indexes.size(); i++) {
const ColumnBase& cb = row_indexes->get_column_base(m_column_indexes[i]);
const ColumnTemplateBase* ctb = dynamic_cast<const ColumnTemplateBase*>(&cb);
REALM_ASSERT(ctb);
if (const StringEnumColumn* cse = dynamic_cast<const StringEnumColumn*>(&cb))
m_string_enum_columns[i] = cse;
else
m_columns[i] = ctb;
}
}
std::vector<size_t> m_column_indexes;
std::vector<bool> m_ascending;
std::vector<const ColumnTemplateBase*> m_columns;
std::vector<const StringEnumColumn*> m_string_enum_columns;
};
void sort(Sorter& sorting_predicate);
#ifdef REALM_COOKIE_CHECK
static const uint64_t cookie_expected = 0x7765697677777777ull; // 0x77656976 = 'view'; 0x77777777 = '7777' = alive
uint64_t cookie;
#endif
IntegerColumn m_row_indexes;
};
} // namespace realm
#endif // REALM_VIEWS_HPP