@@ -13,7 +13,11 @@ struct InputBuffer_t {
13
13
};
14
14
typedef struct InputBuffer_t InputBuffer ;
15
15
16
- enum ExecuteResult_t { EXECUTE_SUCCESS , EXECUTE_TABLE_FULL };
16
+ enum ExecuteResult_t {
17
+ EXECUTE_SUCCESS ,
18
+ EXECUTE_DUPLICATE_KEY ,
19
+ EXECUTE_TABLE_FULL
20
+ };
17
21
typedef enum ExecuteResult_t ExecuteResult ;
18
22
19
23
enum MetaCommandResult_t {
@@ -124,6 +128,16 @@ const uint32_t LEAF_NODE_SPACE_FOR_CELLS = PAGE_SIZE - LEAF_NODE_HEADER_SIZE;
124
128
const uint32_t LEAF_NODE_MAX_CELLS =
125
129
LEAF_NODE_SPACE_FOR_CELLS / LEAF_NODE_CELL_SIZE ;
126
130
131
+ NodeType get_node_type (void * node ) {
132
+ uint8_t value = * ((uint8_t * )node );
133
+ return (NodeType )value ;
134
+ }
135
+
136
+ void set_node_type (void * node , NodeType type ) {
137
+ uint8_t value = type ;
138
+ * ((uint8_t * )node ) = value ;
139
+ }
140
+
127
141
uint32_t * leaf_node_num_cells (void * node ) {
128
142
return node + LEAF_NODE_NUM_CELLS_OFFSET ;
129
143
}
@@ -170,7 +184,10 @@ void deserialize_row(void* source, Row* destination) {
170
184
memcpy (& (destination -> email ), source + EMAIL_OFFSET , EMAIL_SIZE );
171
185
}
172
186
173
- void initialize_leaf_node (void * node ) { * leaf_node_num_cells (node ) = 0 ; }
187
+ void initialize_leaf_node (void * node ) {
188
+ set_node_type (node , NODE_LEAF );
189
+ * leaf_node_num_cells (node ) = 0 ;
190
+ }
174
191
175
192
void * get_page (Pager * pager , uint32_t page_num ) {
176
193
if (page_num > TABLE_MAX_PAGES ) {
@@ -221,19 +238,52 @@ Cursor* table_start(Table* table) {
221
238
return cursor ;
222
239
}
223
240
224
- Cursor * table_end (Table * table ) {
241
+ Cursor * leaf_node_find (Table * table , uint32_t page_num , uint32_t key ) {
242
+ void * node = get_page (table -> pager , page_num );
243
+ uint32_t num_cells = * leaf_node_num_cells (node );
244
+
225
245
Cursor * cursor = malloc (sizeof (Cursor ));
226
246
cursor -> table = table ;
227
- cursor -> page_num = table -> root_page_num ;
228
-
229
- void * root_node = get_page (table -> pager , table -> root_page_num );
230
- uint32_t num_cells = * leaf_node_num_cells (root_node );
231
- cursor -> cell_num = num_cells ;
232
- cursor -> end_of_table = true;
247
+ cursor -> page_num = page_num ;
248
+
249
+ // Binary search
250
+ uint32_t min_index = 0 ;
251
+ uint32_t one_past_max_index = num_cells ;
252
+ while (one_past_max_index != min_index ) {
253
+ uint32_t index = (min_index + one_past_max_index ) / 2 ;
254
+ uint32_t key_at_index = * leaf_node_key (node , index );
255
+ if (key == key_at_index ) {
256
+ cursor -> cell_num = index ;
257
+ return cursor ;
258
+ }
259
+ if (key < key_at_index ) {
260
+ one_past_max_index = index ;
261
+ } else {
262
+ min_index = index + 1 ;
263
+ }
264
+ }
233
265
266
+ cursor -> cell_num = min_index ;
234
267
return cursor ;
235
268
}
236
269
270
+ /*
271
+ Return the position of the given key.
272
+ If the key is not present, return the position
273
+ where it should be inserted
274
+ */
275
+ Cursor * table_find (Table * table , uint32_t key ) {
276
+ uint32_t root_page_num = table -> root_page_num ;
277
+ void * root_node = get_page (table -> pager , root_page_num );
278
+
279
+ if (get_node_type (root_node ) == NODE_LEAF ) {
280
+ return leaf_node_find (table , root_page_num , key );
281
+ } else {
282
+ printf ("Need to implement searching an internal node\n" );
283
+ exit (EXIT_FAILURE );
284
+ }
285
+ }
286
+
237
287
void * cursor_value (Cursor * cursor ) {
238
288
uint32_t page_num = cursor -> page_num ;
239
289
void * page = get_page (cursor -> table -> pager , page_num );
@@ -456,12 +506,21 @@ void leaf_node_insert(Cursor* cursor, uint32_t key, Row* value) {
456
506
457
507
ExecuteResult execute_insert (Statement * statement , Table * table ) {
458
508
void * node = get_page (table -> pager , table -> root_page_num );
459
- if ((* leaf_node_num_cells (node ) >= LEAF_NODE_MAX_CELLS )) {
509
+ uint32_t num_cells = (* leaf_node_num_cells (node ));
510
+ if (num_cells >= LEAF_NODE_MAX_CELLS ) {
460
511
return EXECUTE_TABLE_FULL ;
461
512
}
462
513
463
514
Row * row_to_insert = & (statement -> row_to_insert );
464
- Cursor * cursor = table_end (table );
515
+ uint32_t key_to_insert = row_to_insert -> id ;
516
+ Cursor * cursor = table_find (table , key_to_insert );
517
+
518
+ if (cursor -> cell_num < num_cells ) {
519
+ uint32_t key_at_index = * leaf_node_key (node , cursor -> cell_num );
520
+ if (key_at_index == key_to_insert ) {
521
+ return EXECUTE_DUPLICATE_KEY ;
522
+ }
523
+ }
465
524
466
525
leaf_node_insert (cursor , row_to_insert -> id , row_to_insert );
467
526
@@ -541,6 +600,9 @@ int main(int argc, char* argv[]) {
541
600
case (EXECUTE_SUCCESS ):
542
601
printf ("Executed.\n" );
543
602
break ;
603
+ case (EXECUTE_DUPLICATE_KEY ):
604
+ printf ("Error: Duplicate key.\n" );
605
+ break ;
544
606
case (EXECUTE_TABLE_FULL ):
545
607
printf ("Error: Table full.\n" );
546
608
break ;
0 commit comments