Redisデータ構造——SDS、チェーンテーブル
1943 ワード
単純な動的文字列
SDSはlen属性にSDS自体の長さを記録しているので,1つのSDS長を取得する複雑さはO(1)にすぎない.
SDSの空間割当てポリシーは,バッファオーバーフローの発生の可能性を完全に排除している.SDS APIがSDSを修正する必要がある場合、APIはまずSDSの空間が修正に必要な要求を満たしているかどうかをチェックし、満たさなければ、APIは自動的にSDSの空間を修正に必要な大きさに拡張してから、実際の修正操作を実行するので、
SDSは、SDSのスペースサイズを手動で変更する必要もなく、バッファオーバーフローの問題も発生しません.
SDSはfree未使用空間により文字列長と下位配列長との関連付けを解除する.SDSでは、buf配列の長さは必ずしも文字列数に1を加えたものではなく、配列に未使用のバイトを含めることができ、これらのバイトの配列にはSDSのfree属性レコードがある.
未使用空間を用いて,SDSは,空間事前分配と不活性空間解放の2つの最適化戦略を実現した.
Redisは文字列量としてC文字列のみを使用し、ほとんどの場合、Redisは文字列としてSDS(Simple Dynamic String、単純動的文字列)を使用します.
SDSは、C文字列よりも、以下の利点を有する.定数複雑度文字列長を取得します. バッファオーバーフローを防止します. 文字列の長さを変更して、必要なメモリの再割り当て回数を減らします. バイナリセキュリティ 互換部分C文字列関数 チェーンテーブル
Redisのチェーンテーブル実装の特性は以下のようにまとめることができる.
両端:チェーンテーブルノードにprevとnextポインタがあり、あるノードの前置ノードと後置ノードを取得する複雑さはO(1)である.
ループなし:ヘッダノードのprevポインタとテーブルエンドノードのnextポインタはNULLを指し、チェーンテーブルへのアクセスはNULLを終点とします.
ヘッダ付きポインタとヘッダ付きポインタ:list構造のheadポインタとtailポインタにより、プログラムが取得するチェーンテーブルのヘッダノードとヘッダノードの複雑度はO(1)である.
チェーンテーブル長カウンタ付き:プログラムはlist構造のlen属性を使用してlistが持つチェーンテーブルノードをカウントし、プログラム取得チェーンテーブル中のノード数の複雑度はO(1)である.
マルチステート:チェーンテーブルノードはvoid*ポインタを使用してノード値を保存し、list構造のdup,free,matchの3つの属性でノード値にタイプ固有の関数を設定できるので、チェーンテーブルはさまざまなタイプの値を保存するために使用できます.
struct sdshdr {
unsigned int len; // buf SDS
unsigned int free; // buf
char buf[]; // ,
};
SDSはlen属性にSDS自体の長さを記録しているので,1つのSDS長を取得する複雑さはO(1)にすぎない.
SDSの空間割当てポリシーは,バッファオーバーフローの発生の可能性を完全に排除している.SDS APIがSDSを修正する必要がある場合、APIはまずSDSの空間が修正に必要な要求を満たしているかどうかをチェックし、満たさなければ、APIは自動的にSDSの空間を修正に必要な大きさに拡張してから、実際の修正操作を実行するので、
SDSは、SDSのスペースサイズを手動で変更する必要もなく、バッファオーバーフローの問題も発生しません.
SDSはfree未使用空間により文字列長と下位配列長との関連付けを解除する.SDSでは、buf配列の長さは必ずしも文字列数に1を加えたものではなく、配列に未使用のバイトを含めることができ、これらのバイトの配列にはSDSのfree属性レコードがある.
未使用空間を用いて,SDSは,空間事前分配と不活性空間解放の2つの最適化戦略を実現した.
Redisは文字列量としてC文字列のみを使用し、ほとんどの場合、Redisは文字列としてSDS(Simple Dynamic String、単純動的文字列)を使用します.
SDSは、C文字列よりも、以下の利点を有する.
typedef struct listNode {
struct listNode *prev; //
struct listNode *next; //
void *value; //
} listNode;
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 long len; //
} list;
Redisのチェーンテーブル実装の特性は以下のようにまとめることができる.
両端:チェーンテーブルノードにprevとnextポインタがあり、あるノードの前置ノードと後置ノードを取得する複雑さはO(1)である.
ループなし:ヘッダノードのprevポインタとテーブルエンドノードのnextポインタはNULLを指し、チェーンテーブルへのアクセスはNULLを終点とします.
ヘッダ付きポインタとヘッダ付きポインタ:list構造のheadポインタとtailポインタにより、プログラムが取得するチェーンテーブルのヘッダノードとヘッダノードの複雑度はO(1)である.
チェーンテーブル長カウンタ付き:プログラムはlist構造のlen属性を使用してlistが持つチェーンテーブルノードをカウントし、プログラム取得チェーンテーブル中のノード数の複雑度はO(1)である.
マルチステート:チェーンテーブルノードはvoid*ポインタを使用してノード値を保存し、list構造のdup,free,matchの3つの属性でノード値にタイプ固有の関数を設定できるので、チェーンテーブルはさまざまなタイプの値を保存するために使用できます.