diff --git a/README.md b/README.md index 1283dfa..20b88fd 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ A simple and lightweight database written in C Most part of this README and the docs in `api` folder is written in Chinese. If you want to use it but have any problem in language, please contact me directly through the issues. ## 支持的功能 -- [ ] 创建[数据库文件](/api/dbfile.md#数据库文件格式)和[表](/api/dbfile.md#新建表) -- [ ] [删除表](/api/dbfile.md#删除表) -- [ ] [插入表项](/api/table.md#表项) -- [ ] [删除表项](/api/table.md#表项) +- [ ] 创建[数据库文件](/api/dbfile.md#数据库文件格式)和[表](/api/dbfile.md#表) +- [ ] 删除表 - [ ] 对主键、外键进行[索引](/api/index.md) +- [ ] [插入表项](/api/table.md#表项的增加) +- [ ] 按索引修改表项 +- [ ] 按索引[删除表项](/api/table.md#表项的删除) - [ ] 对非主键(无[unique约束](/api/types.md#类型修饰符))进行[索引](/api/index.md) -- [ ] 修改表项 ## Thanks - [asciiflow](https://asciiflow.com/) \ No newline at end of file diff --git a/api/dbfile.md b/api/dbfile.md index 96e7adc..6686cda 100644 --- a/api/dbfile.md +++ b/api/dbfile.md @@ -1,15 +1,23 @@ # 数据库文件格式 +> `fumidb`的数据库文件扩展名一般为`.fdb`,不做强制要求 + 由于文件内普遍以uint64作为指针,因此理论最大支持文件大小为`16384PB`,在现有条件下完全足够使用。 ## 文件头 -对于未被使用的对齐部分,其开头将有一个8字节指针指向下一块未被使用的对齐部分,没有则置0;接下来紧跟着uint16的数字,指示了本块未被使用的对齐部分的长度。因此,能加入链表的未被使用的对齐部分最短应为10字节,小于这个长度的未被使用部分将不再使用。 +文件最开头填充了固定的8字节ascii编码`FUMIDB\1\0`。前6字节必须为`FUMIDB`,表明本文件为`fumidb`数据库文件格式。7, 8字节`\1\0`作为数据库的版本,是一个小端的uint16,在这里表示第1版,之后将依次递增。今后可能会在文件头增加更多字段,由于其后的`ptr of first table`不一定要求其指向的第一个表头紧跟文件头,字段的增加将不影响之前版本的解析。在目前实现时,为`possible other header data`空出16字节。 ``` 0 8 16 ┌───────────────────┬───────────────────┐ -│ ptr of unused blk │ ptr of next table │ +│ FUMIDB\1\0 │ ptr of unused blk │ +├───────────────────┼───────────────────┤ +│ ptr of first table│ ptr of next table │ ├───────────────────┴───────────────────┤ +│ possible other header data │ +├───────────────────────────────────────┤ │ first table head │ ├───────────────────────────────────────┤ │ ...... ...... ...... │ +├───────────────────────────────────────┤ +│ some possible padding to fit 4096Byte │ ├───────────────────┬───────────────────┤ │ ptr of next table │ second table head │ ├───────────────────┴───────────────────┤ @@ -20,9 +28,19 @@ │ data blocks ... │ └───────────────────────────────────────┘ ``` -### 新建表 -在新建表时将计算表头大小,优先选取一块未被使用的足够大的对齐部分写入表头。当找不到时,在文件末尾附加表头(并留出新的对齐)。接下来将上一个表头开头的`下一个表头的指针`指向新表头的开头,然后建立相应数据结构,填充表头字段。 -### 修改表 +### 空闲块 +#### 链表格式 +对于空闲块,其开头将有一个8字节指针指向下一块空闲块,没有则置0。第一块未被使用的空闲块的指针被记录在文在最开头的`ptr of unused blk`,同样,没有则置0。对于除了文件头之外的每个空闲块指针,在指针之后紧跟一个uint16的数字,指示了本块空闲块的长度(以字节为单位),该长度包括指针和数字。因此,能加入链表的空闲块最短应为10字节,小于这个长度的未被使用部分将不再使用。 +#### 新建 +空闲块不会被主动新建,而是源于分配时富余的部分以及删除后的剩余。 +#### 合并 +受限于记录长度的数字为uint16,一块未被使用的空闲空间大小最大为`65535`,一般则不使其超过`32768`。如果确有连续的超过`32768`字节的空闲,应当划分为多个块。特别地,如果确有连续的超过`32768`字节的空闲且其后的空间不足`4096`字节,应当适当减小前一块的大小,使后一块大小超过`4096`字节。 +#### 使用 +使用时优先从第一个块遍历,比较其大小以及页对齐是否符合要求。当使用后仍有剩余,对于小于10字节的块,直接舍弃不用;否则更新块大小与相关链表指针。 +### 表 +### 新建 +在新建表时将计算表头大小,优先选取一块未被使用的足够大的对齐部分写入表头。当找不到时,在文件末尾附加表头(留出新的对齐)。接下来将上一个表头开头的`下一个表头的指针`指向新表头的开头,然后建立相应数据结构,填充表头字段。 +### 修改 一旦创建数据表,将不支持修改。可以先删除表再重新创建,但这样数据将会丢失。 -### 删除表 -根据表头遍历所有表项,回收空间到未被使用的对齐部分,然后再回收表头,更新表头链表的指针,完成删除。 \ No newline at end of file +### 删除 +根据表头遍历所有表项,回收空间到空闲块,然后再回收表头,更新表头链表的指针,完成删除。 \ No newline at end of file diff --git a/api/index.md b/api/index.md index 2df4cbc..469fdee 100644 --- a/api/index.md +++ b/api/index.md @@ -41,7 +41,7 @@ ``` ## int32/float -使用B+树建立索引,每个节点大小为`4088`字节,可对齐到`4096`字节以方便`mmap`,最多可有`n=341`个扇出,`340`个值;最少则有`170`个值(根节点不遵守最少值规则)。 +使用B+树建立索引,每个节点大小为`4096`字节,最多可有`n=341`个扇出,`340`个值;最少则有`170`个值(根节点不遵守最少值规则)。 > 下面每格4字节 ``` 0 8 12 20 @@ -56,12 +56,12 @@ ├───────────────────┼─────────┼───────────────────┼─────────┤ 4056│ pointer 339 │ key 339 │ pointer 340 │ key 340 │ ├───────────────────┼─────────┴─────────┬─────────┴─────────┘ -4080│ pointer 341 │ unused field │ +4080│ pointer 341 │ next node ptr │ └───────────────────┴───────────────────┘ 4088 4096 ``` ## int64/double -使用B+树建立索引,每个节点大小为`4088`字节,可对齐到`4096`字节以方便`mmap`,最多可有`n=256`个扇出,`255`个值;最少则有`128`个值(根节点不遵守最少值规则)。 +使用B+树建立索引,每个节点大小为`4096`字节,最多可有`n=256`个扇出,`255`个值;最少则有`128`个值(根节点不遵守最少值规则)。 > 下面每格8字节 ``` 0 8 @@ -76,7 +76,7 @@ ├───────────────────┼───────────────────┤ 4064│ pointer 255 │ key 255 │ ├───────────────────┼───────────────────┤ -4080│ pointer 256 │ unused field │ +4080│ pointer 256 │ next node ptr │ └───────────────────┴───────────────────┘ 4088 4096 ``` diff --git a/api/table.md b/api/table.md index 0097abb..b1a6662 100644 --- a/api/table.md +++ b/api/table.md @@ -38,4 +38,4 @@ #### 表项的增加 优先附加到上一个表项末尾。如无法实现,则从空区块选取一个,或附加到整个文件末尾。 #### 表项的删除 -需要更新[未被使用的对齐部分](/api/dbfile.md#文件头) \ No newline at end of file +需要更新[未被使用的对齐部分](/api/dbfile.md#空闲块) \ No newline at end of file