stl的容器库非常强大,但是为了要兼容各种元素类型,采用了模板进行泛化,这样的好处就是 使用非常的方便,但是编译器会对使用到的每种类型都进行一遍实例化,用的类型太多的话 不仅影响编译速度而且生成的可执行文件也很冗余。

    因此,TBOX在设计容器架构的时候,引入tb_element_t类型,来设置容器使用的成员类型,这样 在实现容器通用性的同时,也不会产生过的冗余,而且容器接口操作上,同样相当的便利。

    可以先看个简单使用hash_map的例子:

    1. /* 初始化hash_map, 哈希桶大小8
    2. * 键:大小写敏感字符串
    3. * 值:long整型
    4. */
    5. tb_hash_map_ref_t hash_map = tb_hash_map_init(8, tb_element_str(tb_true), tb_element_long());
    6. if (hash_map)
    7. {
    8. // 设置键值对:"key" => 123
    9. tb_hash_map_insert(hash_map, "key", (tb_pointer_t)123);
    10.  
    11. // 获取值
    12. tb_long_t value = (tb_long_t)tb_hash_map_get(hash_map, "key");
    13.  
    14. // 退出hash_map
    15. tb_hash_map_exit(hash_map);
    16. }
    17.  
    18. /* 初始化hash_map, 哈希桶大小: TB_HASH_BULK_SIZE_MICRO
    19. * 键:tb_struct_xxxx_t 结构体类型,内存数据由hash_map内部自己维护, 后面两个参数设置成员的释放回调函数
    20. * 值:true类型,永远是tb_true, 这种hash_map相当于stl的set<tb_struct_xxxx_t>,内部会去优化掉value占用的内存
    21. */
    22. tb_hash_map_ref_t hash_map = tb_hash_map_init(TB_HASH_BULK_SIZE_MICRO, tb_element_mem(sizeof(tb_struct_xxxx_t), tb_null, tb_null), tb_element_true());
    23. if (hash_map)
    24. {
    25. // 初始化tb_struct_xxxx_t
    26. tb_struct_xxxx_t xxxx = {0};
    27.  
    28. // 设置键值对:xxxx => tb_true
    29. tb_hash_map_insert(hash_map, &xxxx, (tb_pointer_t)tb_true);
    30.  
    31. // 判断键是否存在
    32. if (tb_hash_map_get(hash_map, &xxxx))
    33. {
    34. // ...
    35. }
    36.  
    37. // 退出hash_map
    38. tb_hash_map_exit(hash_map);
    39. }
    40.  
    41. /* 初始化hash_map, 哈希桶大小使用默认大小: 0
    42. * 键:大小写不敏感字符串
    43. * 值:uint8整型
    44. */
    45. tb_hash_map_ref_t hash_map = tb_hash_map_init(0, tb_element_str(tb_false), tb_element_uint8());
    46. if (hash_map)
    47. {
    48. // 设置键值对:"key" => 123
    49. tb_hash_map_insert(hash_map, "key", (tb_pointer_t)123);
    50.  
    51. // 获取u位整型键值
    52. tb_uint8_t value = (tb_uint8_t)tb_hash_map_get(hash_map, "key");
    53.  
    54. // 退出hash_map
    55. tb_hash_map_exit(hash_map);
    56. }

    怎么样,简单吧。各种类型项都是可以在键值上互用的,而且会去适配tb_hash_map_get和tb_hash_map_set等容器接口参数。

    你也可以很方便的在初始化容器的时候,自定义成员释放函数、成员比较函数、哈希计算函数等,例如:

    1. // 指针成员释放函数
    2. static tb_void_t tb_hash_map_item_ptr_free(tb_element_ref_t element, tb_pointer_t buff)
    3. {
    4. // 断言检测
    5. tb_assert_and_check_return(element && buff);
    6.  
    7. // 获取用户私有数据
    8. tb_pointer_t priv = element->priv;
    9.  
    10. /* 获取成员数据,这里为tb_pointer_t类型,buff是指向成员数据的指针
    11. *
    12. * 如果是tb_element_str()项类型,数据就是:
    13. * tb_char_t* data = *((tb_char_t**)buff);
    14. *
    15. * 如果是tb_element_mem()项类型,数据就是:
    16. * tb_byte_t* data = (tb_byte_t*)buff;
    17. *
    18. * 因为tb_element_mem是吧成员数据的内存都放到了容器里面维护,所以
    19. * buff指向的就是成员数据本身的地址
    20. *
    21. * 而str、ptr只是把指针存到了容器中,所以item指向的是指针的地址,这个需要
    22. * 注意的,不然很容易出问题
    23. */
    24. tb_pointer_t data = *((tb_pointer_t*)buff);
    25.  
    26. // 释放它
    27. if (data) tb_free(data);
    28.  
    29. // 清空成员数据
    30. *((tb_pointer_t*)buff) = tb_null;
    31. }
    32.  
    33. // long 比较函数,改成反序比较
    34. static tb_long_t tb_hash_map_item_long_comp(tb_element_ref_t element, tb_cpointer_t ldata, tb_cpointer_t rdata)
    35. {
    36. return ((tb_long_t)ldata < (tb_long_t)rdata? 1 : ((tb_long_t)ldata > (tb_long_t)rdata? -1 : 0));
    37. }
    38.  
    39. // 初始化long整型比较函数
    40. tb_element_t element = tb_element_long();
    41.  
    42. // 替换比较函数, ptr有快捷的传入方式,当然也可以这样传
    43. element.comp = tb_hash_map_item_long_comp;
    44.  
    45. // 初始化hash_map
    46. tb_hash_map_ref_t hash_map = tb_hash_map_init(0, element, tb_element_ptr(tb_hash_map_item_ptr_free, "private data"));