1
0
mirror of https://github.com/fumiama/fumidb.git synced 2026-06-05 00:32:44 +08:00

半完成bucket

This commit is contained in:
源文雨
2022-10-09 00:49:35 +08:00
parent 18513f6e6f
commit 2dd269b364
4 changed files with 153 additions and 5 deletions

View File

@@ -50,8 +50,8 @@
## int32/float
> 查找速度为O(logn)
使用B+树建立索引,每个节点大小为`4096`字节,最多可有`n=341`个扇出,`340`个值;最少则有`170`个值(根节点不遵守最少值规则)。
> 下面每格4字节
- 使用B+树建立索引,每个节点大小为`4096`字节,最多可有`n=341`个扇出,`340`个值;最少则有`170`个值(根节点不遵守最少值规则)。
> 下面每格4字节, next node ptr 将所有块连接起来以便全部遍历(如删除)。
```
0 8 12 20
┌───────────────────┬─────────┬───────────────────┬─────────┐
@@ -69,11 +69,31 @@
└───────────────────┴───────────────────┘
4088 4096
```
> 备选方案
- 使用哈希桶作索引,允许溢出桶,同样每个桶大小为`4096`字节,可装`340`个值。共`256`个桶,初始占用`1M`空间,后续由于溢出可能会增加。
```
0 8 12 20
┌───────────────────┬─────────┬───────────────────┬─────────┐
0│ pointer 001 │ key 001 │ pointer 002 │ key 002 │
├───────────────────┼─────────┼───────────────────┼─────────┤
24│ pointer 003 │ key 003 │ pointer 004 │ key 004 │
├───────────────────┼─────────┼───────────────────┼─────────┤
48│ pointer 005 │ key 005 │ pointer 006 │ key 006 │
├───────────────────┼─────────┼───────────────────┼─────────┤
xxx│ pointer xxx │ key xxx │ pointer xxx │ key xxx │
├───────────────────┼─────────┼───────────────────┼─────────┤
4056│ pointer 339 │ key 339 │ pointer 340 │ key 340 │
├───────────────────┼─────────┴─────────┬─────────┴─────────┘
4080│ overflow ptr │ next node ptr │
└───────────────────┴───────────────────┘
4088 4096
```
## int64/double
> 查找速度为O(logn)
使用B+树建立索引,每个节点大小为`4096`字节,最多可有`n=256`个扇出,`255`个值;最少则有`128`个值(根节点不遵守最少值规则)。
> 下面每格8字节
- 使用B+树建立索引,每个节点大小为`4096`字节,最多可有`n=256`个扇出,`255`个值;最少则有`128`个值(根节点不遵守最少值规则)。
> 下面每格8字节, next node ptr 将所有块连接起来以便全部遍历(如删除)。
```
0 8
┌───────────────────┬───────────────────┐
@@ -91,7 +111,27 @@
└───────────────────┴───────────────────┘
4088 4096
```
> 备选方案
- 使用哈希桶作索引,允许溢出桶,同样每个桶大小为`4096`字节,可装`255`个值。共`1024`个桶,初始占用`4M`空间,后续由于溢出可能会增加。
```
0 8
┌───────────────────┬───────────────────┐
0│ pointer 001 │ key 001 │
├───────────────────┼───────────────────┤
16│ pointer 002 │ key 002 │
├───────────────────┼───────────────────┤
32│ pointer 003 │ key 003 │
├───────────────────┼───────────────────┤
xxx│ pointer xxx │ key xxx │
├───────────────────┼───────────────────┤
4064│ pointer 255 │ key 255 │
├───────────────────┼───────────────────┤
4080│ overflow ptr │ next node ptr │
└───────────────────┴───────────────────┘
4088 4096
```
## string
> 查找速度为O(logn)
先将其哈希为int64再按int64进行查找。具体哈希方法为取字符串`md5`的前8位作为小`uint64`。冲突时根据string表项附带存储的[下一个哈希相同的数据项的指针(uint64)](/api/types.md#字符串)可依次遍历到所有项目,然后找到真正与查询内容相同的项。
先将其哈希为int64再按int64进行查找。具体哈希方法为取字符串`md5`的前8位作为小`uint64`。冲突时根据string表项附带存储的[下一个哈希相同的数据项的指针(uint64)](/api/types.md#字符串)可依次遍历到所有项目,然后找到真正与查询内容相同的项。

View File

@@ -5,6 +5,10 @@
#include <stdint.h>
#include <stdlib.h>
#ifndef __null
# define __null 0
#endif
#ifdef __linux__
# include <endian.h>
#endif

26
include/types/int32.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef _TYPE_INT32_H_
#define _TYPE_INT32_H_
#include <stdint.h>
#include "../types.h"
#define INT32_BUCKET_SZ (256)
#define INT32_INDEX_SZ ((INT32_BUCKET_SZ+1)*(PAGESZ+8))
// len(buf) >= INT32_INDEX_SZ = (PAGESZ+8)*(256+1) = 4104*257 = 1054728 (1M)
// 256个哈希桶, 多出来一个是机动空间, 用于加载溢出桶
void* create_int32_index(int fd, void* buf);
void* load_int32_index(int fd, uint64_t ptr, void* buf);
int remove_int32_index(int fd, void* index);
uint64_t count_int32_items(int fd, void* index);
int insert_int32_item(int fd, void* index, key_t k, uint64_t ptr);
uint64_t find_item_by_int32_key(int fd, void* index, key_t k);
uint64_t remove_item_by_int32_key(int fd, void* index, key_t k);
#endif

78
src/types/int32.c Normal file
View File

@@ -0,0 +1,78 @@
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../../include/binary.h"
#include "../../include/page.h"
#include "../../include/types/int32.h"
void* create_int32_index(int fd, void* buf) {
void* page = alloc_page(fd, buf);
if(unlikely(page == NULL)) return NULL;
memset(page, 0, PAGESZ);
void* prev_page = page;
for(int i = 1; i < INT32_BUCKET_SZ; i++) {
page = alloc_page(fd, buf);
if(unlikely(page == NULL)) {
for(int j = 0; j < i; j++) free_page(fd, buf+j*(PAGESZ+8)+8);
return NULL;
}
memset(page, 0, PAGESZ);
putle64(prev_page+PAGESZ-8, le64(page-8));
if(unlikely(sync_page(fd, prev_page))) {
free_page(fd, page);
for(int j = 0; j < i; j++) free_page(fd, buf+j*(PAGESZ+8)+8);
return NULL;
}
prev_page = page;
}
if(unlikely(sync_page(fd, page))) {
free_page(fd, page);
for(int i = 0; i < INT32_BUCKET_SZ; i++) free_page(fd, buf+i*(PAGESZ+8)+8);
return NULL;
}
return buf+8;
}
void* load_int32_index(int fd, uint64_t ptr, void* buf) {
void* page = get_page(fd, ptr, buf);
if(unlikely(page == NULL)) return NULL;
for(int i = 1; i < INT32_BUCKET_SZ-1; i++) {
page = get_page(fd, le64(page+PAGESZ-8), buf+i*(PAGESZ+8));
if(unlikely(page == NULL)) return NULL;
}
return buf+8;
}
int remove_int32_index(int fd, void* index) {
for(int i = 0; i < INT32_BUCKET_SZ; i++) {
void* page = index+i*(PAGESZ+8);
uint64_t ptr = le64(page+PAGESZ-16);
while(unlikely(ptr)) {
void* p = get_page(fd, ptr, index+INT32_INDEX_SZ-BUFSIZ-8);
if(unlikely(p == NULL)) return EOF;
ptr = le64(p+PAGESZ-16);
if(unlikely(free_page(fd, p))) return EOF;
}
if(unlikely(free_page(fd, page))) return EOF;
}
}
uint64_t count_int32_items(int fd, void* index) {
}
int insert_int32_item(int fd, void* index, key_t k, uint64_t ptr) {
}
uint64_t find_item_by_int32_key(int fd, void* index, key_t k) {
}
uint64_t remove_item_by_int32_key(int fd, void* index, key_t k) {
}