搜索引擎中缓存(cache)用到的哈希(hash)算法
2013-04-26 11:21
615 查看
前一段查看了关于哈希的各种算法,发现流传最广的还算伟大的暴雪(dota爱好者)工程师得到的一种算法,有很多博客中都有对其的介绍,我在此就不多废话了。
虽说是借鉴,也只是一小部分的抄袭。不知道是否冒犯了暴雪的版权。
我修改成了我需要的功能,我的目标是对6w数据进行哈希计算然后暂存到内存中,当做缓存使用。这是搜索引擎中必须要做的一步,当然,代码是公司机密,我只是把我写的代码雏形拿出来,看看有没有值得批评指正的地方。
小弟不才,在这6w的测试数据中,使用5倍的内存,得到最长的一串链表长达180.(不知道大家知道不知道我说的是什么意思)。沟通的机会来了。。。。。
欢迎到之类来沟通交流:
http://lee-sven.com/wordpress/?p=330
还是看看代码:
虽说是借鉴,也只是一小部分的抄袭。不知道是否冒犯了暴雪的版权。
我修改成了我需要的功能,我的目标是对6w数据进行哈希计算然后暂存到内存中,当做缓存使用。这是搜索引擎中必须要做的一步,当然,代码是公司机密,我只是把我写的代码雏形拿出来,看看有没有值得批评指正的地方。
小弟不才,在这6w的测试数据中,使用5倍的内存,得到最长的一串链表长达180.(不知道大家知道不知道我说的是什么意思)。沟通的机会来了。。。。。
欢迎到之类来沟通交流:
http://lee-sven.com/wordpress/?p=330
还是看看代码:
#include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> //#define DEBUG #define NUM 10240 //缓存的最大数据量 typedef struct hash{ char flag; char hz[64]; char *art; int time; int n; struct hash *next; }HASH; HASH *hashtable1=NULL,*hashtable2=NULL,*hashtable3=NULL,*hashtable4=NULL,*hashtable5=NULL; unsigned long cryptTable[0x500]; /****************************************************** * 函数功能:申请哈希表所用的内存; * 函数参数:void; * 函数输出:成功:1;失败:-1; ******************************************************/ int getMalloc(){ hashtable1 = (HASH *)malloc((NUM)*sizeof(HASH)); hashtable2 = (HASH *)malloc(NUM*sizeof(HASH)); hashtable3 = (HASH *)malloc(NUM*sizeof(HASH)); hashtable4 = (HASH *)malloc(NUM*sizeof(HASH)); hashtable5 = (HASH *)malloc(NUM*sizeof(HASH)); memset(hashtable1,0,(NUM)*sizeof(HASH)); memset(hashtable2,0,NUM*sizeof(HASH)); memset(hashtable3,0,NUM*sizeof(HASH)); memset(hashtable4,0,NUM*sizeof(HASH)); memset(hashtable5,0,NUM*sizeof(HASH)); if(hashtable1==NULL||hashtable2==NULL||hashtable3==NULL||hashtable4==NULL||hashtable5==NULL) { perror("get Malloc error"); return -1; } return 1; } /****************************************************** * 函数功能:生成一个长度为0x500的cryptTable[0x500]; * 函数参数:void; * 函数输出:void; ******************************************************/ void prepareCryptTable() { unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i; for( index1 = 0; index1 < 0x100; index1++ ) { for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 ) { unsigned long temp1, temp2; seed = (seed * 125 + 3) % 0x2AAAAB; temp1 = (seed & 0xFFFF) << 0x10; seed = (seed * 125 + 3) % 0x2AAAAB; temp2 = (seed & 0xFFFF); cryptTable[index2] = ( temp1 | temp2 ); } } } /****************************************************** * 函数功能: 计算lpszFileName 字符串的hash值; * 函数参数: 字符串指针 、运算类型(可以去0、1、2); * 函数输出: 哈希值; ******************************************************/ unsigned long HashString( char *lpszFileName, unsigned long dwHashType ) { unsigned char *key = (unsigned char *)lpszFileName; unsigned long seed1 = 0x7FED7FED; unsigned long seed2 = 0xEEEEEEEE; int ch; while( *key != 0 ) { ch = toupper(*key++); seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2); seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3; } return ((seed1*2654435769)%NUM);//seed1%5000 } /****************************************************** * 函数功能: 往哈希表中对应节点的内存中写内容 * 函数参数: ptr:哈希表中一个节点指针 str:关键词 * 函数输出: void ******************************************************/ void writemem(HASH *ptr,char *str){ #ifdef DEBUG static int i=0; i++; printf("i=%d\n",i); #endif #ifdef DEBUG printf("-------writemem start--------\n"); #endif HASH *p=ptr,*q; while(p->next != NULL){ p=p->next; } #ifdef DEBUG printf("----sizeof(HASH):%d-----\n",sizeof(HASH)); #endif HASH *p_hash=NULL; p_hash = (HASH *)malloc(sizeof(HASH)); memset(p_hash,0,sizeof(HASH)); #ifdef DEBUG printf("----------1------------\n"); #endif if(p_hash == NULL){ perror("p_hash malloc error"); } strcpy(p_hash->hz,str); p_hash->flag = 1; p_hash->next=NULL; /*此处还需加上拷贝搜索内容的代码*/ p->next=p_hash; #ifdef DEBUG printf("-------writemem end--------\n"); #endif } /****************************************************** * 函数功能: 往哈希表中写数据 * 函数参数: n:哈希值 hz:关键字数 str:关键字 * 函数输出: void ******************************************************/ void writeHash(int n,int hz,char *str){ #ifdef DEBUG printf("-------writeHash start--------\n"); #endif switch(hz){ case 1: writemem((hashtable1+n),str); break; case 2: writemem((hashtable2+n),str); break; case 3: writemem((hashtable3+n),str); break; case 4: writemem((hashtable4+n),str); break; case 5: writemem((hashtable5+n),str); break; case 6: case 7: case 8: case 9: break; default: break; } #ifdef DEBUG printf("-------writeHash end--------\n"); #endif } /****************************************************** * 函数功能: 遍历哈希表,查询有多少内容 * 函数参数: void * 函数输出: void ******************************************************/ void countHash(){ int i; int all=0; for(i=0;i<NUM;i++){ HASH *p=hashtable1+i; while(p->next!=NULL){ p=p->next; all++; } p=hashtable2+i; while(p->next!=NULL){ p=p->next; all++; } p=hashtable3+i; while(p->next!=NULL){ p=p->next; all++; } p=hashtable4+i; while(p->next!=NULL){ p=p->next; all++; } p=hashtable5+i; while(p->next!=NULL){ p=p->next; all++; } } printf("the title = %d\n",all); } /****************************************************** * 函数功能: 删除哈希表中某一个节点上的内容 * 函数参数: ptr:哈希节点指针 str:关键字 * 函数输出: 找到删除的节点并正确删除返回1;否则返回0 ******************************************************/ char deletemem(HASH *ptr,char *str){ HASH *p=ptr,*q; while(p!=NULL){ if(strcmp(p->hz,str) == 0){ q->next=p->next; /*此处还需加上释放存放搜索结果内存的代码*/ free(p); return 1; } q=p; p=p->next; } printf("delet fail\n"); return 0; } /****************************************************** * 函数功能: 往哈希节点 * 函数参数: n:哈希值 hz:关键字数 str:关键字 * 函数输出: void ******************************************************/ void deleteNode(int n,int hz,char *str){ #ifdef DEBUG printf("-------delete start--------\n"); #endif switch(hz){ case 1: deletemem((hashtable1+n),str); break; case 2: deletemem((hashtable2+n),str); break; case 3: deletemem((hashtable3+n),str); break; case 4: deletemem((hashtable4+n),str); break; case 5: deletemem((hashtable5+n),str); break; case 6: case 7: case 8: case 9: break; default: break; } #ifdef DEBUG printf("-------delete end--------\n"); #endif } int main(){ int error=0; int flag=1,count=0; unsigned long ulHashValue; char *hzString=(char *)malloc(256); if(hzString==NULL){ perror("hzString malloc error"); } error = getMalloc(); if(error==-1){ perror("malloc hash error"); //暂时不做处理 } FILE *stream,*fdata; fdata=fopen("data.txt","w+"); stream=fopen("test.txt","r+"); srand((int)time(NULL)); while(1){ int hz=0; while(hz == 0) hz=((unsigned int)rand())%5; char ch[4]; int i; for(i=0;i<hz;i++){ memset(ch,0,sizeof(ch)); ch[0] = fgetc(stream); if(ch[0]==EOF){ flag=0; break; } if(ch[0] < 0){ ch[1] = fgetc(stream); if(ch[1] == EOF){ flag=0; break; } } strcat(hzString,ch); } count++; if(flag==0||count>NUM) break; prepareCryptTable(); ulHashValue = HashString(hzString,0); char p[20]; memset(p,0,20); sprintf(p,"%u\n",(unsigned int)ulHashValue); fwrite(p,1,strlen(p),fdata); #ifdef DEBUG printf("ulHashValue=%u\n",(unsigned int)ulHashValue); #endif writeHash(ulHashValue,hz,hzString); if(count%5==0){ deleteNode(ulHashValue,hz,hzString); } memset(hzString,0,256); } #ifdef DEBUG #endif countHash(); free(hzString); fclose(fdata); fclose(stream); return 0; }
相关文章推荐
- 继续算法 哈希Hash (一) 概述
- 环形缓存之一致性 hash 算法( consistent hashing )
- c#的哈希(hash)算法解析
- Ehcache 1.5.0 User Guide - Cache Eviction Algorithms (缓存移出算法)
- 哈希Hash 算法
- C# 中使用 MD5 算法计算 hash (哈希)值的四种方法
- 简单易懂讲解simhash算法 hash 哈希
- 对字符串进行哈希的算法,hash_func
- 哈希(hash)算法
- 从PHP的Hash(哈希)算法开始
- 哈希(hash)算法的学习(二)
- C# 中使用 MD5 算法计算 hash (哈希)值的四种方法
- php+mysql分库分表的哈希(hash)算法
- leetcode LRU Cache(高级缓存的最近最少使用算法实现)
- 让WP Super Cache对搜索引擎进行缓存
- 算法打基础——HashⅡ: 全域哈希与完美哈希
- 哈希(hash)算法的学习(一)
- 搜索引擎的缓存(cache)机制
- 哈希(Hash)算法
- C# 中使用 MD5 算法计算 hash (哈希)值的四种方法