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();

    }

    运行结果如下:

  • 相关阅读:
    LVS 模式
    修改RocketMQ的NameServer端口
    一次清理Hbase的oldWALs的过程
    Linux下删除文件系统空间不释放的问题
    HBase 强制删除表
    关闭Found duplicated code
    Java操作HDFS代码样例
    RocketMQ:Cannot allocate memory
    Storm的StreamID使用样例(版本1.0.2)
    android studio 编译sdk版降低报错解决方法
  • 原文地址:https://www.cnblogs.com/fellow1988/p/6142729.html
Copyright © 2011-2022 走看看