-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcpu_btree.cuh
159 lines (138 loc) · 5.05 KB
/
cpu_btree.cuh
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#pragma once
#include "btree/cpu_node.cuh"
#include <stdint.h>
#include <oneapi/tbb.h>
namespace CpuBTree {
class BTree {
private:
Node *root_;
void put_baseline(const uint8_t *key, int key_size, const uint8_t *value,
int value_size);
void put_olc(const uint8_t *key, int key_size, const uint8_t *value,
int value_size);
void get_baseline(const uint8_t *key, int key_size, const uint8_t *&value,
int &value_size) const;
public:
BTree() {
root_ = new LeafNode{};
root_->type = Node::Type::LEAF;
}
void puts_baseline(const uint8_t *keys_bytes, const int *keys_indexs,
const uint8_t *values_bytes, const int64_t *values_indexs,
int n);
void puts_olc(const uint8_t *keys_bytes, const int *keys_indexs,
const uint8_t *values_bytes, const int64_t *values_indexs,
int n);
void gets_baseline(const uint8_t *keys_bytes, const int *keys_indexs, int n,
const uint8_t **values_ptrs, int *values_sizes) const;
};
void BTree::puts_baseline(const uint8_t *keys_bytes, const int *keys_indexs,
const uint8_t *values_bytes,
const int64_t *values_indexs, int n) {
for (int i = 0; i < n; ++i) {
const uint8_t *key = util::element_start(keys_indexs, i, keys_bytes);
int key_size = util::element_size(keys_indexs, i);
const uint8_t *value = util::element_start(values_indexs, i, values_bytes);
int value_size = util::element_size(values_indexs, i);
// printf("insert <%p, %d> <%p, %d>\n", key, key_size, value, value_size);
put_baseline(key, key_size, value, value_size);
}
}
void BTree::put_baseline(const uint8_t *key, int key_size, const uint8_t *value,
int value_size) {
restart:
Node *node = root_;
InnerNode *parent = nullptr;
// printf("put baseline start\n");
// printf("node: %p, parent: %p\n", node, parent);
while (node->type == Node::Type::INNER) {
// printf("inner node: %p, parent: %p\n", node, parent);
InnerNode *inner = static_cast<InnerNode *>(node);
// split preemptively if full
if (inner->is_full()) {
const uint8_t *sep;
int sep_size;
InnerNode *new_inner = inner->split(sep, sep_size);
if (parent) {
parent->insert(sep, sep_size, new_inner);
} else {
// make_root
InnerNode *new_root = new InnerNode{};
new_root->type = Node::Type::INNER;
new_root->n_key = 1;
new_root->keys[0] = sep;
new_root->keys_sizes[0] = sep_size;
new_root->children[0] = inner;
new_root->children[1] = new_inner;
root_ = new_root;
}
goto restart; // TODO: keep going instead of restart
}
parent = inner;
node = inner->children[inner->lower_bound(key, key_size)];
}
// printf("start insert to leaf:\nnode: %p, parent: %p\n", node, parent);
// split leaf if full
LeafNode *leaf = static_cast<LeafNode *>(node);
if (leaf->is_full()) {
// printf("leaf is full, split\n");
// TODO ? why check this
if (!parent && node != root_) { // atomic
goto restart;
}
// split
const uint8_t *sep;
int sep_size;
LeafNode *new_leaf = leaf->split(sep, sep_size);
if (parent) {
parent->insert(sep, sep_size, new_leaf);
} else {
// make root
InnerNode *new_root = new InnerNode{};
new_root->type = Node::Type::INNER;
new_root->n_key = 1;
new_root->keys[0] = sep;
new_root->keys_sizes[0] = sep_size;
new_root->children[0] = leaf;
new_root->children[1] = new_leaf;
root_ = new_root;
}
goto restart; // TODO: keep going instead of restart
} else {
// printf("leaf is not full, insert\n");
leaf->insert(key, key_size, value, value_size);
}
// printf("finish insert to leaf\n");
}
void BTree::gets_baseline(const uint8_t *keys_bytes, const int *keys_indexs,
int n, const uint8_t **values_ptrs,
int *values_sizes) const {
for (int i = 0; i < n; ++i) {
const uint8_t *key = util::element_start(keys_indexs, i, keys_bytes);
int key_size = util::element_size(keys_indexs, i);
const uint8_t *&value = values_ptrs[i];
int &value_size = values_sizes[i];
get_baseline(key, key_size, value, value_size);
}
}
void BTree::get_baseline(const uint8_t *key, int key_size,
const uint8_t *&value, int &value_size) const {
// TODO
Node *node = root_;
while (node->type == Node::Type::INNER) {
InnerNode *inner = static_cast<InnerNode *>(node);
node = inner->children[inner->lower_bound(key, key_size)];
}
LeafNode *leaf = static_cast<LeafNode *>(node);
int pos = leaf->lower_bound(key, key_size);
if (pos < leaf->n_key && util::bytes_equal(key, key_size, leaf->keys[pos],
leaf->keys_sizes[pos])) {
value = leaf->values[pos];
value_size = leaf->values_sizes[pos];
} else {
value = nullptr;
value_size = 0;
}
return;
}
} // namespace CpuBTree