redisが使用するビットドメイン


redisが使用するビットドメイン
今日redisソースを見ていると3.0バージョンのredisです.hファイルにはこのような数行のコードが発見され、面白さを見て、研究してみると、これがc言語のビットドメインであることが分かった.
/*
 * redisObject Redis  
 */ 
typedef struct redisObject {

	unsigned type : 4; //   

	unsigned encoding : 4; //   

	unsigned lru : REDIS_LRU_BITS; //             

	int refcount; //     

	void *ptr; //         
} robj;



この概念について、整理した内容は以下の部分があります.
ビットドメインとは
一部の情報は、格納時に完全なバイトを占有する必要はなく、数または1つのバイナリビットを占有するだけです.例えば、1つのスイッチング量を格納する場合、0と1の2つの状態だけで、1ビットの2進位でよい.記憶領域を節約し、処理を簡便にするために、C言語は「ビットドメイン」または「ビットセグメント」と呼ばれるデータ構造を提供する.「ビットドメイン」とは、1バイトのバイナリビットをいくつかの異なる領域に分割し、各領域のビット数を説明するものである.各ドメインにはドメイン名があり、プログラム内でドメイン名で操作できます.これにより,いくつかの異なるオブジェクトを1バイトのバイナリビットドメインで表すことができる.一、ビットドメインの定義とビットドメイン変数の説明ビットドメイン定義は構造定義と似ており、その形式は以下の通りである.

struct       
{      };

          :          :     
  : 

struct bs
{
	int a:8;
	int b:2;
	int c:6;
};

ビットドメイン変数の説明は、構造変数の説明と同じです.先に定義してから説明し、同時に説明を定義したり、直接説明したりする3つの方法を採用することができます.例:
struct bs
{
	int a:8;
	int b:2;
	int c:6;
}data;

説明dataはbs変数で、2バイトを占めています.ここで、ビットドメインaは8ビット、ビットドメインbは2ビット、ビットドメインcは6ビットを占める.ビットドメインの定義については、以下の説明があります.
1
  • ビットドメインは、2バイトにまたがることができない同じバイトに格納する必要があります.1バイトの空き領域が他のビットドメインを格納するのに足りない場合は、次のユニットからビットドメインを格納する必要があります.あるビットドメインを次のユニットから意図的に開始させることもできます.例:
  • struct bs
    {
    	unsigned a:4
    	unsigned :0 /*  */
    	unsigned b:4 /*         */
    	unsigned c:4
    }
    

    このビットドメイン定義では、aは第1バイトの4ビットを占め、後4ビットは0を記入して使用しないことを示し、bは第2バイトから4ビットを占有し、cは4ビットを占有する.
  • ビットドメインは2バイトにまたがることを許さないため、ビットドメインの長さは1バイトの長さより大きくすることはできない.すなわち、8ビットバイナリビットを超えることはできない.

  • ビットドメインは、ビットドメイン名を持たずに使用できます.この場合、位置の入力または調整にのみ使用されます.無名のビットドメインは使用できません.例:
  • struct k
    {
    	int a:1
    	int :2 /* 2     */
    	int b:3
    	int c:2
    };
    

    以上の解析から,ビットドメインは本質的に構造タイプであるが,そのメンバーはバイナリビットで割り当てられていることがわかる.
    二、ビットドメインの使用ビットドメインの使用と構造メンバーの使用は同じで、その一般的な形式は:ビットドメイン変数名・ビットドメイン名ビットドメインは各種のフォーマットで出力することを許可する.次はサンプルコードです
    #include 
    int main()
    {
    	struct bs
    	{
    		unsigned a:1;
    		unsigned b:3;
    		unsigned c:4;
    	} bit, *pbit;
    
    	bit.a=1;
    	bit.b=7;
    	bit.c=15;
    	printf("%d,%d,%d
    "
    ,bit.a,bit.b,bit.c); //1 7 15 pbit=&bit; pbit->a=0; pbit->b&=3; pbit->c|=1; printf("%d,%d,%d
    "
    ,pbit->a,pbit->b,pbit->c); //0 3 15 }

    上記の例のプログラムでは、ビットドメイン構造bsが定義され、3つのビットドメインはa,b,cである.bsタイプの変数bitとbsタイプを指すポインタ変数pbitについて説明した.これは、ビットドメインもポインタを使用できることを示します.プログラムの9,10,11の3行はそれぞれ3つのビットドメインに値を付与する.(このビットドメインの許容範囲を超えてはならないことに注意してください)プログラム12行目は、3つのドメインの内容を整数形式で出力します.13行目はビットドメイン変数bitのアドレスをポインタ変数pbitに送る.14行目はポインタ方式でビットドメインaに値を再付与し、0に付与する.15行目には、pbit->b=pbit->b&3ビットドメインbの値が7であり、3とビットと演算された結果が3(111&011=011、10進数値が3)に相当する複合ビット演算子「&=」が使用される.同様に,プログラム16行目に複合ビット演算"|="が用いられ,pbit->c=pbit->c|1の結果が15であることに相当する.プログラム17行目はポインタ方式でこの3つのドメインの値を出力した.
    以上のコードを修正してbit.a = 1; bitに変更します.a = 3; 何が起こるの?私が使っているコンパイラgccは、範囲を超えていると警告します!!!でも強引にプリントアウトした値は0!!;
    以上