Memcached里的Hashmap实现是一个简单的链式存储方式,简单记录一下
链式hashmap的结构比较简单,基本上可以理解为一个一维线性空间,每个空间称作一个bucket,每个bucket又是一个链表结构,这个链表结构上的所有元素的key的hash值是相同的,所以被分配在一个bucket里。
hashmap存储时首先根据key计算hash得到对应bucket,然后加入该bucket中的链表首部
hashmap查询时也是通过key计算hash得到对应bucket,然后遍历链表查找对应元素
所以hashmap的关键是hash的算法是否可以尽可能的减小不同key值计算出相同hash的概率(减小冲突),如果所有的key的hash均相同,那么hashmap也就变成了List结构了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned long int ub4; /* unsigned 4-byte quantities */
typedef unsigned char ub1; /* unsigned 1-byte quantities */
/* hard-code one million buckets, for now (2**20 == 4MB hash) */
#define HASHPOWER 20 // 1<<20 = buckets 的总数
#define hashsize(n) ((ub4)1<<(n))
#define hashmask(n) (hashsize(n)-1) // 防止hash值超过buckets总长度
#define mix(a,b,c) \
{ \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<<8); \
c -= a; c -= b; c ^= (b>>13); \
a -= b; a -= c; a ^= (c>>12); \
b -= c; b -= a; b ^= (a<<16); \
c -= a; c -= b; c ^= (b>>5); \
a -= b; a -= c; a ^= (c>>3); \
b -= c; b -= a; b ^= (a<<10); \
c -= a; c -= b; c ^= (b>>15); \
}
//测试用的一个item
typedef struct _item{
struct _item *next;
char *key;
char *value;
}item;
//最重要的算法部分
ub4 hash( k, length, initval)
register ub1 *k; /* the key */
register ub4 length; /* the length of the key */
register ub4 initval; /* the previous hash, or an arbitrary value */
{
register ub4 a,b,c,len;
/* Set up the internal state */
len = length;
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
c = initval; /* the previous hash value */
/*------------------------------------ handle most of the key*/
while (len >= 12)
{
a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
mix(a,b,c);
k += 12; len -= 12;
}
/*------------------------------------- handle the last 11 bytes*/
c += length;
switch(len) /* all the case statements fall through*/
{
case 11: c+=((ub4)k[10]<<24);
case 10: c+=((ub4)k[9]<<16);
case 9 : c+=((ub4)k[8]<<8);
/* the first byte of c is reserved for the length */
case 8 : b+=((ub4)k[7]<<24);
case 7 : b+=((ub4)k[6]<<16);
case 6 : b+=((ub4)k[5]<<8);
case 5 : b+=k[4];
case 4 : a+=((ub4)k[3]<<24);
case 3 : a+=((ub4)k[2]<<16);
case 2 : a+=((ub4)k[1]<<8);
case 1 : a+=k[0];
/* case 0: nothing left to add */
}
mix(a,b,c);
/*-------------------------------------------- report the result*/
return c;
}
static item **hashtable=0;
//初始化hash buckets空间
void assoc_init(void) {
unsigned int hash_size = hashsize(HASHPOWER) * sizeof(void*);
hashtable = malloc(hash_size);
if (! hashtable) {
fprintf(stderr, "Failed to init hashtable.\n");
exit(1);
}
memset(hashtable, 0, hash_size);
}
item *assoc_find(char *key){
ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER);
item *it = hashtable[hv];
while(it){
if(strcmp(it->key,key)==0)
return it;
it=it->next;
}
return 0;
}
int assoc_insert(char *key,item *it){
ub4 hv = hash(key, strlen(key), 0) & hashmask(HASHPOWER);
it->next = hashtable[hv];
hashtable[hv] = it;
return 1;
}
int main(int argc,char **argv){
assoc_init();
item *it=malloc(sizeof(item));
it->key=malloc(200);
it->value=malloc(200);
strcpy(it->key,"k1");
strcpy(it->value,"value1");
assoc_insert("k1",it);
item *head=assoc_find("k1");
printf("%s->%s",head->key,head->value);
}
分享到:
相关推荐
- **Map**: 存储键值对的数据结构,如HashMap和TreeMap。 - **泛型**: 提高代码安全性,限制集合只能存储特定类型的对象。 5. **输入输出流** - 文件I/O:使用FileReader/Writer处理文本文件,FileInputStream/...
- **HashSet与HashMap**:存储无序不重复元素,HashSet基于哈希表,HashMap存储键值对,查找效率高。 - **TreeSet与TreeMap**:基于红黑树的数据结构,保证元素排序。 5. **IO流** - **流的概念**:Java的IO流...
最后,`CompletableFuture`是Java 8引入的异步编程工具,它提供了链式调用、组合多个异步操作的能力,极大地简化了复杂异步逻辑的编写。 总的来说,JUC学习笔记涵盖了Java多线程编程的主要方面,包括线程的创建与...
- **容器**:如ArrayList、LinkedList、HashSet、HashMap等,用于存储和管理对象。 - **迭代器**:遍历集合的接口,提供了add、remove和hasNext等方法。 - **泛型**:在定义集合时指定元素类型,避免类型转换并...
LinkedList是List的实现类,提供了链式存储方式。LinkedList可以用于存储大量数据,并提供了高效率的插入和删除操作。 HashMap的使用 HashMap是Map的实现类,提供了键值对的存储方式。HashMap可以用于存储大量数据...
10. **多线程**:Java提供了Thread类和Runnable接口来实现并发执行,还包括同步机制(synchronized关键字、wait()、notify()、notifyAll()方法)。 11. **网络编程**:Socket编程,用于创建客户端和服务器之间的...
- List、Set、Map接口及其实现类的特性与用法,如ArrayList、LinkedList、HashSet、HashMap等。 - 集合操作:迭代器、泛型、并发集合(CopyOnWriteArrayList、ConcurrentHashMap)等。 - 并发容器:如...
20. Map集合的实现类HashMap:键值对存储,键唯一。 21. 单例模式和模板方法模式:设计模式,解决特定问题。 22. Java异常处理机制:try-catch-finally、throw、throws关键字,处理程序中的错误。 23. File类:文件...
### Effective Java读书笔记(上) #### 第一章 引言 本书主要针对Java开发者提供了大量实用的编程指导建议,帮助读者提升代码质量和程序性能。在本章节中,我们将重点介绍对象的创建与销毁,以及一些重要的设计...
深入理解它们的特性和使用场景,例如ArrayList的快速随机访问,LinkedList的链式结构适合插入删除操作,以及HashMap的散列原理。 3. **IO与NIO**:Java I/O流处理是基础,涉及FileInputStream、OutputStream等类,...
- **哈希表**:用HashMap和LinkedHashMap实现,LeetCode中常用于查找和存储元素。 - **二叉树**:自定义节点类,如`data class TreeNode(var val: Int, var left: TreeNode? = null, var right: TreeNode? = null)...
6. **集合框架**:Java集合框架包括List、Set、Queue和Map接口,以及ArrayList、LinkedList、HashSet、HashMap等实现类。这些容器用于存储和管理对象。 7. **输入/输出(I/O)**:学习使用File类、Scanner类进行文件...