基于磁盘的哈希表

diskhash的Python项目详细描述


#基于磁盘的哈希表

[![特拉维斯](https://api.travis ci.org/luispedro/diskhash.png)(https://travis ci.org/luispedro/diskhash)
[![许可证:mit](https://img.shields.io/badge/license mit blue.svg)(https://opensource.org/licenses/mit)



>一个简单的基于磁盘的哈希表(即持久哈希表)。

因此,它可以用一个"MMAP()"系统调用装入
,并直接在内存中使用(一旦它从磁盘加载到内存中的哈希表中就快了)。
BR/>代码在C中,为Python、Haskell和C++提供了包装器。
包装器遵循类似的api,并带有各种变体,以适应语言的特殊性。它们都使用相同的底层代码,因此您可以打开在c中从haskell创建的hashtable
,在haskell代码中修改它,然后在python中打开
结果(尽管python的版本目前只处理
整数,存储为长文件)。

使用多个线程(不同的进程将共享内存:操作系统为您这样做)。但是,写入或修改
值不是线程安全的。

在当前的api中,需要预先指定键的
最大大小值,即下面的值"15 `



<
<<
35

`` c
` include<;stdio.h>;
;include<;inttypes.h>;
include"diskhash.h"




int main main(void)
hashtablopts-hashtablopts.hashtablopts.选择;
opts.key_maxlen=15;
opts.object_datalen=sizeof(int64_t);
char*err=null;
hashtable*ht=dht_open("testing.dht",opts,o_rdwr o_create,&err);
如果(!ht){
如果(!err)err="未知错误";
fprintf(stderr,"打开哈希表失败:%s.\n",err);
return 1;
}
long i=9;
dht_insert(ht,"key"&;i);

long*val=(long*)dht_lookup(ht,"key");
printf("查找值:%l\n",*val);

dht_free(ht);
返回0;
}
`````

对于读写和只读的哈希表,您有不同的类型/函数。


读写示例:

``haskell
导入数据。diskhash
导入数据。int
main=do
ht<;-htopenrw"testing.dht"15
htinsertrw ht"key"(9::int64)
val<;-htlookuprw"key"ht
print val
```

>只读示例(在本例中,"htlookupro"是纯示例):

```haskell
导入数据。diskhash
导入数据。int
main=do
ht<;-htopenro"testing.dht"15
让val::int64
val=htlookupo"key"ht
打印val
````


例如,`'ll`
指的是一对64位int(_long廑):

``python
import diskhash
tb=diskhash.structhash("testing.dht",15,"ll","rw")
tb.insert("key",1,2)
print(tb.lookup("key"))
````

python接口目前仅限python 3。将补丁扩展到2.7
是受欢迎的,但不是优先事项。
BR/> BR/> BR/> C++中定义了一个简单的包装器,它提供了一种类型的安全性。另外,STD:BADYOLCUC和STD:RunTimeOrthError可以被抛出,并且
不返回代码。string>;

包含<;diskhash.hpp>;

const int key_maxlen=15;
dht::diskhash<;uint64_t>;ht("testing.dht",key_maxlen,dht::dhopenrw);
std::string line;
uint64_t ix=0;
而(std::getline(std::cine,line)){
if(line.length()>;key_maxlen){
std::cerr<;<;"key too long:'"<;<;line<;"。正在中止。\n";
返回2;
}
const bool inserted=ht.insert(line.c_str(),ix);
如果(!插入){
std::cerr<;<;"找到重复键"<;<;line<;<;"'(忽略);
}
+++ix;
}
}
return 0;
}
`````

我使用它已经足够好了,但是api在未来可以在没有任何警告的情况下进行
更改。二进制格式是版本控制的(魔术字符串对其版本进行编码,因此可以检测到更改,并且您将在将来收到错误消息,而不是一些无声的错误行为。

[自动单元测试](https://travis-ci.org/luispedro/diskhash)确保了
基本错误不会不注意。

这可以通过对密钥进行预哈希(使用强哈希)或对不同的密钥大小使用多个哈希表来解决。当前在diskhash中两者都没有实现。

-不能删除对象。这不是我使用的必需品,因此它没有实现。一个简单的实现可以通过将对象标记为
"deleted"并在哈希表大小更改时重新压缩或使用
显式的"dht_gc()"调用来完成。为
缩小哈希表添加功能以避免浪费磁盘空间也很重要。

-该算法是线性寻址的一种相当简单的实现。切换到[robin hood
哈希(https://www.sebastiansylvan.com/post/robin hood哈希应该是默认的哈希表实现)
并不难,而且这确实可能在不久的将来发生。

license:mit

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java使用split函数分割字符串,但没有得到期望的结果   未找到包含derby数据库嵌入架构的sql Java桌面应用程序错误   java elasticsearch vs solr用于定制全文搜索系统   java Android:创建没有startOffset的动画延迟?   java如何查看其他应用程序接收的数据?   java如何在Linux中使用D和classpath选项运行jar文件   java和域设计最佳实践   具有相同内存位置的java数组,将显示为输出   连接到java中的elasticsearch?   Java Playframework重定向到带有Json负载的外部url   java无法在Android平台上使用InputStream为蓝牙socket创建ObjectInputStream   使用POI将Excel日期转换为Java日期,年份未正确显示   oracle从数据库层还是Java层调用webservice?