zoukankan      html  css  js  c++  java
  • 哈希表

    公司提供了一套接口供客户开发应用。这套接口的框架是用IPCRPC实现,严格意义上说这是伪IPCRPC,因为不涉及机器之间的通信,只是不同进程间的通信。

    提供给客户的接口里面,其实只是通过socket发送信息到一个类似daemon的进程,具体的操作都是在deamon进程中,处理完后将结果返回给应用进程。mdnsResponder也是采用这样的思路。

    在接口里面,将接口的函数名字和参数打包发给daemon进程,在daemon进程将一些相同名字的函数注册到一个哈希表中,当收到应用进程发来的函数名字后,直接查找哈希表,调用相应的函数。

    基于上面这种想法,实现一个哈希表,以函数名为key,以函数作为value.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    typedef struct _HashNode{
      char *key;
      void *value;
      struct _HashNode *prev;
      struct _HashNode *next;
    }HashNode;
    typedef struct _HashList{
      HashNode *pListHead;//链表头
      int elemNum;//链表中元素个数
    }HashList;
    typedef struct _HashTable{
      HashList *pTable;
      unsigned long tableSize;
    }HashTable;//哈希表的每一项都是一个双链表
    HashTable gHashTable;
    typedef int (*Handle)();


    void hash_init(HashTable *hashTable, unsigned long tableSize)
    {
      hashTable->pTable = (HashList *)malloc(tableSize * sizeof(HashList));
      memset(hashTable->pTable, 0, tableSize * sizeof(HashList));
      hashTable->tableSize = tableSize;
    }
    unsigned long hash_func(const char *key, unsigned long tableSize)
    {
      char *tmp = NULL;
      unsigned long hashCode = 0;
      for (tmp = key; *tmp != ''; tmp++)
      {
        hashCode = hashCode * 31 + *tmp;
      }
      hashCode = hashCode & (tableSize - 1);
      return hashCode;
    }

    void hash_add(HashTable *hashTable, const char *key, void *value)
    {
      unsigned long hashCode = hash_func(key, hashTable->tableSize);
      HashNode *pNode = (HashNode *)malloc(sizeof(HashNode));
      pNode->key = key;
      pNode->value = value;
      pNode->prev = pNode->next = NULL;
      if (hashTable->pTable[hashCode].pListHead == NULL)
      {
        hashTable->pTable[hashCode].pListHead = pNode;
      }
      else
      {
        pNode->next = hashTable->pTable[hashCode].pListHead;
        hashTable->pTable[hashCode].pListHead->prev = pNode;
        hashTable->pTable[hashCode].pListHead = pNode;
      }
      hashTable->pTable[hashCode].elemNum++;
    }

    int hash_get(HashTable *hashTable, const char *key, void **value)
    {
      unsigned long hashCode = hash_func(key, hashTable->tableSize);
      if (hashTable->pTable[hashCode].pListHead == NULL)
      {
        printf("key:%s NOT found ", key);
        return 0;
      }
      else
      {
        HashNode *tmp = NULL;
        for (tmp = hashTable->pTable[hashCode].pListHead; tmp; tmp = tmp->next)
        {
          if(!strncmp(tmp->key, key, strlen(key)))
          {
            if (value)
            {
              *value = tmp->value;
            }
            return 1;
          }
        }
      }
      printf("1key:%s NOT found ", key);
      return 0;
    }

    int handle_fellow_open()
    {
      printf("fellow open! ");
    }
      int handle_fellow_close()
    {
      printf("fellow close! ");
    }
    int handle_fellow_play()
    {
      printf("fellow play! ");
    }
    void reg_handle_func(HashTable *hashTable, const char *key, Handle handle)
    {
      printf("reg %s, 0x%x ", key, (int)handle);
      if (hash_get(hashTable, key, NULL))
      {
        printf("already exist ");
        return;
      }
      hash_add(hashTable, key, handle);

    }
    #define REG_HANDLE(name)
    do{reg_handle_func(&gHashTable, #name, handle_##name);}while(0)

    void init_handle()
    {
      REG_HANDLE(fellow_open);
      REG_HANDLE(fellow_close);
      REG_HANDLE(fellow_play);
    }

    void main(void)
    {
      hash_init(&gHashTable, 1024);
      init_handle();
      Handle handle;
      hash_get(&gHashTable, "fellow_play", (void **)&handle);
      handle();
      reg_handle_func(&gHashTable, "fellow_open", handle_fellow_open);
      hash_get(&gHashTable, "fellow_close", (void **)&handle);
      handle();

    }

    运行结果如下:

  • 相关阅读:
    【Nginx】ngx_event_core_module模块
    ELMAH--Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components 77 out of 90 rated th
    nyist oj 214 单调递增子序列(二) (动态规划经典)
    java 入门书籍(java7)
    ARCGIS将WGS84坐标投影到高斯平面
    【linux】linux下对java程序生成dump文件,并使用IBM Heap Analyzer进行分析,查找定位内存泄漏的问题代码
    【springboot】【socket】spring boot整合socket,实现服务器端两种消息推送
    【linux】linux修改open file 大小
    【docker】docker限制日志文件大小的方法+查看日志文件的方法
    【docker】docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6142729.html
Copyright © 2011-2022 走看看