测试时候要修改下sock_alloc_mm以及sock_free_mm宏
#define sock_alloc_mm(size) malloc(size)
#define sock_free_mm(p) free(p)
代码:
#include "key_object.h" struct object_hash_item{ struct object_hash_item* next; /* 单链表 */ struct object_hash_item** entry; /* hash表入口头 */ unsigned long key; void* object; }; struct object_hash_pool{ int hash_size; struct object_hash_item** hash_table; /* hash表 */ int pool_size; /* object数量 */ struct object_hash_item* object_pool; /* object池 */ int pool_stick; /* object轮转分配位置 */ }; /* * 初始化一个hash_pool, pool_size <=0 表明不使用object池,不限制object数量 */ void* alloc_object_hash_pool(int hash_size, int pool_size) { struct object_hash_pool* pool; if (hash_size <= 0) return NULL; pool = sock_alloc_mm(sizeof(struct object_hash_pool)); if (!pool) return NULL; /* 初始化数据结构 */ memset(pool, 0, sizeof(struct object_hash_pool)); /* 动态分配hash表 */ pool->hash_size = hash_size; pool->hash_table = sock_alloc_mm(hash_size * sizeof(struct object_hash_item*)); if (!pool->hash_table){ free_object_hash_pool(pool); return NULL; } memset(pool->hash_table, 0, hash_size * sizeof(struct object_hash_item*)); /* 预分配object池 */ if (pool_size > 0){ pool->pool_size = pool_size; pool->object_pool = sock_alloc_mm(pool_size * sizeof(struct object_hash_item)); if (!pool->object_pool){ free_object_hash_pool(pool); return NULL; } memset(pool->object_pool, 0, pool_size * sizeof(struct object_hash_item)); } return pool; } /* * 释放object_hash_pool */ void free_object_hash_pool(void* pool_handle) { int i; struct object_hash_item* enum_item; struct object_hash_item* hash_head; struct object_hash_item* hash_item; struct object_hash_pool* pool = (struct object_hash_pool*)pool_handle; if (pool){ /* 释放object */ if (pool->object_pool){ sock_free_mm(pool->object_pool); } else if (pool->hash_table) { /* 遍历hash表,依次释放object */ for (i = 0; i < pool->hash_size; i++){ hash_head = pool->hash_table[i]; for (enum_item = hash_head; enum_item;){ hash_item = enum_item; enum_item = hash_item->next; sock_free_mm(hash_item); } } } /* 释放hash表 */ if (pool->hash_table) sock_free_mm(pool->hash_table); memset(pool, 0, sizeof(struct object_hash_pool)); sock_free_mm(pool); } } static struct object_hash_item* key_to_hash_object(struct object_hash_pool* pool, unsigned long key) { int hash_index; struct object_hash_item* hash_head; struct object_hash_item* enum_item; if (!pool) return NULL; /* 计算待插入的hash链表头 */ hash_index = key % pool->hash_size; hash_head = pool->hash_table[hash_index]; /* head->自己*/ for (enum_item = hash_head; enum_item; enum_item = enum_item->next){ if (enum_item->key == key) return enum_item; } return NULL; } /* * 插入一个key到hash表,key不允许重复 */ int add_object_hash_pool(void* pool_handle, unsigned long key, void* object) { int hash_index; struct object_hash_item* enum_item; struct object_hash_item* hash_item; struct object_hash_pool* pool = (struct object_hash_pool*)pool_handle; if (!pool) return -1; /* 计算待插入的hash链表头 */ hash_index = key % pool->hash_size; /* 检查是否key冲突 */ if (key_to_hash_object(pool, key)) return -1; /* 申请一个object */ if (pool->object_pool){ pool->pool_stick++; pool->pool_stick = pool->pool_stick % pool->pool_size; hash_item = pool->object_pool + pool->pool_stick; } else { hash_item = sock_alloc_mm(sizeof(struct object_hash_item)); memset(hash_item, 0, sizeof(struct object_hash_item)); } /* 从原来的hash队列中删除 */ if (hash_item->entry && *hash_item->entry){ if (*hash_item->entry == hash_item){ *hash_item->entry = hash_item->next; } else { for (enum_item = *hash_item->entry; enum_item; enum_item = enum_item->next){ if (enum_item->next == hash_item){ enum_item->next = hash_item->next; break; } } } } hash_item->entry = pool->hash_table + hash_index; hash_item->next = NULL; hash_item->key = key; hash_item->object = object; if (*hash_item->entry){ /* 挂入队列尾 */ for (enum_item = *hash_item->entry; enum_item->next; enum_item = enum_item->next); enum_item->next = hash_item; } else { *hash_item->entry = hash_item; } return 0; } /* * 通过key快速检索到一个object */ void* get_object_hash_pool(void* pool_hanle, unsigned long key) { struct object_hash_item* hash_item = key_to_hash_object((struct object_hash_pool*)pool_hanle, key); return hash_item ? hash_item->object : NULL; } /* * 删除指定key对应的object */ int del_object_hash_pool(void* pool_handle, unsigned long key) { struct object_hash_pool* pool = (struct object_hash_pool*)pool_handle; struct object_hash_item* enum_item; struct object_hash_item* hash_item = key_to_hash_object(pool, key); /* 从链表中删除该object */ for (enum_item = *hash_item->entry; enum_item && enum_item->next != hash_item;) enum_item = enum_item->next; /* 删除该节点 */ if (enum_item && enum_item->next == hash_item) enum_item->next = hash_item->next; if (!pool->object_pool) sock_free_mm(hash_item); return 0; }
代码:
#include "..\key_object.h" #include <stdlib.h> #include <stdio.h> #define TEST_NUM 1024 int keys[TEST_NUM]; int main(int argc, char** argv) { void* hash_pool = alloc_object_hash_pool(TEST_NUM, 512); int i,obj,err_num = 0, ok_num = 0, fail_num = 0; for (i=0; i<TEST_NUM; i++){ keys[i] = rand(); //printf("[%d] key:%d\n", i, keys[i]); if (add_object_hash_pool(hash_pool, keys[i], keys + i) < 0) keys[i] = -1; } for (i=0; i<TEST_NUM; i++){ obj = (int)get_object_hash_pool(hash_pool, keys[i]); if ((int)(keys + i) == obj){ printf("[%d] key:%08x \tobj:%08x ok\n", i, keys[i], obj); ok_num++; }else if (keys[i] == -1){ printf("[%d] insert fail!\n", i); fail_num++; }else{ printf("[%d] key:%08x \tobj:%08x err!!!%08x\n", i, keys[i], obj, keys + i); err_num++; } } free_object_hash_pool(hash_pool); printf("Total %d:ok %d fail %d err %d\n", TEST_NUM, ok_num, fail_num, err_num); return 0; }