C开源hash代码uthash的用法实例,亲测有效

最近在弄linux下弄一个与哈希表有关的东西,然后找到了uthhash这个东西,自己有看过别人介绍的博客,还有例子,但是例子不够详细,很多东西自己试过才知道,

下边把我的源码发上来,上边也有一些注释,写的不是很好,是个半成品。

#include "uthash.h"
#include <stdlib.h>
#include <stdio.h>
#include<string.h>

#include <time.h>


//哈希表的实质就是把key和内存地址通过哈希函数关联起来,从而节省时间。


typedef struct net_kit{
        char key[50];
        time_t  t1;//获取当前时间距离1970.1.1的秒数。
        char content[32];//32位的一个东西
        UT_hash_handle hh; /* makes this structure hashable */
}Net_Kit;


//定义哈希表指针
Net_Kit  *users = NULL;
int   insert(char *tuple4,char *con);
Net_Kit * search(char *tuple4);
int32_t update(char *tuple4,char*con);
time_t timeinfo();
void  changed(Net_Kit *new_kit);
//定义那3个函数
int   insert(char *tuple4,char *con)
{
    Net_Kit *tmp_kit = NULL;
    Net_Kit *lastkit = NULL;
    unsigned int num;
    num = HASH_COUNT(users);
 //   printf("before insert  total num is %d\n",num);
    if(num !=0)
    {
        //先查找这个tuple4是不是已经存在了,num  为0查找会出现错误。
        //HASH_FIND_STR(users, tuple4, tmp_kit );
    }


    if(tmp_kit==NULL)//就说明原来没有,第一次出现
    {
        //判断有没有满,满了的话先删除一个好久没用的


        if(num>=100000000)
        {
                lastkit = users;
                  //必须得先确定唯一得端口才能来删除
                 //直接从users头找找到最后边的东西,然后删除掉
                 while(lastkit->hh.next){
                           lastkit =  lastkit->hh.next;
                 }
                 HASH_DEL( users, lastkit); /* user: pointer to deletee */
                free(lastkit);
        }


        //然后申请内存
        tmp_kit = (Net_Kit*)malloc(sizeof(Net_Kit));
            if(tmp_kit == NULL)//分配失败
            {
                printf("malloc  failed");
                return 0;
            }


        tmp_kit->t1 = timeinfo();
        strcpy(tmp_kit->key,tuple4);
        strcpy(tmp_kit->content,con);


        HASH_ADD_STR( users, key, tmp_kit ); //这个key是键值
    }else{
        printf("this tuple4 has exited!\n");
        return 0;
    }
//插入成功返回1,不成功返回0;
    return   1;
}


int32_t update(char *tuple4,char*con)
{
    //先查找,然后再修改
     Net_Kit*   tmp_kit = NULL;
    HASH_FIND_STR(users, tuple4, tmp_kit );


    if(tmp_kit !=NULL)//找到了
    {
            //需要更新时间???
            tmp_kit->t1 = timeinfo();
            strcpy(tmp_kit->content,con);
            changed( tmp_kit);//更新顺序
          return 1;
    }
    return 0;
}


Net_Kit * search(char *tuple4)
{
printf("search  begin\n");
     Net_Kit*   tmp_kit = NULL;
      Net_Kit*   next_kit = NULL;
    HASH_FIND_STR(users, tuple4, tmp_kit );//这个是从头开始查,如果由一样掉,先返回第一个。


    if(tmp_kit !=NULL)
    {
          //这儿写些东西用来测试
          if(tmp_kit->hh.next){
                next_kit = tmp_kit->hh.next;
                printf("更新前他的后一个包键值为%s",next_kit->key);
                printf("更新前他的后一个东西的包内容");
                puts(next_kit->content);
            }
             if(tmp_kit->hh.prev){
                next_kit = tmp_kit->hh.prev;
                printf("更新前他的前一个包键值为%s",next_kit->key);
                printf("更新前他的前一个东西的包内容");
                puts(next_kit->content);
            }
            //需要更新时间???
            tmp_kit->t1 = timeinfo();
              changed( tmp_kit);//更新顺序
          return tmp_kit;
    }
    else
        return NULL;
}


time_t timeinfo()
{
   // time(&tmp_time)函数获取当前时间距1970年1月1日的秒数,以秒计数单位,存于rawtime 中。
        time_t tmp_time;
        time(&tmp_time);


        return tmp_time;
}
//这个函数就是弄他的前一个还有后一个指向的东西
void  changed(Net_Kit *new_kit)
{
    Net_Kit *temp_prekit;
    Net_Kit *temp_nextkit;
    Net_Kit *firstkit;


    temp_prekit = new_kit->hh.prev;
    temp_nextkit = new_kit->hh.next;


    if(temp_prekit)//他前一个不为空
    {
            firstkit = temp_prekit;
            while(firstkit->hh.prev)//获取第一个
            {
                firstkit = firstkit->hh.prev;
            }


            if(temp_nextkit)//后一个也不为空
            {
                    temp_prekit->hh.next=temp_nextkit;//他前一个的后一个指向他的后一个
                    temp_nextkit->hh.prev= temp_prekit;
                    //
                     new_kit->hh.prev = NULL;//他的前一个指向空,后一个指向第一个
                    new_kit->hh.next = firstkit;
                      //第一个的前一个由空指向他
                      firstkit->hh.prev = new_kit;
            }else{
                   temp_prekit->hh.next  = NULL;//他的前一个的next指向空


                    new_kit->hh.prev = NULL;//他的前一个指向空,后一个指向第一个
                    new_kit->hh.next = firstkit;
                      //第一个的前一个由空指向他
                    firstkit->hh.prev = new_kit;
           }
    }/*else{
               if(temp_nextkit)//后一个不为空
               {
               //那他就是最新一个不用改变
               }else
               {
               //说明只有他一个,那也不需要改变
               }
    }*/
}






int main(int argc,char *argv[])
{
    char in[10];
    char tuple4[50];
    char con[500];
    int32_t run = 1;
      int32_t times ;
    Net_Kit  *temp_kit = NULL;
    while(run)
    {
    printf(" 1.insert\n");
    printf(" 2.update\n");
    printf(" 3.search\n");
    printf(" 4.exit\n");
    printf(" 5.sort by time and put out\n");
    printf(" 6.insert many data");
   fgets(in,10,stdin);
    //gets(in);
        switch(atoi(in))
        {
            case 1:
                printf("--insert--\n");
                printf("tuple is?");
                fgets(tuple4,50,stdin);//他会把换行符也会读进去。
             //这儿可以加上一些长度检验什么读。
                printf("kit is?");
                fgets(con,500,stdin);


//if(insert("1","2")==1)
//printf("insert success\n");
               if( insert(tuple4,con)==1)
                   printf("insert success\n");
                else
                    printf("insert falied\n");
                break;
            case 2:
                    printf("-----update-----\n");
                    printf("tuple is?");
                    fgets(tuple4,50,stdin);
                    printf("kit is?");
                    fgets(con,500,stdin);
                    if( update(tuple4,con))
                         printf("update success\n");
                    else
                         printf("update falied\n");
                   break;
            case 3:
                    printf("-----search------ \n");
                    temp_kit = NULL;
                    printf("tuple is?");
                    fgets(tuple4,50,stdin);
                    temp_kit = search(tuple4);


                    if( temp_kit !=NULL)
                    {
                        puts(temp_kit->content);
                    }
                    else
                         printf("no this kit\n");
                   break;
            case 4:
                run = 0;
                break;
            case 5:
                while( users->hh.prev)//先给users指向最前边的东西
                {
                        users = users->hh.prev;
                }
                temp_kit = users;
                while(temp_kit !=NULL)
                {
                        printf("key:%s,con:%s",temp_kit->key,temp_kit->content);
                        temp_kit = temp_kit->hh.next;
                      //  puts(users->hh.next);
                }
                break;
            case 6:
                 times= 10000000;
                 char a[50];
                 char b[100];
                 strcpy(a,"172.16.18.235,500,111.11.11.111,400");
                 strcpy(b," How are you ? I'm fine,and you ? I'm OK ,thankyou!");
                while(times != 0)
                {
                         insert(tuple4,con);
                         times--;
                }
                break;
            default:
                printf("input error\n");
                break;
        }
    }
    return 0;
}

下边说下uthash这个东西,你从相应的.h文件里边可以看到他不是单纯的哈希表,结构体里边还有两个双向指针,可以指向他的前一个和后一个,

在插入的时候我测试过他是有顺序的,从头到尾像是一个双向链表一样,然后键值里边的东西是可以相同的,如果你查找的话他是会按照从头到后返回第一次出现到那个。

我这个例子里边每次查找和更新的时候会把正在弄的这个结点放到头上,把他的前一个和后一个链接起来,如果存在的话。

说了这些,其实都是我自己试验的结果,他里边的代码我也不是很懂,大家凑合的看把。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值