mirror of
https://github.com/fumiama/fumidb.git
synced 2026-06-06 09:10:32 +08:00
add more api
This commit is contained in:
@@ -15,18 +15,18 @@
|
||||
| 5 | double | 直接存储 |
|
||||
|
||||
## 字符串
|
||||
> 字符串为变长的可索引的字节数组,长度最大不超过uint32(65535字节)。
|
||||
> 字符串为变长的可索引的字节数组,长度最大不超过uint16(65535字节)。
|
||||
### 类型列表
|
||||
| 类型代号 | 类型 | 存储方式 |
|
||||
| --- | --- | --- |
|
||||
| 6 | string | 下一个哈希相同的数据项的指针+uint32长度+该长度的数据(字节数组) |
|
||||
| 6 | string | 下一个哈希相同的数据项的指针+uint16长度+该长度的数据(字节数组) |
|
||||
|
||||
## 二进制数据块
|
||||
> 二进制数据块为变长的不参与索引的字节数组,长度最大不超过uint64。
|
||||
> 二进制数据块为变长的不参与索引的字节数组,长度最大不超过uint32。
|
||||
### 类型列表
|
||||
| 类型代号 | 类型 | 存储方式 |
|
||||
| --- | --- | --- |
|
||||
| 7 | binary | uint64长度+直接存储的数据(字节数组) |
|
||||
| 7 | binary | uint32长度+直接存储的数据(字节数组) |
|
||||
|
||||
## 类型修饰符
|
||||
> 类型修饰符占据类型代号的高2位,通过或运算与基础代号结合
|
||||
|
||||
@@ -16,8 +16,8 @@ void* create_table(int fd, char* buf, const char* name, int row_len, ...);
|
||||
// 加载 ptr 位置的表
|
||||
// len(buf) >= 4096+8+2=4106
|
||||
// 返回:
|
||||
// NULL 失败,详见 errno
|
||||
// table 指向表头的指针
|
||||
// 0 失败,详见 errno
|
||||
// ptr 指向表头的指针
|
||||
void* load_table(int fd, char* buf, uint64_t ptr);
|
||||
|
||||
// 获得表名长度,包含结尾0
|
||||
@@ -27,11 +27,14 @@ uint16_t get_table_name_length(void* table);
|
||||
// 返回:buf
|
||||
char* get_table_name(void* table, char* buf);
|
||||
|
||||
// 获得第 pos 项的索引 ptr
|
||||
uint64_t get_index_ptr(void* table, uint16_t pos);
|
||||
|
||||
// 为 pos 位置的列创建索引。不可用于 0 列,即 pk 列,因为 pk 必有索引
|
||||
// 返回:
|
||||
// NULL 失败,详见 errno
|
||||
// index 指向索引头的指针
|
||||
void* add_table_index(int fd, void* table, uint16_t pos);
|
||||
// NULL 失败,详见 errno
|
||||
// ptr 指向索引头的指针
|
||||
uint64_t add_table_index(int fd, void* table, uint16_t pos);
|
||||
|
||||
// 删除 pos 位置的列的索引。不可用于 0 列,即 pk 列,因为 pk 必有索引
|
||||
// 返回:
|
||||
@@ -44,6 +47,10 @@ int remove_table_index(int fd, void* table, uint16_t pos);
|
||||
// 加一个 int isavailable,标记本项是否有值
|
||||
// 如果 isavailable==0,后面不再跟有本项数据
|
||||
// 如果 isavailable!=0,则在后面附加数据
|
||||
// 如果 val 不为 string,直接装填其值
|
||||
// 否则,值是指向 string 的指针 (const char*)
|
||||
// 如果是 binary,需要在指针之前提供一个 uint32 参数
|
||||
// 说明 binary 的大小
|
||||
// 返回:
|
||||
// 0 失败,详见 errno
|
||||
// ptr 本行插入的位置
|
||||
|
||||
11
src/page.c
11
src/page.c
@@ -326,13 +326,20 @@ int add_block(int fd, uint16_t size, uint64_t off) {
|
||||
lseek(fd, prev_ptr, SEEK_SET);
|
||||
putle64(buf, off);
|
||||
if(write(fd, buf, 8) != 8) return EOF; // 将本页附加到链表
|
||||
#ifdef DEBUG
|
||||
printf("add blk: %016llx, next ptr: %016llx, size: %d\n", off, ptr, size);
|
||||
#endif
|
||||
readle16(fd, sz);
|
||||
putle16(buf, sz);
|
||||
if(prev_ptr+sz == off && prev_ptr%PAGESZ < off%PAGESZ) { // 可以和前一块合并
|
||||
lseek(fd, prev_ptr, SEEK_SET);
|
||||
putle64(buf, ptr);
|
||||
write(fd, buf, 8);
|
||||
putle16(buf, size+sz);
|
||||
write(fd, buf, 2);
|
||||
#ifdef DEBUG
|
||||
printf("merge front: %016llx, size: %d\n", ptr, size+sz);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if(off+size == ptr && off%PAGESZ < ptr%PAGESZ) { // 可以和后一块合并
|
||||
@@ -344,6 +351,10 @@ int add_block(int fd, uint16_t size, uint64_t off) {
|
||||
write(fd, buf, 8);
|
||||
putle16(buf, size+sz);
|
||||
write(fd, buf, 2);
|
||||
#ifdef DEBUG
|
||||
printf("merge rear: %016llx, size: %d\n", prev_ptr, size+sz);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
88
src/table.c
88
src/table.c
@@ -44,11 +44,37 @@ static int _add_index_type(int fd, uint64_t* index_ptr, type_t t) {
|
||||
void* buf = malloc(sz);
|
||||
if(buf == NULL) return 1;
|
||||
void* index = create_index(fd, t, buf);
|
||||
if(index == NULL) {
|
||||
free(buf);
|
||||
return 2;
|
||||
}
|
||||
*index_ptr = le64(buf);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 移除 t 类型索引
|
||||
// 返回:
|
||||
// 1 失败,详见 errno
|
||||
// 0 成功
|
||||
static int _remove_index_type(int fd, type_t t, uint64_t ptr) {
|
||||
int sz = _calc_index_size(t);
|
||||
if(sz <= 0) {
|
||||
errno = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
void* buf = malloc(sz);
|
||||
if(buf == NULL) return 1;
|
||||
void* index = load_index(fd, t, ptr, buf);
|
||||
if(index == NULL) {
|
||||
free(buf);
|
||||
return 2;
|
||||
}
|
||||
sz = remove_index(fd, t, index);
|
||||
free(buf);
|
||||
return sz;
|
||||
}
|
||||
|
||||
// 创建表,可变参数为本表的一行的 types,详见 types.h
|
||||
// 如果 types 为外键,需要紧跟一个 uint64_t ptr
|
||||
// 指示外键链接到的表位置
|
||||
@@ -127,6 +153,9 @@ void* create_table(int fd, char* buf, const char* name, int row_len, ...) {
|
||||
// 将 page 变为 block
|
||||
putle64(buf, ptr);
|
||||
putle16(buf+8, len);
|
||||
#ifdef DEBUG
|
||||
printf("create len: %d\n", len);
|
||||
#endif
|
||||
return buf+10;
|
||||
}
|
||||
|
||||
@@ -155,6 +184,9 @@ void* load_table(int fd, char* buf, uint64_t ptr) {
|
||||
putle16(buf+8, len); // this blk len
|
||||
lseek(fd, ptr, SEEK_SET);
|
||||
if(read(fd, buf+10, len) != len) return NULL;
|
||||
#ifdef DEBUG
|
||||
printf("load len: %d\n", len);
|
||||
#endif
|
||||
return buf+10;
|
||||
}
|
||||
|
||||
@@ -172,12 +204,41 @@ char* get_table_name(void* table, char* buf) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
uint64_t get_index_ptr(void* table, uint16_t pos) {
|
||||
int len = 8+2+le16(table+8);
|
||||
uint16_t rlen = le16(table+len);
|
||||
if(pos >= rlen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
len += 2;
|
||||
type_t t = ((type_t*)table)[len+(int)pos];
|
||||
len += (int)rlen+(int)pos*8;
|
||||
return *(uint64_t*)(table+len);
|
||||
}
|
||||
|
||||
// 为 pos 位置的列创建索引。不可用于 0 列,即 pk 列,因为 pk 必有索引
|
||||
// 返回:
|
||||
// NULL 失败,详见 errno
|
||||
// index 指向索引头的指针
|
||||
void* add_table_index(int fd, void* table, uint16_t pos) {
|
||||
return NULL;
|
||||
// 0 失败,详见 errno
|
||||
// ptr 指向索引头的指针
|
||||
uint64_t add_table_index(int fd, void* table, uint16_t pos) {
|
||||
if(!pos) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
int len = 8+2+le16(table+8);
|
||||
uint16_t rlen = le16(table+len);
|
||||
if(pos >= rlen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
len += 2;
|
||||
type_t t = ((type_t*)table)[len+(int)pos];
|
||||
len += (int)rlen+(int)pos*8;
|
||||
if(*(uint64_t*)(table+len)) return *(uint64_t*)(table+len); // 已经有索引
|
||||
if(_add_index_type(fd, table+len, t)) return 0;
|
||||
if(sync_block(fd, table)) return 0;
|
||||
return *(uint64_t*)(table+len);
|
||||
}
|
||||
|
||||
// 删除 pos 位置的列的索引。不可用于 0 列,即 pk 列,因为 pk 必有索引
|
||||
@@ -185,7 +246,24 @@ void* add_table_index(int fd, void* table, uint16_t pos) {
|
||||
// 非 0 失败,详见 errno
|
||||
// 0 成功
|
||||
int remove_table_index(int fd, void* table, uint16_t pos) {
|
||||
return 0;
|
||||
if(!pos) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
int len = 8+2+le16(table+8);
|
||||
uint16_t rlen = le16(table+len);
|
||||
if(pos >= rlen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
len += 2;
|
||||
type_t t = ((type_t*)table)[len+(int)pos];
|
||||
len += (int)rlen+(int)pos*8;
|
||||
uint64_t ptr = *(uint64_t*)(table+len);
|
||||
if(ptr == 0) return 0; // 没有索引
|
||||
*(uint64_t*)(table+len) = 0; // 清除
|
||||
_remove_index_type(fd, t, ptr);
|
||||
return sync_block(fd, table);
|
||||
}
|
||||
|
||||
// 插入一行,如果 pk 有值则替换
|
||||
|
||||
@@ -3,10 +3,10 @@ project(fumidb_test VERSION 1.0)
|
||||
|
||||
add_executable(binary_test binary_test.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_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)
|
||||
|
||||
@@ -51,5 +51,6 @@ int main() {
|
||||
return 4;
|
||||
}
|
||||
if(strcmp(get_table_name(table, namebuf), "test_table")) return 5;
|
||||
if(get_index_ptr(table, 0) != 0x100) return 6;
|
||||
close(fd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user