mirror of
https://github.com/fumiama/fumidb.git
synced 2026-06-22 05:16:56 +08:00
finish load table
This commit is contained in:
@@ -11,7 +11,7 @@
|
|||||||
// 返回:
|
// 返回:
|
||||||
// NULL 失败,详见 errno
|
// NULL 失败,详见 errno
|
||||||
// table 指向表头的指针
|
// table 指向表头的指针
|
||||||
void* create_table(int fd, char* buf, const char* name, uint16_t row_len, ...);
|
void* create_table(int fd, char* buf, const char* name, int row_len, ...);
|
||||||
|
|
||||||
// 加载 ptr 位置的表
|
// 加载 ptr 位置的表
|
||||||
// len(buf) >= 4096+8+2=4106
|
// len(buf) >= 4096+8+2=4106
|
||||||
@@ -47,7 +47,7 @@ int remove_table_index(int fd, void* table, uint16_t pos);
|
|||||||
// 返回:
|
// 返回:
|
||||||
// 0 失败,详见 errno
|
// 0 失败,详见 errno
|
||||||
// ptr 本行插入的位置
|
// ptr 本行插入的位置
|
||||||
uint64_t insert_row(int fd, void* table, uint16_t row_len, ...);
|
uint64_t insert_row(int fd, void* table, int row_len, ...);
|
||||||
|
|
||||||
// 根据主键的匹配值查找行
|
// 根据主键的匹配值查找行
|
||||||
// 如果主键不为 string,k 直接装填其值
|
// 如果主键不为 string,k 直接装填其值
|
||||||
@@ -65,7 +65,7 @@ uint64_t find_row_by_pk(int fd, void* table, key_t k);
|
|||||||
// 返回:
|
// 返回:
|
||||||
// 非 0 失败,详见 errno
|
// 非 0 失败,详见 errno
|
||||||
// 0 成功
|
// 0 成功
|
||||||
int find_row_by(int fd, void* table, int (*f)(uint64_t), uint16_t row_len, ...);
|
int find_row_by(int fd, void* table, int (*f)(uint64_t), int row_len, ...);
|
||||||
|
|
||||||
// 根据主键的匹配值删除行
|
// 根据主键的匹配值删除行
|
||||||
// 如果主键不为 string,k 直接装填其值
|
// 如果主键不为 string,k 直接装填其值
|
||||||
@@ -82,6 +82,6 @@ int remove_row_by_pk(int fd, void* table, key_t k);
|
|||||||
// 返回:
|
// 返回:
|
||||||
// 非 0 失败,详见 errno
|
// 非 0 失败,详见 errno
|
||||||
// 0 成功
|
// 0 成功
|
||||||
int remove_row_by(int fd, void* table, uint16_t row_len, ...);
|
int remove_row_by(int fd, void* table, int row_len, ...);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
22
src/page.c
22
src/page.c
@@ -30,7 +30,7 @@ void* alloc_page(int fd, void* page) {
|
|||||||
if(write(fd, buf, 8) != 8) return NULL; // 从空闲块链表移除本块
|
if(write(fd, buf, 8) != 8) return NULL; // 从空闲块链表移除本块
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
if(prev_prev_ptr && ptr < prev_ptr) { // 不符合顺序,进行一次调整
|
if(prev_prev_ptr && ptr < prev_ptr && ptr != 8) { // 不符合顺序,进行一次调整
|
||||||
lseek(fd, prev_prev_ptr, SEEK_SET);
|
lseek(fd, prev_prev_ptr, SEEK_SET);
|
||||||
putle64(buf, ptr);
|
putle64(buf, ptr);
|
||||||
if(write(fd, buf, 8) != 8) return NULL; // 1->next = 3
|
if(write(fd, buf, 8) != 8) return NULL; // 1->next = 3
|
||||||
@@ -87,7 +87,7 @@ int free_page(int fd, void* page) {
|
|||||||
errno = ESPIPE;
|
errno = ESPIPE;
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
if(prev_prev_ptr && ptr < prev_ptr) { // 不符合顺序,进行一次调整
|
if(prev_prev_ptr && ptr < prev_ptr && ptr != 8) { // 不符合顺序,进行一次调整
|
||||||
lseek(fd, prev_prev_ptr, SEEK_SET);
|
lseek(fd, prev_prev_ptr, SEEK_SET);
|
||||||
putle64(buf, ptr);
|
putle64(buf, ptr);
|
||||||
if(write(fd, buf, 8) != 8) return EOF; // 1->next = 3
|
if(write(fd, buf, 8) != 8) return EOF; // 1->next = 3
|
||||||
@@ -140,7 +140,11 @@ void* alloc_block(int fd, uint16_t size, void* blk) {
|
|||||||
errno = ESPIPE;
|
errno = ESPIPE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
readle16(fd, blksz);
|
if(ptr == 8) blksz = 0;
|
||||||
|
else readle16(fd, blksz);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("ptr: %016llx, blksize: %d\n", ptr, blksz);
|
||||||
|
#endif
|
||||||
if(blksz >= size) { // 找到符合要求的块
|
if(blksz >= size) { // 找到符合要求的块
|
||||||
if(blksz - size > 10) { // 分裂块
|
if(blksz - size > 10) { // 分裂块
|
||||||
lseek(fd, ptr+size, SEEK_SET);
|
lseek(fd, ptr+size, SEEK_SET);
|
||||||
@@ -152,6 +156,9 @@ void* alloc_block(int fd, uint16_t size, void* blk) {
|
|||||||
}
|
}
|
||||||
putle64(blk, ptr);
|
putle64(blk, ptr);
|
||||||
putle16(blk+8, size);
|
putle16(blk+8, size);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("find match: ptr: %016llx, size: %d\n", ptr, size);
|
||||||
|
#endif
|
||||||
blk += 10;
|
blk += 10;
|
||||||
if(lseek(fd, prev_ptr, SEEK_SET) < 0) return NULL;
|
if(lseek(fd, prev_ptr, SEEK_SET) < 0) return NULL;
|
||||||
if(write(fd, buf, 8) != 8) { // 从空闲块链表移除本块
|
if(write(fd, buf, 8) != 8) { // 从空闲块链表移除本块
|
||||||
@@ -160,7 +167,7 @@ void* alloc_block(int fd, uint16_t size, void* blk) {
|
|||||||
}
|
}
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
if(prev_prev_ptr && ptr < prev_ptr) { // 不符合顺序,进行一次调整
|
if(prev_prev_ptr && ptr < prev_ptr && ptr != 8) { // 不符合顺序,进行一次调整
|
||||||
lseek(fd, prev_prev_ptr, SEEK_SET);
|
lseek(fd, prev_prev_ptr, SEEK_SET);
|
||||||
putle64(buf, ptr);
|
putle64(buf, ptr);
|
||||||
if(write(fd, buf, 8) != 8) return NULL; // 1->next = 3
|
if(write(fd, buf, 8) != 8) return NULL; // 1->next = 3
|
||||||
@@ -221,6 +228,9 @@ int sync_block(int fd, void* blk) {
|
|||||||
errno = EFBIG;
|
errno = EFBIG;
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("off: %016llx, size: %d\n", off, size);
|
||||||
|
#endif
|
||||||
if(lseek(fd, off, SEEK_SET) < 0) return EOF;
|
if(lseek(fd, off, SEEK_SET) < 0) return EOF;
|
||||||
return write(fd, blk, size) != size;
|
return write(fd, blk, size) != size;
|
||||||
}
|
}
|
||||||
@@ -235,7 +245,7 @@ int free_block(int fd, void* blk) {
|
|||||||
errno = ESPIPE;
|
errno = ESPIPE;
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
if(prev_prev_ptr && ptr < prev_ptr) { // 不符合顺序,进行一次调整
|
if(prev_prev_ptr && ptr < prev_ptr && ptr != 8) { // 不符合顺序,进行一次调整
|
||||||
lseek(fd, prev_prev_ptr, SEEK_SET);
|
lseek(fd, prev_prev_ptr, SEEK_SET);
|
||||||
putle64(buf, ptr);
|
putle64(buf, ptr);
|
||||||
if(write(fd, buf, 8) != 8) return EOF; // 1->next = 3
|
if(write(fd, buf, 8) != 8) return EOF; // 1->next = 3
|
||||||
@@ -288,7 +298,7 @@ int add_block(int fd, uint16_t size, uint64_t off) {
|
|||||||
errno = ESPIPE;
|
errno = ESPIPE;
|
||||||
return EOF;
|
return EOF;
|
||||||
}
|
}
|
||||||
if(prev_prev_ptr && ptr < prev_ptr) { // 不符合顺序,进行一次调整
|
if(prev_prev_ptr && ptr < prev_ptr && ptr != 8) { // 不符合顺序,进行一次调整
|
||||||
lseek(fd, prev_prev_ptr, SEEK_SET);
|
lseek(fd, prev_prev_ptr, SEEK_SET);
|
||||||
putle64(buf, ptr);
|
putle64(buf, ptr);
|
||||||
if(write(fd, buf, 8) != 8) return EOF; // 1->next = 3
|
if(write(fd, buf, 8) != 8) return EOF; // 1->next = 3
|
||||||
|
|||||||
40
src/table.c
40
src/table.c
@@ -35,7 +35,7 @@ static int _calc_index_size(type_t t) {
|
|||||||
// 返回:
|
// 返回:
|
||||||
// 1 失败,详见 errno
|
// 1 失败,详见 errno
|
||||||
// 0 成功
|
// 0 成功
|
||||||
static void* _add_index_type(int fd, uint64_t* index_ptr, type_t t) {
|
static int _add_index_type(int fd, uint64_t* index_ptr, type_t t) {
|
||||||
int sz = _calc_index_size(t);
|
int sz = _calc_index_size(t);
|
||||||
if(sz <= 0) {
|
if(sz <= 0) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@@ -56,10 +56,8 @@ static void* _add_index_type(int fd, uint64_t* index_ptr, type_t t) {
|
|||||||
// 返回:
|
// 返回:
|
||||||
// NULL 失败,详见 errno
|
// NULL 失败,详见 errno
|
||||||
// table 指向表头的指针
|
// table 指向表头的指针
|
||||||
void* create_table(int fd, char* buf, const char* name, uint16_t row_len, ...) {
|
void* create_table(int fd, char* buf, const char* name, int row_len, ...) {
|
||||||
va_list list;
|
if(row_len <= 0 || row_len > 128) {
|
||||||
|
|
||||||
if(!row_len || row_len > 128) {
|
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -88,9 +86,10 @@ void* create_table(int fd, char* buf, const char* name, uint16_t row_len, ...) {
|
|||||||
len += 2;
|
len += 2;
|
||||||
|
|
||||||
int foreign_cnt = 0;
|
int foreign_cnt = 0;
|
||||||
|
va_list list;
|
||||||
va_start(list, row_len);
|
va_start(list, row_len);
|
||||||
|
|
||||||
type_t t = va_arg(list, type_t); // 是主键,检查是否有 unique + nonnull 类型修饰符
|
type_t t = va_arg(list, int); // 是主键,检查是否有 unique + nonnull 类型修饰符
|
||||||
if(!(t&EXTYPE_NONNULL) || !(t&EXTYPE_UNIQUE)) {
|
if(!(t&EXTYPE_NONNULL) || !(t&EXTYPE_UNIQUE)) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -104,7 +103,7 @@ void* create_table(int fd, char* buf, const char* name, uint16_t row_len, ...) {
|
|||||||
// 为 pk 创建索引
|
// 为 pk 创建索引
|
||||||
if(_add_index_type(fd, table+len+(int)row_len, t)) return NULL;
|
if(_add_index_type(fd, table+len+(int)row_len, t)) return NULL;
|
||||||
for(int i = 1; i < (int)row_len; i++) {
|
for(int i = 1; i < (int)row_len; i++) {
|
||||||
t = va_arg(list, type_t);
|
t = va_arg(list, int);
|
||||||
((type_t*)table)[len+i] = t; // 填充 type of row No.i
|
((type_t*)table)[len+i] = t; // 填充 type of row No.i
|
||||||
if(t & EXTYPE_FOREIGNKEY) { // 是外键,还有一个参数
|
if(t & EXTYPE_FOREIGNKEY) { // 是外键,还有一个参数
|
||||||
ptr = va_arg(list, uint64_t);
|
ptr = va_arg(list, uint64_t);
|
||||||
@@ -137,7 +136,26 @@ void* create_table(int fd, char* buf, const char* name, uint16_t row_len, ...) {
|
|||||||
// NULL 失败,详见 errno
|
// NULL 失败,详见 errno
|
||||||
// table 指向表头的指针
|
// table 指向表头的指针
|
||||||
void* load_table(int fd, char* buf, uint64_t ptr) {
|
void* load_table(int fd, char* buf, uint64_t ptr) {
|
||||||
return NULL;
|
uint64_t tmp;
|
||||||
|
int len = 8;
|
||||||
|
putle64(buf, ptr); // this blk ptr
|
||||||
|
if(lseek(fd, ptr+8, SEEK_SET) < 0) return NULL; // skip next table ptr
|
||||||
|
readle16(fd, tmp); // table name length
|
||||||
|
len += 2+(int)tmp;
|
||||||
|
if(lseek(fd, tmp, SEEK_CUR) < 0) return NULL;
|
||||||
|
readle16(fd, tmp); // table row length
|
||||||
|
len += 2+((int)tmp)*(8+1);
|
||||||
|
for(int i = 0; i < (int)tmp; i++) {
|
||||||
|
type_t t;
|
||||||
|
read(fd, &t, 1);
|
||||||
|
if(t&EXTYPE_FOREIGNKEY) { // 外键有额外 ptr 长度
|
||||||
|
len += 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putle16(buf+8, len); // this blk len
|
||||||
|
lseek(fd, ptr, SEEK_SET);
|
||||||
|
if(read(fd, buf+10, len) != len) return NULL;
|
||||||
|
return buf+10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获得表名长度,包含结尾0
|
// 获得表名长度,包含结尾0
|
||||||
@@ -178,7 +196,7 @@ int remove_table_index(int fd, void* table, uint16_t pos) {
|
|||||||
// 返回:
|
// 返回:
|
||||||
// 0 失败,详见 errno
|
// 0 失败,详见 errno
|
||||||
// ptr 本行插入的位置
|
// ptr 本行插入的位置
|
||||||
uint64_t insert_row(int fd, void* table, uint16_t row_len, ...) {
|
uint64_t insert_row(int fd, void* table, int row_len, ...) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +218,7 @@ uint64_t find_row_by_pk(int fd, void* table, key_t k) {
|
|||||||
// 返回:
|
// 返回:
|
||||||
// 非 0 失败,详见 errno
|
// 非 0 失败,详见 errno
|
||||||
// 0 成功
|
// 0 成功
|
||||||
int find_row_by(int fd, void* table, int (*f)(uint64_t), uint16_t row_len, ...) {
|
int find_row_by(int fd, void* table, int (*f)(uint64_t), int row_len, ...) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +239,6 @@ int remove_row_by_pk(int fd, void* table, key_t k) {
|
|||||||
// 返回:
|
// 返回:
|
||||||
// 非 0 失败,详见 errno
|
// 非 0 失败,详见 errno
|
||||||
// 0 成功
|
// 0 成功
|
||||||
int remove_row_by(int fd, void* table, uint16_t row_len, ...) {
|
int remove_row_by(int fd, void* table, int row_len, ...) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ project(fumidb_test VERSION 1.0)
|
|||||||
|
|
||||||
add_executable(binary_test binary_test.c)
|
add_executable(binary_test binary_test.c)
|
||||||
add_executable(page_test page_test.c ../src/page.c ../src/file.c)
|
add_executable(page_test page_test.c ../src/page.c ../src/file.c)
|
||||||
add_executable(types_test types_test.c ../src/types.c ../src/types/int8.c ../src/types/int16.c ../src/page.c ../src/file.c)
|
#add_executable(types_test types_test.c ../src/types.c ../src/types/int8.c ../src/types/int16.c ../src/page.c ../src/file.c)
|
||||||
|
add_executable(table_test table_test.c ../src/table.c ../src/types.c ../src/types/int8.c ../src/types/int16.c ../src/page.c ../src/file.c)
|
||||||
|
|
||||||
add_test(test_binary binary_test COMMAND binary_test)
|
add_test(test_binary binary_test COMMAND binary_test)
|
||||||
add_test(test_page page_test COMMAND page_test)
|
add_test(test_page page_test COMMAND page_test)
|
||||||
add_test(test_types types_test COMMAND types_test)
|
#add_test(test_types types_test COMMAND types_test)
|
||||||
|
add_test(test_table table_test COMMAND table_test)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ int main() {
|
|||||||
perror("create");
|
perror("create");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(init_file_header_page(fd) < 0) return 2;
|
if(init_file_header_page(fd)) return 2;
|
||||||
for(int i = 0; i < 16; i++) {
|
for(int i = 0; i < 16; i++) {
|
||||||
void* page = alloc_page(fd, nullpages[i]);
|
void* page = alloc_page(fd, nullpages[i]);
|
||||||
if(page == NULL) {
|
if(page == NULL) {
|
||||||
|
|||||||
55
tests/table_test.c
Normal file
55
tests/table_test.c
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include "../include/binary.h"
|
||||||
|
#include "../include/file.h"
|
||||||
|
#include "../include/page.h"
|
||||||
|
#include "../include/table.h"
|
||||||
|
#include "../include/types.h"
|
||||||
|
|
||||||
|
char buf[4106];
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int fd = open("table_test_tmp.bin", O_RDWR | O_CREAT | O_TRUNC, 0644);
|
||||||
|
if(fd < 0) {
|
||||||
|
perror("create");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(init_file_header_page(fd)) return 2;
|
||||||
|
void* table = create_table(
|
||||||
|
fd, buf, "test_table", 5,
|
||||||
|
TYPE_INT16|EXTYPE_NONNULL|EXTYPE_UNIQUE,
|
||||||
|
TYPE_INT64,
|
||||||
|
TYPE_INT8,
|
||||||
|
TYPE_STRING,
|
||||||
|
TYPE_BINARY
|
||||||
|
);
|
||||||
|
if(table == NULL) {
|
||||||
|
perror("create_table");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
int len = get_table_name_length(table);
|
||||||
|
if(len != sizeof("test_table")) return 4;
|
||||||
|
char namebuf[len];
|
||||||
|
if(strcmp(get_table_name(table, namebuf), "test_table")) return 5;
|
||||||
|
close(fd);
|
||||||
|
fd = open("table_test_tmp.bin", O_RDWR, 0644);
|
||||||
|
if(fd < 0) {
|
||||||
|
perror("open");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
memset(buf, 0, sizeof(buf));
|
||||||
|
table = load_table(fd, buf, get_first_table(fd));
|
||||||
|
if(table == NULL) {
|
||||||
|
perror("load_table");
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
len = get_table_name_length(table);
|
||||||
|
if(len != sizeof("test_table")) {
|
||||||
|
printf("%d\n", len);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
if(strcmp(get_table_name(table, namebuf), "test_table")) return 5;
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ int main() {
|
|||||||
perror("create");
|
perror("create");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(init_file_header_page(fd) < 0) return 2;
|
if(init_file_header_page(fd)) return 2;
|
||||||
void* index = create_index(fd, TYPE_INT8, buf);
|
void* index = create_index(fd, TYPE_INT8, buf);
|
||||||
if(!index) {
|
if(!index) {
|
||||||
perror("create_int8_index");
|
perror("create_int8_index");
|
||||||
|
|||||||
Reference in New Issue
Block a user