@@ -48,6 +48,12 @@ namespace alg {
48
48
} __attribute__ ((packed));
49
49
typedef struct node_t *node;
50
50
51
+ public:
52
+ // node and index
53
+ struct nr {
54
+ uint32_t offset;
55
+ int32_t idx;
56
+ };
51
57
private:
52
58
node m_root;
53
59
int fd;
@@ -72,7 +78,7 @@ namespace alg {
72
78
close (fd);
73
79
}
74
80
75
- int32_t Search (int32_t x) {
81
+ nr Search (int32_t x) {
76
82
return search (m_root, x);
77
83
}
78
84
@@ -87,6 +93,7 @@ namespace alg {
87
93
s->flag &= ~LEAF;
88
94
s->flag |= ONDISK; // write to offset 0
89
95
s->offset = 0 ;
96
+ s->n = 0 ;
90
97
s->c [0 ] = m_root->offset ;
91
98
// free old & set new
92
99
free (m_root);
@@ -98,20 +105,30 @@ namespace alg {
98
105
}
99
106
}
100
107
108
+ void DeleteKey (int32_t k) {
109
+ node x = m_root;
110
+ delete_op (m_root, k);
111
+ }
112
+
101
113
private:
102
114
/* *
103
115
* search a key, returns node and index
104
116
*/
105
- int32_t search (node x, int32_t k) {
117
+ nr search (node x, int32_t k) {
106
118
int32_t i = 0 ;
119
+ nr ret;
107
120
while (i<x->n && k > x->key [i]) i++;
108
121
109
- if (i<x->n && k == x->key [i]) {
110
- return i;
111
- } else if (x->flag & LEAF) {
112
- return -1 ;
122
+ if (i<x->n && k == x->key [i]) { // search in [0,n-1]
123
+ ret.offset = x->offset ;
124
+ ret.idx = i;
125
+ return ret;
126
+ } else if (x->flag & LEAF) { // leaf, no more childs
127
+ ret.offset = 0 ;
128
+ ret.idx = -1 ;
129
+ return ret;
113
130
} else {
114
- std::auto_ptr<node_t > xi (READ (x, i));
131
+ std::auto_ptr<node_t > xi (READ (x, i)); // in last child
115
132
return search (xi.get (), k);
116
133
}
117
134
}
@@ -121,8 +138,8 @@ namespace alg {
121
138
*/
122
139
void insert_nonfull (node x, int32_t k) {
123
140
int32_t i = x->n -1 ;
124
- if (x->flag & LEAF) {
125
- while (i>=0 && k <x->key [i]) {
141
+ if (x->flag & LEAF) { // insert into leaf
142
+ while (i>=0 && k < x->key [i]) { // shift from right to left, when k < key[i]
126
143
x->key [i+1 ] = x->key [i];
127
144
i = i - 1 ;
128
145
}
@@ -140,6 +157,8 @@ namespace alg {
140
157
if (k > x->key [i]) {
141
158
i = i+1 ;
142
159
}
160
+ // reload x[i] after split_child(will modify child x[i])
161
+ xi = READ (x, i);
143
162
}
144
163
insert_nonfull (xi, k);
145
164
free (xi);
@@ -167,41 +186,87 @@ namespace alg {
167
186
std::auto_ptr<node_t > y (READ (x, i));
168
187
z->flag &= ~LEAF;
169
188
z->flag |= (y->flag & LEAF);
170
- printf (" leafz:%x\n " , z->flag );
171
- printf (" leafy:%x\n " , y->flag );
172
- printf (" leafx:%x offset:%x\n " , x->flag , x->offset );
173
189
z->n = T - 1 ;
174
190
175
191
int32_t j;
176
- for (j=0 ;j<T-1 ;j++) { // init z
192
+ for (j=0 ;j<T-1 ;j++) { // init z, t-1 keys
177
193
z->key [j] = y->key [j+T];
178
194
}
179
195
180
- if (!(y->flag & LEAF)) {
196
+ if (!(y->flag & LEAF)) { // if not leaf, copy childs too.
181
197
for (j=0 ;j<T;j++) {
182
198
z->c [j] = y->c [j+T];
183
199
}
184
200
}
185
201
186
- y->n = T-1 ; // splited y
202
+ y->n = T-1 ; // shrink y to t-1 elements
187
203
WRITE (y.get ());
188
204
WRITE (z.get ());
189
205
190
- for (j=x->n ;j>=i+1 ;j--) {
191
- x->c [j+1 ] = x->c [j]; // shift
206
+ for (j=x->n ;j>=i+1 ;j--) { // make place for the new child in x
207
+ x->c [j+1 ] = x->c [j];
192
208
}
193
209
194
- // save z
195
- x->c [i+1 ] = z->offset ;
196
-
197
- for (j=x->n -1 ;j>=i;j--) {
210
+ x->c [i+1 ] = z->offset ; // make z the child of x
211
+ for (j=x->n -1 ;j>=i;j--) { // move keys in x
198
212
x->key [j+1 ] = x->key [j];
199
213
}
200
- x->key [i] = y->key [T-1 ];
214
+ x->key [i] = y->key [T-1 ]; // copy the middle element of y into x
201
215
x->n = x->n +1 ;
202
216
WRITE (x);
203
217
}
204
218
219
+ /* *
220
+ * recursion deletion
221
+ */
222
+ void delete_op (node x, int32_t k) {
223
+ int32_t i;
224
+ for (i=0 ;i<x->n ;i++) {
225
+ if (x->key [i] == k) { // leaf node, case1
226
+ break ;
227
+ }
228
+ }
229
+
230
+ if (i<x->n && (x->flag & LEAF)) {
231
+ int j;
232
+ for (j = i;j<x->n -1 ;j++) { // shift copy
233
+ x->key [j] = x->key [j+1 ];
234
+ }
235
+ WRITE (x);
236
+ } else if (x->key [i] == k) { // non-leaf
237
+ if (i = x->n -1 || i == 0 ) { // outside, case 2c
238
+ delete_case3 (x);
239
+ } else {
240
+ node y= READ (x, i-1 );
241
+ if (y->n >= T) { // case 2a
242
+ x->key [i] = y->key [y->n -1 ]; // subsitute the key with predecessor
243
+ delete_op (y, x->key [i]);
244
+ free (y);
245
+ return ;
246
+ }
247
+
248
+ node z = READ (x, i+1 );
249
+ if (z->n >= T) { // case 2b
250
+ x->key [i] = z->key [0 ];
251
+ delete_op (z, x->key [i]);
252
+ return ;
253
+ }
254
+
255
+ // case 2c:
256
+ if (y->n == T-1 && z->n == T-1 ) {
257
+
258
+ }
259
+ delete_case3 (x);
260
+ }
261
+ }
262
+ }
263
+
264
+ /* *
265
+ * delete case3
266
+ */
267
+ void delete_case3 (node x) {
268
+ }
269
+
205
270
/* *
206
271
* Read a 4K-block from disk, and returns the node struct.
207
272
*/
@@ -211,7 +276,7 @@ namespace alg {
211
276
read (fd, xi, BLOCKSIZE);
212
277
return (node)xi;
213
278
}
214
-
279
+
215
280
/* *
216
281
* update a node struct to file, create if offset is -1.
217
282
*/
0 commit comments