在这一节中,我们要增加一个“游标 Cursor”属性,为之后改造成B树做准备
游标出现场景:
具体如下:
数据结构定义以及初始化:
typedef struct {
Table* table;
uint32_t row_num;
bool end_of_table; // Indicates a position one past the last element
} Cursor;
表明这是table表的游标x
如果该cursor是表中的最后一个的下一个,那么end_of_table=true。
通常我们需要在这个cursor上插入新数据。
相关方法:
获取表的第一个指针和最后一个指针:
Cursor* table_start(Table* table){
Cursor *cursor= malloc(sizeof(Cursor));
cursor->table=table;
cursor->row_num=0;
cursor->end_of_table=(cursor->row_num==table->row_num);
return cursor;
}
Cursor* table_end(Table* table){
Cursor* cursor= malloc(sizeof (Cursor));
cursor->table=table;
cursor->row_num=table->row_num;
cursor->end_of_table=true;
return cursor;
}
通过游标插入和查找:插入需要获得table_end,查找则需要table_start
所以把execute方法改一下:
ExecuteResult execute_insert(Statement* statement,Table* table){
Cursor *cursor= table_end(table);
if(table->row_num>=TABLE_MAX_ROWS){
return EXECUTE_TABLE_FULL;
}
Row *row=&(statement->row);
serialize_row(row, cursor_value(cursor));
table->row_num++;
return EXECUTE_SUCCESS;
}
ExecuteResult execute_select_all(Statement* statement,Table* table){
Cursor *cursor= table_start(table);
uint32_t all_num=table->row_num;
if(all_num<0) return EXECUTE_ERROR;
Row row;
// for(uint32_t i=0;i<all_num;i++){
// deserialize_row(read_slot(table,i),&row);
// print_row(&row);
// }
while(cursor->end_of_table!=true){
deserialize_row(cursor_value(cursor),&row);
print_row(&row);
cursor_advance(cursor);
}
free(cursor);
return EXECUTE_SUCCESS;
}
cursor_value则获取cursor->row_num地址:
void* cursor_value(Cursor* cursor){
// int page_id=row_num/ROW_NUM_PER_PAGE;
// void* page=table->page[page_id];
//
// if(page==NULL){
// //insert
// page=malloc(PAGE_SIZE);
// table->page[page_id]=page;
// }
uint32_t row_num=cursor->row_num;
uint32_t page_num=row_num/ROW_NUM_PER_PAGE;
void* page=get_page(cursor->table->pager,page_num);
uint32_t row_offset=row_num%ROW_NUM_PER_PAGE;
uint32_t offset=row_offset*ROW_SIZE;
return offset+page;
}