@@ -110,13 +110,13 @@ We also need code to convert to and from the compact representation.
110
110
Next, a ` Table ` structure that points to pages of rows and keeps track of how many rows there are:
111
111
``` diff
112
112
+ const uint32_t PAGE_SIZE = 4096;
113
- + const uint32_t TABLE_MAX_PAGES = 100;
113
+ + #define TABLE_MAX_PAGES 100
114
114
+ const uint32_t ROWS_PER_PAGE = PAGE_SIZE / ROW_SIZE;
115
115
+ const uint32_t TABLE_MAX_ROWS = ROWS_PER_PAGE * TABLE_MAX_PAGES;
116
116
+
117
117
+ struct Table_t {
118
118
+ uint32_t num_rows;
119
- + void** pages;
119
+ + void* pages[TABLE_MAX_PAGES] ;
120
120
+ };
121
121
+ typedef struct Table_t Table;
122
122
```
@@ -188,17 +188,16 @@ memory release function and handle a few more error cases:
188
188
+ Table* new_table() {
189
189
+ Table* table = malloc(sizeof(Table));
190
190
+ table->num_rows = 0;
191
- + // Allocate space for the pointers to the pages
192
- + // and initialize them to NULL
193
- + table->pages = calloc(TABLE_MAX_PAGES, sizeof(void *));
191
+ + for (uint32_t i = 0; i < TABLE_MAX_PAGES; i++) {
192
+ + table->pages[i] = NULL;
193
+ + }
194
194
+ return table;
195
195
+ }
196
196
+
197
197
+ void free_table(Table* table) {
198
198
+ for (int i = 0; table->pages[i]; i++) {
199
199
+ free(table->pages[i]);
200
200
+ }
201
- + free(table->pages);
202
201
+ free(table);
203
202
+ }
204
203
```
@@ -266,7 +265,7 @@ We'll address those issues in the next part. For now, here's the complete diff f
266
265
267
266
struct InputBuffer_t {
268
267
char* buffer;
269
- @@ -10,6 +11,106 @@ struct InputBuffer_t {
268
+ @@ -10,6 +11,105 @@ struct InputBuffer_t {
270
269
};
271
270
typedef struct InputBuffer_t InputBuffer;
272
271
@@ -292,9 +291,9 @@ We'll address those issues in the next part. For now, here's the complete diff f
292
291
+ #define COLUMN_USERNAME_SIZE 32
293
292
+ #define COLUMN_EMAIL_SIZE 255
294
293
+ struct Row_t {
295
- + uint32_t id;
296
- + char username[COLUMN_USERNAME_SIZE];
297
- + char email[COLUMN_EMAIL_SIZE];
294
+ + uint32_t id;
295
+ + char username[COLUMN_USERNAME_SIZE];
296
+ + char email[COLUMN_EMAIL_SIZE];
298
297
+ };
299
298
+ typedef struct Row_t Row;
300
299
+
@@ -315,65 +314,64 @@ We'll address those issues in the next part. For now, here's the complete diff f
315
314
+ const uint32_t ROW_SIZE = ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;
316
315
+
317
316
+ const uint32_t PAGE_SIZE = 4096;
318
- + const uint32_t TABLE_MAX_PAGES = 100;
317
+ + #define TABLE_MAX_PAGES 100
319
318
+ const uint32_t ROWS_PER_PAGE = PAGE_SIZE / ROW_SIZE;
320
319
+ const uint32_t TABLE_MAX_ROWS = ROWS_PER_PAGE * TABLE_MAX_PAGES;
321
320
+
322
321
+ struct Table_t {
323
- + uint32_t num_rows;
324
- + void** pages;
322
+ + uint32_t num_rows;
323
+ + void* pages[TABLE_MAX_PAGES] ;
325
324
+ };
326
325
+ typedef struct Table_t Table;
327
326
+
328
327
+ void print_row(Row* row) {
329
- + printf("(%d, %s, %s)\n", row->id, row->username, row->email);
328
+ + printf("(%d, %s, %s)\n", row->id, row->username, row->email);
330
329
+ }
331
330
+
332
331
+ void serialize_row(Row* source, void* destination) {
333
- + memcpy(destination + ID_OFFSET, &(source->id), ID_SIZE);
334
- + memcpy(destination + USERNAME_OFFSET, &(source->username), USERNAME_SIZE);
335
- + memcpy(destination + EMAIL_OFFSET, &(source->email), EMAIL_SIZE);
332
+ + memcpy(destination + ID_OFFSET, &(source->id), ID_SIZE);
333
+ + memcpy(destination + USERNAME_OFFSET, &(source->username), USERNAME_SIZE);
334
+ + memcpy(destination + EMAIL_OFFSET, &(source->email), EMAIL_SIZE);
336
335
+ }
337
336
+
338
337
+ void deserialize_row(void *source, Row* destination) {
339
- + memcpy(&(destination->id), source + ID_OFFSET, ID_SIZE);
340
- + memcpy(&(destination->username), source + USERNAME_OFFSET, USERNAME_SIZE);
341
- + memcpy(&(destination->email), source + EMAIL_OFFSET, EMAIL_SIZE);
338
+ + memcpy(&(destination->id), source + ID_OFFSET, ID_SIZE);
339
+ + memcpy(&(destination->username), source + USERNAME_OFFSET, USERNAME_SIZE);
340
+ + memcpy(&(destination->email), source + EMAIL_OFFSET, EMAIL_SIZE);
342
341
+ }
343
342
+
344
343
+ void* row_slot(Table* table, uint32_t row_num) {
345
- + uint32_t page_num = row_num / ROWS_PER_PAGE;
346
- + void *page = table->pages[page_num];
347
- + if (page == NULL) {
348
- + // Allocate memory only when we try to access page
349
- + page = table->pages[page_num] = malloc(PAGE_SIZE);
350
- + }
351
- + uint32_t row_offset = row_num % ROWS_PER_PAGE;
352
- + uint32_t byte_offset = row_offset * ROW_SIZE;
353
- + return page + byte_offset;
344
+ + uint32_t page_num = row_num / ROWS_PER_PAGE;
345
+ + void *page = table->pages[page_num];
346
+ + if (page == NULL) {
347
+ + // Allocate memory only when we try to access page
348
+ + page = table->pages[page_num] = malloc(PAGE_SIZE);
349
+ + }
350
+ + uint32_t row_offset = row_num % ROWS_PER_PAGE;
351
+ + uint32_t byte_offset = row_offset * ROW_SIZE;
352
+ + return page + byte_offset;
354
353
+ }
355
354
+
356
355
+ Table* new_table() {
357
- + Table* table = malloc(sizeof(Table));
358
- + table->num_rows = 0;
359
- + // Allocate space for the pointers to the pages
360
- + // and initialize them to NULL
361
- + table->pages = calloc(TABLE_MAX_PAGES, sizeof(void *));
362
- + return table;
356
+ + Table* table = malloc(sizeof(Table));
357
+ + table->num_rows = 0;
358
+ + for (uint32_t i = 0; i < TABLE_MAX_PAGES; i++) {
359
+ + table->pages[i] = NULL;
360
+ + }
361
+ + return table;
363
362
+ }
364
363
+
365
364
+ void free_table(Table* table) {
366
- + for (int i = 0; table->pages[i]; i++) {
367
- + free(table->pages[i]);
368
- + }
369
- + free(table->pages);
370
- + free(table);
365
+ + for (int i = 0; table->pages[i]; i++) {
366
+ + free(table->pages[i]);
367
+ + }
368
+ + free(table);
371
369
+ }
372
370
+
373
371
InputBuffer* new_input_buffer() {
374
372
InputBuffer* input_buffer = malloc(sizeof(InputBuffer));
375
373
input_buffer->buffer = NULL;
376
- @@ -40,17 +141 ,105 @@ void close_input_buffer(InputBuffer* input_buffer) {
374
+ @@ -40,17 +140 ,105 @@ void close_input_buffer(InputBuffer* input_buffer) {
377
375
free(input_buffer);
378
376
}
379
377
@@ -409,25 +407,25 @@ We'll address those issues in the next part. For now, here's the complete diff f
409
407
+ }
410
408
+
411
409
+ ExecuteResult execute_insert(Statement* statement, Table* table) {
412
- + if (table->num_rows >= TABLE_MAX_ROWS) {
413
- + return EXECUTE_TABLE_FULL;
414
- + }
410
+ + if (table->num_rows >= TABLE_MAX_ROWS) {
411
+ + return EXECUTE_TABLE_FULL;
412
+ + }
415
413
+
416
- + Row* row_to_insert = &(statement->row_to_insert);
414
+ + Row* row_to_insert = &(statement->row_to_insert);
417
415
+
418
- + serialize_row(row_to_insert, row_slot(table, table->num_rows));
419
- + table->num_rows += 1;
416
+ + serialize_row(row_to_insert, row_slot(table, table->num_rows));
417
+ + table->num_rows += 1;
420
418
+
421
- + return EXECUTE_SUCCESS;
419
+ + return EXECUTE_SUCCESS;
422
420
+ }
423
421
+
424
422
+ ExecuteResult execute_select(Statement* statement, Table* table) {
425
- + Row row;
426
- + for (uint32_t i = 0; i < table->num_rows; i++) {
427
- + deserialize_row(row_slot(table, i), &row);
428
- + print_row(&row);
429
- + }
430
- + return EXECUTE_SUCCESS;
423
+ + Row row;
424
+ + for (uint32_t i = 0; i < table->num_rows; i++) {
425
+ + deserialize_row(row_slot(table, i), &row);
426
+ + print_row(&row);
427
+ + }
428
+ + return EXECUTE_SUCCESS;
431
429
+ }
432
430
+
433
431
+ ExecuteResult execute_statement(Statement* statement, Table *table) {
0 commit comments