Google Sparse Hash 简介

Google Sparsehash:内存高效哈希表实现
Google Sparsehash 是一个关注空间效率的内存中哈希表库,支持持久化存储。它采用内部探测散列算法,实现常数级查找时间。库中的Key和data通过Union方式存储,节省空间。主要接口包括分配、清除、释放哈希表,查找、插入、删除元素等。此外,还支持哈希表的保存和加载。为了提高性能,可以考虑添加共享内存和淘汰机制。
[url]http://www.open-open.com/lib/view/open1326091425953.html[/url]
Google Sparsehash 包

实现背景:
该包由2种类型和HashTable实现组成。
Sparse 设计的实现过程中考虑的是空间优先;dense 设计上考虑的是时间优先。设计的注重点不一样,所以实现也不一样。为了和通用的STL相适应,每一种实现提供了hash-map和Hash-set2种封装方式。


在使用Hash_map和Hash_set的过程中是不需要安装STL库的,google提供了整个的实现过程。Google在实现的过程中大量使用了模板和泛型编程。

实现特点:
[b]1。这个库提供了内存中Hash tables的一种实现,同时提供了持久化存储的能力。[/b]实现上尽可能快,可移植和小。 实现这些目标使用了Knuth在<<计算机程序设计艺术 第三卷>>中提到的 内部探测散列算法(具体Hash函数的实现可以参考http://burtleburtle.net/bob/hash/evahash 和 http://burtleburtle.net/bob/c/lookup2.c)。与开放链Hash算法不同,它不需要指向每个元素的指针项,在实践中仍然达到了常数级的查找时间。
[b]2.为了节省空间,在插入Hash table的过程中,无论是Key还是data使用Union方式[/b]:如果Key或data很小,就直接存储,否则就存取一个指针。
为了便于存取Key和data,可以使用2个宏 KEY_PTR和PTR_KEY在参数和指针实际所指的数据之间转换比如:

char key[] = "ab", *key2;
HTItem *bck; HashTable *ht;
HashInsert(ht, PTR_KEY(ht, key), 0);
bck = HashFind(ht, PTR_KEY(ht, "ab"));
key2 = KEY_PTR(ht, bck->key);

[color=red][b]主要接口:[/b][/color]
这个Hash table的实现支持的主要接口如下:


[i]1. HashTable *AllocateHashTable(int cchKey, int fSaveKeys) [/i]

功能:分配一个Hashtable的结构并且返回它
参数: cchKey: 为正数时候,表明每个Key是固定长度的;为0表明Key是一个以\0结束的固定长度的字符串。
fSaveKey: 通过是需要调用者分配Key的空间,如果设置为1,会Copy一个Key。

[i]2. ClearHashTable(HashTable *ht) [/i]
功能:移除 hashtable的所有元素;

[i]3. void FreeHashTable(HashTable *ht) [/i]
功能: 释放 hashtable使用的内存

[i]4. HTItem *HashFind(HashTable *ht, ulong key) [/i]
功能:查询Hashtable,找到返回该元素,否则为空;
[i]5. HTItem *HashFindLast(HashTable *ht) [/i]
功能:返回最后查找过的的元素
[i]6 HTItem *HashFindOrInsert(HashTable *ht, ulong key, ulong dataInsert) [/i]
功能:查找指定的Key的元素,不在就插入。

[i]7. HTItem *HashFindOrInsertItem(HashTable *ht, HTItem *pItem) [/i]
功能:插入一个Key/data对,是否覆盖已经存在的元素由 SAMEKEY_OVERWRITE标记设定。

[i]9 HTItem *HashInsert(HashTable *ht, ulong key, ulong data) [/i]
功能: -- 插入 key/data as an HTItem.
[i]10 int HashDelete(HashTable *ht, ulong key) [/i]
功能: -- 移除一个制定Key的元素,成功返回1,否则不存在返回0
[i]11 int HashDeleteLast(HashTable *ht) [/i]
功能: -- 删除最近查询过的元素.

[i]12 HTItem *HashFirstBucket(HashTable *ht) [/i]
功能-- 用来遍历hashtable的桶, 遍历过程中不要做插入和删除操作;
[i]13 HTItem *HashNextBucket(HashTable *ht) [/i]
-- RETURNS NULL at the end of iterating.

[i]14 int HashSetDeltaGoalSize(HashTable *ht, int delta) [/i]
功能:一次性批量插入数据;

[i]15 void HashSave(FILE *fp, HashTable *ht, int (*dataWrite)(FILE *, char *)) [/i]

功能:将整个Hash表的内容保存在文件中。如果数据域是一个指针或者复杂的数据结构,需要传递一个函数指针将文件指针作为参数,此时可以写入你想写入的东西,函数返回写入的字节数。如果数据域是整数,不需要传函数指针。

[i]16 static HashTable *HashDoLoad(FILE *fp, char * (*dataRead)(FILE *, int),
HashTable *ht) [/i]

功能: --装入Hash表. 他需要一个函数来读取一个文件的结构和结构的大小。功能与 HashSave对应。
[i]17 HashTable *HashLoadKeys(FILE *fp, char * (*dataRead)(FILE *, int)) [/i]
功能: -- 与 HashLoad(),不同 只有必要的时候才从磁盘Load相应的数据.这种方法可以节省内存 。
注意:在装入数据的时候不应该插入和删除数据。


功能扩展:

这个HashTable实现没有使用共享内存的方式,我们可以对AllocateHashTable进行简单改写使用共享内存的方式;另外这个 Hashtable没有提供自动淘汰节点的功能,可以增加LRU,对访问节点的计数和时间统计,在无法继续插入新的节点时候触发淘汰操作。
在 Java 中,`Hashtable` 是一个线程安全的哈希表实现,它存储键值对(Key-Value Pair),不允许使用 `null` 作为键或值。它是 Java 集合框架中的一部分,位于 `java.util` 包中。 `HashMap` 不同,`Hashtable` 是线程安全的,适用于多线程环境。 ### 示例代码:使用 Java Hashtable 以下是一个使用 `Hashtable` 的完整示例: ```java import java.util.Hashtable; import java.util.Enumeration; import java.util.Set; import java.util.Iterator; public class HashtableExample { public static void main(String[] args) { // 创建一个 Hashtable 实例 Hashtable<String, Integer> table = new Hashtable<>(); // 添加键值对 table.put("Apple", 10); table.put("Banana", 20); table.put("Orange", 30); table.put("Grapes", 40); // 获取值 System.out.println("Value for key 'Apple': " + table.get("Apple")); // 遍历 Hashtable 使用 Enumeration(旧版方式) System.out.println("\nUsing Enumeration:"); Enumeration<String> keys = table.keys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); System.out.println("Key: " + key + ", Value: " + table.get(key)); } // 遍历 Hashtable 使用 Iterator(推荐方式) System.out.println("\nUsing Iterator:"); Set<String> keySet = table.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); System.out.println("Key: " + key + ", Value: " + table.get(key)); } // 检查是否包含某个键或值 System.out.println("\nContains Key 'Banana': " + table.containsKey("Banana")); System.out.println("Contains Value 30: " + table.containsValue(30)); // 删除某个键值对 table.remove("Orange"); System.out.println("\nAfter removing 'Orange': " + table); // 获取 Hashtable 大小 System.out.println("Size of Hashtable: " + table.size()); // 清空 Hashtable table.clear(); System.out.println("After clearing: " + table); } } ``` ### 解释 1. **创建 `Hashtable` 实例:** ```java Hashtable<String, Integer> table = new Hashtable<>(); ``` 这行代码创建了一个键为 `String` 类型、值为 `Integer` 类型的哈希表。 2. **添加键值对:** ```java table.put("Apple", 10); ``` 使用 `put(K key, V value)` 方法将键值对插入到 `Hashtable` 中。 3. **获取值:** ```java table.get("Apple"); ``` 使用 `get(Object key)` 方法获取指定键对应的值。 4. **遍历 `Hashtable`:** - 使用 `Enumeration`: ```java Enumeration<String> keys = table.keys(); ``` 通过 `keys()` 方法获得键的枚举,然后遍历。 - 使用 `Iterator`: ```java Set<String> keySet = table.keySet(); Iterator<String> iterator = keySet.iterator(); ``` 通过 `keySet()` 方法获取键的集合,然后使用 `Iterator` 遍历。 5. **检查键或值是否存在:** ```java table.containsKey("Banana"); table.containsValue(30); ``` 6. **删除键值对:** ```java table.remove("Orange"); ``` 7. **清空和获取大小:** ```java table.clear(); table.size(); ``` --- ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值