哈希表

公司提供了一套接口供客户开发应用。这套接口的框架是用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();

}

运行结果如下:

哈希表