adlist是redis自己是實現的一個通用的雙向鏈表。
------------------------------------------------adlist.h---------------------------------------------------
#ifndef __ADLIST_H__ #define __ADLIST_H__ /* Node, List, and Iterator are the only data structures used currently. */ typedef struct listNode { struct listNode * prev; struct listNode * next; void * value; } listNode; 雙向鏈表,存的結構是一個指針void * typedef struct listIter { listNode * next; int direction; } listIter; 迭代器,可以向前遍歷,也可以向后遍歷; typedef struct list { listNode * head; listNode * tail; void *(*dup)( void * ptr); void (*free)( void * ptr); int (*match)( void *ptr, void * key); unsigned int len; } list; 鏈表本身的結構,頭、尾指針,同時一個函數指針dup用于在復制鏈表(list or listNode ? )調用,一個函數指針free在釋放鏈表時調用,一個函數指針match用來作匹配時調用,以及一個記錄鏈表長度的字段;注意三個函數指針是list的成員,也就是被所有list node共用,因此listNode應該具有共性。 /* Functions implemented as macros */ #define listLength(l) ((l)->len) 鏈表長度 #define listFirst(l) ((l)->head) 鏈表的第一個結點 #define listLast(l) ((l)->tail) 鏈表的最后一個結點 #define listPrevNode(n) ((n)->prev) 當前結點的前一個結點 #define listNextNode(n) ((n)->next) 當前結點的后一個結點 #define listNodeValue(n) ((n)->value) 當前結點的值 #define listSetDupMethod(l,m) ((l)->dup = (m)) #define listSetFreeMethod(l,m) ((l)->free = (m)) #define listSetMatchMethod(l,m) ((l)->match = (m)) set三個函數指針的方法 #define listGetDupMethod(l) ((l)->dup) #define listGetFree(l) ((l)->free) #define listGetMatchMethod(l) ((l)->match) get三個函數指針的方法 /* Prototypes */ list *listCreate( void ); 創建鏈表 void listRelease(list * list); 釋放鏈表 list *listAddNodeHead(list *list, void * value); 在表頭加一個結點 list *listAddNodeTail(list *list, void * value); 在表尾加一個結點 list *listInsertNode(list *list, listNode *old_node, void *value, int after); void listDelNode(list *list, listNode * node); listIter *listGetIterator(list *list, int direction); listNode *listNext(listIter * iter); void listReleaseIterator(listIter * iter); list *listDup(list * orig); listNode *listSearchKey(list *list, void * key); listNode *listIndex(list *list, int index); void listRewind(list *list, listIter * li); void listRewindTail(list *list, listIter * li); /* Directions for iterators */ #define AL_START_HEAD 0 #define AL_START_TAIL 1 定義迭代器方向 #endif /* __ADLIST_H__ */
?
?
------------------------------------------------adlist.c---------------------------------------------------
1 #include <stdlib.h> 2 #include " adlist.h " 3 #include " zmalloc.h " //redis對內存分配庫函數的一個封裝,用于stat目的 4 5 /* Create a new list. The created list can be freed with 6 * AlFreeList(), but private value of every node need to be freed 7 * by the user before to call AlFreeList(). 8 * 9 * On error, NULL is returned. Otherwise the pointer to the new list. */ 10 list *listCreate( void ) 11 { 12 struct list * list; 13 14 if ((list = zmalloc( sizeof (*list))) == NULL) 15 return NULL; 16 list->head = list->tail = NULL; 17 list->len = 0 ; 18 list->dup = NULL; 19 list->free = NULL; 20 list->match = NULL; 21 return list; 22 } //這個函數創建的list是個裸的list,三個函數指針需要自行調用set賦值 23 24 /* Free the whole list. 25 * 26 * This function can't fail. */ 27 void listRelease(list * list) 28 { 29 unsigned int len; 30 listNode *current, * next; 31 32 current = list-> head; 33 len = list-> len; 34 while (len-- ) { 35 next = current-> next; 36 if (list->free) list->free(current-> value); // 37 zfree(current); 38 current = next; 39 } 40 zfree(list); 41 } //先用free釋放listNode中保存的元素,然后釋放結點,最后釋放鏈表本身。在鏈表操作中,注意在釋放當前結點時,需要保存后續結點的值 42 43 /* Add a new node to the list, to head, contaning the specified 'value' 44 * pointer as value. 45 * 46 * On error, NULL is returned and no operation is performed (i.e. the 47 * list remains unaltered). 48 * On success the 'list' pointer you pass to the function is returned. */ 49 list *listAddNodeHead(list *list, void * value) 50 { 51 listNode * node; 52 53 if ((node = zmalloc( sizeof (*node))) == NULL) 54 return NULL; 55 node->value = value; 56 if (list->len == 0 ) { 57 list->head = list->tail = node; 58 node->prev = node->next = NULL; 59 } else { 60 node->prev = NULL; 61 node->next = list-> head; 62 list->head->prev = node; 63 list->head = node; 64 } 65 list->len++ ; 66 return list; 67 } 68 69 /* Add a new node to the list, to tail, contaning the specified 'value' 70 * pointer as value. 71 * 72 * On error, NULL is returned and no operation is performed (i.e. the 73 * list remains unaltered). 74 * On success the 'list' pointer you pass to the function is returned. */ 75 list *listAddNodeTail(list *list, void * value) 76 { 77 listNode * node; 78 79 if ((node = zmalloc( sizeof (*node))) == NULL) 80 return NULL; 81 node->value = value; 82 if (list->len == 0 ) { 83 list->head = list->tail = node; 84 node->prev = node->next = NULL; 85 } else { 86 node->prev = list-> tail; 87 node->next = NULL; 88 list->tail->next = node; 89 list->tail = node; 90 } 91 list->len++ ; 92 return list; 93 } 94 95 list *listInsertNode(list *list, listNode *old_node, void *value, int after) { 96 listNode * node; 97 98 if ((node = zmalloc( sizeof (*node))) == NULL) 99 return NULL; 100 node->value = value; 101 if (after) { 102 node->prev = old_node; 103 node->next = old_node-> next; 104 if (list->tail == old_node) { 105 list->tail = node; 106 } 107 } else { 108 node->next = old_node; 109 node->prev = old_node-> prev; 110 if (list->head == old_node) { 111 list->head = node; 112 } 113 } 114 if (node->prev != NULL) { 115 node->prev->next = node; 116 } 117 if (node->next != NULL) { 118 node->next->prev = node; 119 } 120 list->len++ ; 121 return list; 122 } 123 124 /* Remove the specified node from the specified list. 125 * It's up to the caller to free the private value of the node. 126 * 127 * This function can't fail. */ 128 void listDelNode(list *list, listNode * node) 129 { 130 if (node-> prev) 131 node->prev->next = node-> next; 132 else 133 list->head = node-> next; 134 if (node-> next) 135 node->next->prev = node-> prev; 136 else 137 list->tail = node-> prev; 138 if (list->free) list->free(node-> value); 139 zfree(node); 140 list->len-- ; 141 } 142 143 /* Returns a list iterator 'iter'. After the initialization every 144 * call to listNext() will return the next element of the list. 145 * 146 * This function can't fail. */ 147 listIter *listGetIterator(list *list, int direction) 148 { 149 listIter * iter; 150 151 if ((iter = zmalloc( sizeof (*iter))) == NULL) return NULL; 152 if (direction == AL_START_HEAD) 153 iter->next = list-> head; 154 else 155 iter->next = list-> tail; 156 iter->direction = direction; 157 return iter; 158 } 159 160 /* Release the iterator memory */ 161 void listReleaseIterator(listIter * iter) { 162 zfree(iter); 163 } 164 165 /* Create an iterator in the list private iterator structure */ 166 void listRewind(list *list, listIter * li) { 167 li->next = list-> head; 168 li->direction = AL_START_HEAD; 169 } 170 171 void listRewindTail(list *list, listIter * li) { 172 li->next = list-> tail; 173 li->direction = AL_START_TAIL; 174 } 175 176 /* Return the next element of an iterator. 177 * It's valid to remove the currently returned element using 178 * listDelNode(), but not to remove other elements. 179 * 180 * The function returns a pointer to the next element of the list, 181 * or NULL if there are no more elements, so the classical usage patter 182 * is: 183 * 184 * iter = listGetIterator(list,<direction>); 185 * while ((node = listNext(iter)) != NULL) { 186 * doSomethingWith(listNodeValue(node)); 187 * } 188 * 189 * */ 190 listNode *listNext(listIter * iter) 191 { 192 listNode *current = iter-> next; 193 194 if (current != NULL) { 195 if (iter->direction == AL_START_HEAD) 196 iter->next = current-> next; 197 else 198 iter->next = current-> prev; 199 } 200 return current; 201 } //注意這個函數,如果對返回值作delete操作,iter并未失效 202 203 /* Duplicate the whole list. On out of memory NULL is returned. 204 * On success a copy of the original list is returned. 205 * 206 * The 'Dup' method set with listSetDupMethod() function is used 207 * to copy the node value. Otherwise the same pointer value of 208 * the original node is used as value of the copied node. 209 * 210 * The original list both on success or error is never modified. */ 211 list *listDup(list * orig) 212 { 213 list * copy; 214 listIter * iter; 215 listNode * node; 216 217 if ((copy = listCreate()) == NULL) 218 return NULL; 219 copy->dup = orig-> dup; 220 copy->free = orig-> free; 221 copy->match = orig-> match; 222 iter = listGetIterator(orig, AL_START_HEAD); 223 while ((node = listNext(iter)) != NULL) { 224 void * value; 225 226 if (copy-> dup) { 227 value = copy->dup(node-> value); 228 if (value == NULL) { 229 listRelease(copy); 230 listReleaseIterator(iter); 231 return NULL; 232 } 233 } else 234 value = node-> value; 235 if (listAddNodeTail(copy, value) == NULL) { 236 listRelease(copy); //這里疑似有內存泄露,如果copy->dup被指定,并為value成功分配了內存,但addNodeTail的時候失敗了,這塊內存就沒人管了。 237 listReleaseIterator(iter); 238 return NULL; 239 } 240 } 241 listReleaseIterator(iter); 242 return copy; 243 } //如果沒有指定dup函數則是個淺拷貝,否則是個深拷貝。 244 245 /* Search the list for a node matching a given key. 246 * The match is performed using the 'match' method 247 * set with listSetMatchMethod(). If no 'match' method 248 * is set, the 'value' pointer of every node is directly 249 * compared with the 'key' pointer. 250 * 251 * On success the first matching node pointer is returned 252 * (search starts from head). If no matching node exists 253 * NULL is returned. */ 254 listNode *listSearchKey(list *list, void * key) 255 { 256 listIter * iter; 257 listNode * node; 258 259 iter = listGetIterator(list, AL_START_HEAD); 260 while ((node = listNext(iter)) != NULL) { 261 if (list-> match) { 262 if (list->match(node-> value, key)) { 263 listReleaseIterator(iter); 264 return node; 265 } 266 } else { 267 if (key == node-> value) { 268 listReleaseIterator(iter); 269 return node; 270 } 271 } 272 } 273 listReleaseIterator(iter); 274 return NULL; 275 } //O(n)的復雜度,n是鏈表長度 276 277 /* Return the element at the specified zero-based index 278 * where 0 is the head, 1 is the element next to head 279 * and so on. Negative integers are used in order to count 280 * from the tail, -1 is the last element, -2 the penultimante 281 * and so on. If the index is out of range NULL is returned. */ 282 listNode *listIndex(list *list, int index) { 283 listNode * n; 284 285 if (index < 0 ) { 286 index = (-index)- 1 ; //注意從后邊往前數時index的處理 287 n = list-> tail; 288 while (index-- && n) n = n-> prev; 289 } else { 290 n = list-> head; 291 while (index-- && n) n = n-> next; 292 } 293 return n; 294 }
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
