开始写一个简单的db,https://cstack.github.io/db_tutorial/parts/part1.html,参考。
可以算是toy了,不过希望能借此开始db生涯。
一、总览
查询语句经过的部件
前端有Tokenizer、Parser、Code Generator
后端有virtual machine、B-Tree、Pager、OSInterface
- virtual machine接收前端生成查询计划后的字节码,生成指令,可以对表或者索引进行操作,表和索引存在B+树的结点中。VM本质上的作用就是把字节码生成对应的指令。
- B-树:一个结点存一个页面。通过pager的指令将数据磁盘读取页面,或者将数据页写回磁盘。
- pager:发出读取/写回数据的指令,将最近访问过的页面放在缓存中,同时决定这些页面什么时候写回磁盘。
二、REPL(read-execute-print loop)
开始主函数,是一个能接收输入的无限循环。
数据结构定义以及初始化函数
- InputBuffer
typedef struct{
char* buffer;
size_t buffer_length;
ssize_t input_length;
}InputBuffer;
相关方法实现
-
print_prompt
显示提示符 -
read_input
读取命令
需要用到的函数:ssize_t getline(char **lineptr, size_t *n, FILE *stream);
-
close_input_buffer
退出db时释放内存
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
typedef struct{
char* buffer;
size_t buffer_length;
ssize_t input_length;
}InputBuffer;
InputBuffer* newInputBuffer(){
InputBuffer* inputBuffer=(InputBuffer*)malloc(sizeof(InputBuffer));
inputBuffer->buffer=NULL;
inputBuffer->buffer_length=0;
inputBuffer->input_length=0;
return inputBuffer;
}
void read_line(InputBuffer* buffer){
ssize_t read_size=getline(&(buffer->buffer),&(buffer->buffer_length),stdin);
if(read_size<=0){
printf("Error reading\n");
exit(EXIT_FAILURE); //exit(1) 异常退出
}
buffer->input_length=read_size-1;//忽略换行符
buffer->buffer[read_size-1]=0; //忽略换行符
}
void print_prompt() {
printf("zjxdb > ");
}
void close_input_buffer(InputBuffer* buffer){
free(buffer->buffer);//buffer数组释放
free(buffer);//InputBuffer本身释放
}
int main(){
InputBuffer* inputBuffer=newInputBuffer();
while(1){
print_prompt();
read_line(inputBuffer);
if(strcmp(inputBuffer->buffer,".exit")==0){
close_input_buffer(inputBuffer);
exit(EXIT_SUCCESS);//exit(0) 正常退出
}
else{
printf("command not found:%s\n",inputBuffer->buffer);
}
}
}