map容器的c实现

来源:互联网 发布:alpine linux 包管理 编辑:程序博客网 时间:2024/04/29 14:55

原文来自:http://blog.chinaunix.net/uid-21457204-id-3063180.html

主要是使用红黑树这种数据结构封装一个MAP容器,本来想模仿STL MAP,不过现在暂时实现,今后会改进,目前还没实现加锁这功能,不过可以支持win32和linux平台。。。

以下是源代码:

  1. /*
  2. * file: main.c
  3. * author: vincent.cws2008@gmail.com
  4. * history:
  5. * initial @ 2012-01-31
  6. */

  7. #define DEBUG

  8. #include <stdio.h>
  9. #include <time.h>
  10. #include <stdlib.h>
  11. #include <string.h>

  12. #include "map.h"

  13. #ifdef DEBUG
  14. #define dump(a,s) __dump((a),(s))
  15. #else
  16. #define dump(a,s)
  17. #endif


  18. typedef struct word_info {
  19. unsigned long hash_major;
  20. unsigned long hash_minor;
  21. char *path;
  22. unsigned long line;
  23. unsigned long col;
  24. }word_info_t;

  25. typedef struct priv_info {
  26. unsigned long key;
  27. char val[10];
  28. }priv_info_t;


  29. static void __dump(priv_info_t *array, size_t num)
  30. {
  31. int i;
  32. printf("-- DUMP START -- \n");
  33. for (i=0; i< num; i++)
  34. {
  35. printf("array[%d].key=%03d, array[%d].val=%s\n",
  36. i, array[i].key, i,array[i].val);
  37. }
  38. printf("-- DUMP END -- \n");
  39. }

  40. #define map_info(pm){\
  41. printf("-- dump map start ... --\n");\
  42. map_dump(pm);\
  43. printf("-- dump map end ... --\n");\
  44. }

  45. #define ARRAY_SIZE(a)(sizeof(a)/sizeof(a[0]))

  46. #define MAX_NUM 20

  47. int main()
  48. {
  49. map_t map1;
  50. int key;
  51. int i, j;
  52. priv_info_t priv_info[MAX_NUM];

  53. srand(time(0));

  54. memset(priv_info, 0, sizeof(priv_info));
  55. for (i=0; i<MAX_NUM; i++)
  56. {
  57. key = rand()%MAX_NUM;
  58. priv_info[i].key= key;
  59. sprintf(priv_info[i].val,"i am %d", key);
  60. }
  61. dump(priv_info, ARRAY_SIZE(priv_info));

  62. map_init(&map1);

  63. i = 0;
  64. while (i< MAX_NUM)
  65. {
  66. struct mnode* node;
  67. printf("-- %d -- \n", i);
  68. node = map_find(&map1,&(priv_info[i].key),NULL);
  69. if (!node){
  70. printf("->>> insert node: priv_info[%d].key=%d \n", i, priv_info[i].key);
  71. map_insert_alloc(&map1,&(priv_info[i].key),
  72. &priv_info[i], sizeof(priv_info[i]),NULL);
  73. } else {
  74. /* key not matched, so just print out */
  75. printf("priv_info[%d].key=%d is exist!\n", i, priv_info[i].key);
  76. for (j=0; j< MAX_NUM; j++){
  77. if(priv_info[j].key== priv_info[i].key&& i!=j)
  78. printf("\t|-- priv_info[%d].key=%d\n", j, priv_info[j].key);
  79. }
  80. }
  81. map_info(&map1);

  82. i++;
  83. }
  84. map_info(&map1);

  85. printf("-----------------------------------\n");
  86. for (i=0; i< MAX_NUM; i++)
  87. {
  88. struct mnode* node;
  89. node = map_find(&map1,&i,NULL);
  90. if (node){
  91. map_remove_free(&map1,&i, NULL);
  92. printf("--> key=%03d deleted!\n", i);
  93. map_info(&map1);
  94. }else{
  95. printf("key=%03d not found!\n", i);
  96. }
  97. }
  98. map_info(&map1);

  99. map_exit(&map1);
  100. return 0;
  101. }

.............................................................................................
.............................................................................................


  1. /*
  2. * file: map.h
  3. * author: vincent.cws2008@gmail.com
  4. * history:
  5. * initial @ 2012-01-31
  6. */
  7. #ifndef __MAP_H__
  8. #define __MAP_H__

  9. #include <stdlib.h>
  10. #include "platform.h"
  11. #include "rbtree.h"

  12. #define lock_t int
  13. #define lock_init(x)
  14. #define lock_exit(x)

  15. #ifndef NULL
  16. #define NULL 0
  17. #endif

  18. #define __assert(x)
  19. #define __free(x) free(x)
  20. #define __malloc(x) malloc(x)
  21. #define __memcpy(d,s,len) memcpy((d),(s),(len))

  22. extern struct map;

  23. typedef int (*CMP_FUNC)(const void*d1, const void *d2);

  24. typedef struct mnode{
  25. struct rb_node node;
  26. void *key;
  27. void *private;
  28. }mnode_t;

  29. /*
  30. typedef struct ops{
  31. struct mnode*(*find)(struct map*map, void *key, CMP_FUNC cmpf);
  32. int (*insert_alloc)(struct map*map, void *key,
  33. void *private, size_t size, CMP_FUNC cmpf);
  34. int (*remove_free)(struct map*map, void *key, CMP_FUNC cmpf);
  35. int (*insert)(struct map*map, struct mnode*data, CMP_FUNC cmpf);
  36. int (*remove)(struct map*map, void *key, CMP_FUNC cmpf);
  37. }ops_t;
  38. */

  39. typedef struct map{
  40. struct rb_root root;
  41. lock_t lock;
  42. }map_t;

  43. extern int map_init(struct map* map);
  44. extern int map_exit(struct map* map);

  45. struct mnode* __rbfind(struct map*map, void *key, CMP_FUNC cmpf);
  46. int __rbinsert_alloc(struct map*map, void *key,
  47. void *private, size_t size, CMP_FUNC cmpf);
  48. int __rbremove_free(struct map*map, void *key, CMP_FUNC cmpf);
  49. int __rbinsert(struct map*map, struct mnode*data, CMP_FUNC cmpf);
  50. int __rbremove(struct map*map, void *key, CMP_FUNC cmpf);

  51. #define map_find(map,key,cmpf)\
  52. __rbfind((map),(key),(cmpf))

  53. #define map_insert_alloc(map,key,priv,size,cmpf)\
  54. __rbinsert_alloc((map),(key),(priv),(size),(cmpf))

  55. #define map_remove_free(map,key,cmpf)\
  56. __rbremove_free((map),(key),(cmpf))

  57. #if 0
  58. #define map_insert(map,data,cmpf)\
  59. __rbinsert((map),(data),(cmpf))
  60. #define map_remove(map,key,cmpf)\
  61. __rbremove((map),(key),(cmpf))
  62. #endif


  63. #define map_entry(ptr, type, member) container_of(ptr, type, member)

  64. extern struct mnode *map_first(const struct map*map);
  65. extern struct mnode *map_last(const struct map*map);
  66. extern struct mnode *map_next(const struct mnode*mnode);
  67. extern struct mnode *map_prev(const struct mnode*mnode);

  68. extern void map_dump(const struct map* map);


  69. #endif
.............................................................................................
.............................................................................................

  1. /*
  2. * file: map.c
  3. * author: vincent.cws2008@gmail.com
  4. * history:
  5. * initial @ 2012-01-31
  6. */
  7. #define DEBUG
  8. #include "map.h"

  9. #define mnode_init(mnode){\
  10. (mnode)->node.rb_parent_color=0;\
  11. (mnode)->node.rb_right=0;\
  12. (mnode)->node.rb_left=0;\
  13. (mnode)->key=0;\
  14. (mnode)->private=0;\
  15. }


  16. void map_dump(const struct map* map)
  17. {
  18. struct mnode *mnode;
  19. int cnt=0;
  20. for (mnode= map_first(map); mnode; mnode= map_next(mnode))
  21. printf("key=%03d%s",*(int*)mnode->key,++cnt%10==0?"\n":" ");
  22. printf("\n");
  23. }


  24. static int __cmp_default(long*d1, long *d2)
  25. {
  26. // printf("-- d1:%d, d2:%d\n",*d1, *d2);
  27. if (*d1< *d2) return-1;
  28. else if(*d1 > *d2) return 1;
  29. else return 0;
  30. }

  31. struct mnode* __rbfind(struct map*map, void *key, CMP_FUNC cmpf)
  32. {
  33. int result;
  34. CMP_FUNC cmp;
  35. struct mnode *data;
  36. struct rb_node *node = map->root.rb_node;

  37. __assert(map && key);

  38. cmp = cmpf ? cmpf: __cmp_default;
  39. /* printf("==> entry %s key:%d\n", __func__,*(int*)key);*/
  40. while (node)
  41. {
  42. data = container_of(node, struct mnode, node);
  43. /* printf("data->key:%d VS key:%d\n",*(int*)(data->key),*(int*)key);*/
  44. result = cmp(key, data->key);
  45. /*printf("result=%d, node->rb_left=%p, node->rb_right=%p\n",
  46. result, node->rb_left, node->rb_right);*/
  47. if (result< 0)
  48. node = node->rb_left;
  49. else if(result > 0)
  50. node = node->rb_right;
  51. else
  52. return data;
  53. }
  54. //printf("node=%p\n", node);
  55. return NULL;
  56. }

  57. int __rbinsert(struct map*map, struct mnode*data, CMP_FUNC cmpf)
  58. {
  59. int result;
  60. struct mnode *this;
  61. CMP_FUNC cmp;
  62. struct rb_node **new= &(map->root.rb_node),*parent = NULL;

  63. __assert(map && data);

  64. cmp = cmpf ? cmpf: __cmp_default;

  65. /* Figure out whereto put new node */
  66. while (*new)
  67. {
  68. this = container_of(*new, struct mnode, node);
  69. result = cmp(data->key, this->key);

  70. parent = *new;
  71. if (result< 0) new = &((*new)->rb_left);
  72. else if(result > 0) new= &((*new)->rb_right);
  73. else return -2;
  74. }
  75. /* Add new nodeand rebalance tree.*/
  76. rb_link_node(&(data->node), parent, new);
  77. rb_insert_color(&(data->node),&(map->root));
  78. return 0;
  79. }

  80. int __rbremove(struct map*map, void *key, CMP_FUNC cmpf)
  81. {
  82. struct mnode* data = __rbfind(map, key, cmpf);
  83. __assert(map && key);
  84. if (data)
  85. rb_erase(&(data->node),&(map->root));
  86. return 0;
  87. }

  88. int __rbinsert_alloc(struct map*map, void *key,
  89. void *private, size_t size, CMP_FUNC cmpf)
  90. {
  91. struct mnode *new;
  92. __assert(map && key&& private);
  93. new = (struct mnode*)__malloc(size+sizeof(struct mnode));
  94. __assert(new);
  95. mnode_init(new);
  96. new->key= key;
  97. new->private= new+1;
  98. if (private)
  99. __memcpy(new->private,private, size);

  100. return __rbinsert(map, new, cmpf);
  101. }

  102. int __rbremove_free(struct map*map, void *key, CMP_FUNC cmpf)
  103. {
  104. struct mnode* data;
  105. __assert(map && key);
  106. data = __rbfind(map, key, cmpf);
  107. /* printf("%s: key: %d\n", __func__,*(int*)(data->key));*/
  108. if (data)
  109. {
  110. /* printf("%s: deleted!\n", __func__);*/
  111. rb_erase(&(data->node),&(map->root));
  112. __free(data);
  113. }
  114. return 0;
  115. }

  116. struct mnode *map_first(const struct map*map)
  117. {
  118. struct rb_node *node;
  119. __assert(map);
  120. node = rb_first(&(map->root));
  121. if(node)
  122. return map_entry(node, struct mnode, node);
  123. return NULL;
  124. }

  125. struct mnode *map_last(const struct map*map)
  126. {
  127. struct rb_node *node;
  128. __assert(map);
  129. node = rb_last(&(map->root));
  130. if(node)
  131. return map_entry(node, struct mnode, node);
  132. return NULL;
  133. }

  134. struct mnode *map_next(const struct mnode*mnode)
  135. {
  136. struct rb_node *node;
  137. __assert(mnode);
  138. node = rb_next(&(mnode->node));
  139. if(node)
  140. return map_entry(node, struct mnode, node);
  141. return NULL;
  142. }

  143. struct mnode *map_prev(const struct mnode*mnode)
  144. {
  145. struct rb_node *node;
  146. __assert(mnode);
  147. node = rb_prev(&(mnode->node));
  148. if(node)
  149. return map_entry(node, struct mnode, node);
  150. return NULL;
  151. }


  152. int map_init(struct map* map)
  153. {
  154. map->root.rb_node= NULL;
  155. lock_init(map->lock);
  156. return 0;
  157. }

  158. int map_exit(struct map* map)
  159. {
  160. lock_exit(map->lock);
  161. return 0;
  162. }