redis6.0ソースデュアルエンドチェーンテーブル
21014 ワード
redisではリストキー、パブリケーションとサブスクリプション、スロークエリー、モニタなどにチェーンテーブルが使用され、Redisサーバ自体はチェーンテーブルで複数のクライアントの状態情報を保存し、チェーンテーブルを使用してクライアント出力バッファを構築します.
チェーンテーブルノードadlist.h/listNode
チェーンテーブル操作
新しいチェーンテーブルの作成
ノードを含まない新しいチェーンテーブルを作成
チェーンテーブルヘッダに新しいノードを挿入
チェーンテーブルの末尾に新しいノードを挿入
list構造マクロ実装の関数
反復器 listNodeは、特定のノード情報 である. direction遍歴方向AL_START_HEADは頭から尾へAL_を遍歴するSTART_TAILは尾部から頭部に向かって を遍歴する.
チェーンテーブルに基づいて反復器を得る
かいほう反復器
チェーンテーブルとkeyが一致するノードのクエリー
もっと説明して、私のgithub:go成神の道に注目してください.
チェーンテーブルノードadlist.h/listNode
typedef struct listNode {
struct listNode *prev;//
struct listNode *next;//
void *value;//
} listNode;
typedef struct list {
listNode *head;//
listNode *tail;//
//
void *(*dup)(void *ptr);
//
void (*free)(void *ptr);
//
int (*match)(void *ptr, void *key);
unsigned long len;
} list;
チェーンテーブル操作
新しいチェーンテーブルの作成
ノードを含まない新しいチェーンテーブルを作成
list *listCreate(void)
{
struct list *list;
//
if ((list = zmalloc(sizeof(*list))) == NULL)
return NULL;
//
list->head = list->tail = NULL;
list->len = 0;
list->dup = NULL;
list->free = NULL;
list->match = NULL;
return list;
}
チェーンテーブルヘッダに新しいノードを挿入
list *listAddNodeHead(list *list, void *value)
{
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
list->head = list->tail = node;
node->prev = node->next = NULL;
} else {
node->prev = NULL;
node->next = list->head;
list->head->prev = node;
list->head = node;
}
list->len++;
return list;
}
チェーンテーブルの末尾に新しいノードを挿入
list *listAddNodeTail(list *list, void *value)
{
listNode *node;
if ((node = zmalloc(sizeof(*node))) == NULL)
return NULL;
node->value = value;
if (list->len == 0) {
list->head = list->tail = node;
node->prev = node->next = NULL;
} else {
node->prev = list->tail;
node->next = NULL;
list->tail->next = node;
list->tail = node;
}
list->len++;
return list;
}
list構造マクロ実装の関数
/* 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))
#define listGetDupMethod(l) ((l)->dup)
#define listGetFreeMethod(l) ((l)->free)
#define listGetMatchMethod(l) ((l)->match)
反復器
typedef struct listIter {
listNode *next;
int direction;
} listIter;
チェーンテーブルに基づいて反復器を得る
listIter *listGetIterator(list *list, int direction)
{
listIter *iter;
if ((iter = zmalloc(sizeof(*iter))) == NULL) return NULL;
if (direction == AL_START_HEAD)
iter->next = list->head;
else
iter->next = list->tail;
iter->direction = direction;
return iter;
}
かいほう反復器
void listReleaseIterator(listIter *iter) {
zfree(iter);
}
listNode *listNext(listIter *iter)
{
listNode *current = iter->next;
if (current != NULL) {
if (iter->direction == AL_START_HEAD)
iter->next = current->next;
else
iter->next = current->prev;
}
return current;
}
チェーンテーブルとkeyが一致するノードのクエリー
listNode *listSearchKey(list *list, void *key)
{
listIter iter;
listNode *node;
// ->
listRewind(list, &iter);
//
while((node = listNext(&iter)) != NULL) {
if (list->match) {
if (list->match(node->value, key)) {
return node;
}
} else {
if (key == node->value) {
return node;
}
}
}
return NULL;
}
もっと説明して、私のgithub:go成神の道に注目してください.