redisソースの浅見のsds

1781 ワード

sdsはredisプロジェクトが文字列操作に基づいてカプセル化されたライブラリであり、その公式解釈は「SDSLib 2.0--A C dynamic strings library」である.
公式にソースコードをダウンロードした後、コードクラウドRedisにアップロードし、ヘッダファイルとソースファイルの接続は以下の通りである.
sds.h
sds.c 
C言語の文字列操作ペアを保持するとともに、メモリ管理を実現し、使用コストを節約することを考えています.
実現原理:structが長くなる.
typedef char *sds;
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};

全部で5つの構造で、他の4つは大同小異で、sdshdr 5にはlenとallocの2人のメンバーがなく、flag取得タイプへのアクセスのみをしています.
他の3つの違いは、lenとallocの2つのメンバーのタイプが異なり、対応するbufメンバーの記憶データ量も異なり、一部の機種ではsdshdr 32とsdshdr 64が同じである可能性があることです.
操作の統一性のために、各structは、flagsメンバーの下位3ビットに一意のflagを格納する.
メンバーの解析:
-len:文字列の長さ、'0'、'0'は含まれていません.ユーザーは関心を持つ必要はありません.
-alloc:申請されたメモリ領域のサイズ;
-flags:タイプ、現在は低3ビットしか使用されていません.その後、現在のsdsに対応するヘッダのタイプを判断するために拡張される可能性があります.
-buf:長くなり、データが格納されます.
 
巧妙な点:
1.C言語の文字列ペアの操作を保証するために、bufは'char*'と定義され、作成関数はbufメンバーに対応するメモリアドレスを返し、操作に直接アクセスすることができるが、typedefを使用してsdsと名前を変更するだけである.
2.bufはflagsタイプと同じであり、アドレス配列関係からbuf[-1]がちょうどflags対応のメモリ空間であり、flagsによりstructタイプが得られ、さらにbuf対応のヘッダが推定される.ヘッダーが取得されると、すべてのメンバーが任意にアクセスできます.
3.sdsは一連の操作関数を定義し、print族関数が比較的重いことを考慮してstdargを結合した.hは推奨バージョンのprintシリーズを実現した.
 
sdsコードの読み取りの難点は3つあります:長くなるstrcut、アドレス変換、define
長くなる構造:C言語の特徴、使用方法はネット上でたくさん検索することができます;
アドレス変換:structのメモリレイアウト;
define:sdshdrはデジタルシリーズであり、「###」と組み合わせて対応する構造名をつづることができる
#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (void*)((s)-(sizeof(struct sdshdr##T)));
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))

 
PS:redisソースを読んで、特に記憶して、堅持してください.