Skip to content

Commit 07ef8aa

Browse files
committed
Store table->pages on the stack
1 parent 6a75735 commit 07ef8aa

File tree

1 file changed

+52
-54
lines changed

1 file changed

+52
-54
lines changed

_parts/part3.md

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,13 @@ We also need code to convert to and from the compact representation.
110110
Next, a `Table` structure that points to pages of rows and keeps track of how many rows there are:
111111
```diff
112112
+const uint32_t PAGE_SIZE = 4096;
113-
+const uint32_t TABLE_MAX_PAGES = 100;
113+
+#define TABLE_MAX_PAGES 100
114114
+const uint32_t ROWS_PER_PAGE = PAGE_SIZE / ROW_SIZE;
115115
+const uint32_t TABLE_MAX_ROWS = ROWS_PER_PAGE * TABLE_MAX_PAGES;
116116
+
117117
+struct Table_t {
118118
+ uint32_t num_rows;
119-
+ void** pages;
119+
+ void* pages[TABLE_MAX_PAGES];
120120
+};
121121
+typedef struct Table_t Table;
122122
```
@@ -188,17 +188,16 @@ memory release function and handle a few more error cases:
188188
+ Table* new_table() {
189189
+ Table* table = malloc(sizeof(Table));
190190
+ 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+
+ }
194194
+ return table;
195195
+}
196196
+
197197
+void free_table(Table* table) {
198198
+ for (int i = 0; table->pages[i]; i++) {
199199
+ free(table->pages[i]);
200200
+ }
201-
+ free(table->pages);
202201
+ free(table);
203202
+}
204203
```
@@ -266,7 +265,7 @@ We'll address those issues in the next part. For now, here's the complete diff f
266265

267266
struct InputBuffer_t {
268267
char* buffer;
269-
@@ -10,6 +11,106 @@ struct InputBuffer_t {
268+
@@ -10,6 +11,105 @@ struct InputBuffer_t {
270269
};
271270
typedef struct InputBuffer_t InputBuffer;
272271

@@ -292,9 +291,9 @@ We'll address those issues in the next part. For now, here's the complete diff f
292291
+#define COLUMN_USERNAME_SIZE 32
293292
+#define COLUMN_EMAIL_SIZE 255
294293
+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];
298297
+};
299298
+typedef struct Row_t Row;
300299
+
@@ -315,65 +314,64 @@ We'll address those issues in the next part. For now, here's the complete diff f
315314
+const uint32_t ROW_SIZE = ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;
316315
+
317316
+const uint32_t PAGE_SIZE = 4096;
318-
+const uint32_t TABLE_MAX_PAGES = 100;
317+
+#define TABLE_MAX_PAGES 100
319318
+const uint32_t ROWS_PER_PAGE = PAGE_SIZE / ROW_SIZE;
320319
+const uint32_t TABLE_MAX_ROWS = ROWS_PER_PAGE * TABLE_MAX_PAGES;
321320
+
322321
+struct Table_t {
323-
+ uint32_t num_rows;
324-
+ void** pages;
322+
+ uint32_t num_rows;
323+
+ void* pages[TABLE_MAX_PAGES];
325324
+};
326325
+typedef struct Table_t Table;
327326
+
328327
+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);
330329
+}
331330
+
332331
+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);
336335
+}
337336
+
338337
+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);
342341
+}
343342
+
344343
+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;
354353
+}
355354
+
356355
+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;
363362
+}
364363
+
365364
+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);
371369
+}
372370
+
373371
InputBuffer* new_input_buffer() {
374372
InputBuffer* input_buffer = malloc(sizeof(InputBuffer));
375373
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) {
377375
free(input_buffer);
378376
}
379377

@@ -409,25 +407,25 @@ We'll address those issues in the next part. For now, here's the complete diff f
409407
+}
410408
+
411409
+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+
+ }
415413
+
416-
+ Row* row_to_insert = &(statement->row_to_insert);
414+
+ Row* row_to_insert = &(statement->row_to_insert);
417415
+
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;
420418
+
421-
+ return EXECUTE_SUCCESS;
419+
+ return EXECUTE_SUCCESS;
422420
+}
423421
+
424422
+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;
431429
+}
432430
+
433431
+ExecuteResult execute_statement(Statement* statement, Table *table) {

0 commit comments

Comments
 (0)