【SimpleDB】Part 9 - Binary Search and Duplicate Keys

Added functions: Arrange in order according to primary keys; Eliminate primary key conflicts

I. Overview

Now when we insert records, we still insert them at the end of the table, so the data records are out of order.
In this section, we need to find the correct location in the table to insert. If there is already a key to be inserted at this location, an error will be reported (indicating that the primary key already exists)

Because records need to be stored in order, binary search can be used when inserting.

2. Code implementation

  1. Insert key and corresponding value into the root of a table
Cursor* table_find(Table* table,uint32_t key){
    
    
    void* root_node= get_page(table->pager,table->root_page_num);
  //  printf("%d", get_node_type(root_node));
    if(get_node_type(root_node)==NODE_LEAF){
    
    
        return leaf_node_find(table,table->root_page_num,key);
    }
    else{
    
    
        printf("Internal Node\n");
        exit(EXIT_FAILURE);
    }

}
  1. Enter the node and insert a new cell. You need to find the insertion position first (because the records in the node are in order, binary search)
    leaf_node_find
Cursor* leaf_node_find(Table* table,uint32_t page_num,uint32_t key){
    
    
    void* node= get_page(table->pager,page_num);
    uint32_t num_cells= *leaf_node_num_cells(node);
    Cursor* cursor= malloc(sizeof(Cursor));
    cursor->table=table;
    cursor->page_num=page_num;
    //cursor->cell_num ??
    //Binary Search
    // find key from [0,num_cells)
    uint32_t left=0,right=num_cells;
    while(left<right){
    
    
        uint32_t mid=(left+right)/2;
        uint32_t mid_key= *leaf_node_key(node,mid);
        if(mid_key==key){
    
    
            cursor->cell_num=mid;
            return cursor;
        }
        if(key<mid_key){
    
    
            right=mid;
        }
        else{
    
    
            left=mid+1;

        }
    }
    cursor->cell_num=left;
    return cursor;


}
  1. perform insert operation
void leaf_node_insert(Cursor* cursor,uint32_t key,Row* value){
    
    
    void* node= get_page(cursor->table->pager,cursor->page_num);
    uint32_t num_cell= *leaf_node_num_cells(node);
    if(num_cell>LEAF_NODE_MAX_NUM){
    
    
        printf("Need to implement splitting a leaf Node\n");
        exit(EXIT_FAILURE);
    }
    if(cursor->cell_num<num_cell){
    
    
        for(uint32_t i=num_cell;i>cursor->cell_num;i--){
    
    
            memcpy(leaf_node_cell(node,i), leaf_node_cell(node,i-1),LEAF_NODE_CELL_SIZE);
        }
    }
    *leaf_node_num_cells(node)+=1;
    *leaf_node_key(node,cursor->cell_num)=key;
    serialize_row(value, leaf_node_value(node,cursor->cell_num));
}
ExecuteResult execute_insert(Statement* statement,Table* table){
    
    
    void* page= get_page(table->pager,table->root_page_num);
    uint32_t num_cells= *leaf_node_num_cells(page);
    if(num_cells>=LEAF_NODE_MAX_NUM){
    
    
        return EXECUTE_TABLE_FULL;
    }

    Row *row=&(statement->row);
    uint32_t key=row->id;
    Cursor* cursor= table_find(table,key);

    if(cursor->cell_num<num_cells){
    
    
        uint32_t key_at_index=*leaf_node_key(page,cursor->cell_num);//得到要插入的位置的值
        if(key==key_at_index){
    
     //如果发现
            return EXECUTE_DUPLICATE_KEY;
        }
    }

    leaf_node_insert(cursor,row->id,row);//key没有重复,插入
    return EXECUTE_SUCCESS;
}

Guess you like

Origin blog.csdn.net/qq_39679772/article/details/124832946