mirror of
https://github.com/fumiama/fumidb.git
synced 2026-06-05 00:32:44 +08:00
半完成bucket
This commit is contained in:
50
api/index.md
50
api/index.md
@@ -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#字符串)可依次遍历到所有项目,然后找到真正与查询内容相同的项。
|
||||
|
||||
@@ -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
26
include/types/int32.h
Normal 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
78
src/types/int32.c
Normal 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) {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user