@@ -110,13 +110,13 @@ We also need code to convert to and from the compact representation.
110110Next, 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