array_unsigned.hpp
3.45 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
120
121
122
123
124
125
126
/*************************************************************************
*
* 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.
*
**************************************************************************/
#ifndef REALM_ARRAY_UNSIGNED_HPP
#define REALM_ARRAY_UNSIGNED_HPP
#include <realm/node.hpp>
namespace realm {
// Array holding unsigned values only
class ArrayUnsigned : public Node {
public:
ArrayUnsigned(Allocator& allocator)
: Node(allocator)
{
}
// Will create an uninitialized array of size 'initial_size'
// Has a width big enough to hold values smaller than 'ubound_value'
void create(size_t initial_size, uint64_t ubound_value);
void init_from_ref(ref_type ref) noexcept
{
REALM_ASSERT_DEBUG(ref);
char* header = m_alloc.translate(ref);
init_from_mem(MemRef(header, ref, m_alloc));
}
void update_from_parent() noexcept;
size_t lower_bound(uint64_t value) const noexcept;
size_t upper_bound(uint64_t value) const noexcept;
void add(uint64_t value)
{
insert(m_size, value);
}
// insert value at index (moving successive elements 1 position forwards)
void insert(size_t ndx, uint64_t value);
// delete value at index
void erase(size_t ndx);
// return value at index
uint64_t get(size_t index) const;
// return tagged value at index
// override value at index
void set(size_t ndx, uint64_t value);
void adjust(size_t begin, size_t end, int64_t diff)
{
if (diff != 0) {
// FIXME: Should be optimized
for (size_t i = begin; i < end; ++i)
adjust(i, diff); // Throws
}
}
void truncate(size_t ndx);
/// The meaning of 'width' depends on the context in which this
/// array is used.
size_t get_width() const noexcept
{
return m_width;
}
private:
uint_least8_t m_width = 0; // Size of an element (meaning depend on type of array).
uint64_t m_ubound; // max number that can be stored with current m_width
void init_from_mem(MemRef mem) noexcept
{
Node::init_from_mem(mem);
set_width(get_width_from_header(get_header()));
}
void adjust(size_t ndx, int64_t diff)
{
if (diff != 0) {
set(ndx, get(ndx) + diff); // Throws
}
}
void alloc(size_t init_size, size_t new_width)
{
Node::alloc(init_size, new_width);
set_width(uint8_t(new_width));
}
void set_width(uint8_t width);
uint8_t bit_width(uint64_t value);
void _set(size_t ndx, uint8_t width, uint64_t value);
uint64_t _get(size_t ndx, uint8_t width) const;
};
class ClusterKeyArray : public ArrayUnsigned {
public:
using ArrayUnsigned::ArrayUnsigned;
uint64_t get(size_t ndx) const
{
return (m_data != nullptr) ? ArrayUnsigned::get(ndx) : uint64_t(ndx);
}
};
} // namespace realm
#endif /* REALM_ARRAY_UNSIGNED_HPP */