2単純な動的文字列

3126 ワード

Redisは、単純動的文字列(simple dynamic string, SDS)という抽象型を構築し、SDSredisのデフォルト文字列表現として使用する.RedisC文字列は、データベース内の文字列を保存するために使用されるほか、SDSがバッファ(buffer)として使用される文字列の字面量としてのみ使用されます.
2.1 SDSの定義sds.h/sdshdr構造は、SDSの値を表します.
struct sdshdr{
    //  buf           
    //  SDS          
    int len;
    //  buf           
    int free;
    //    ,       
    char buf[];
};
SDSは、C文字列が空白文字で終わる慣例に従うが、この動作はSDS関数によって自動的に行われる.
2.2 SDSC文字列の違いC言語は長さN+1の文字配列を使用して長さNの文字列を表し、文字配列の最後の要素が常に空の文字列'\0' C言語で使用される文字列は、Redisの文字列に対する安全性、効率、および機能の要件を満たすことができない.
2.2.1定数複雑度取得文字列長C文字列は、自身の長さ情報を記録せず、C文字列の長さを取得し、プログラムは文字列全体を遍歴しなければならない.この動作の時間的複雑さはO(N)である.SDSは、lenの属性にSDS自体の長さを記録しているので、SDSの長さを取得する複雑さはO(1)にすぎない.SDSの長さを設定および更新する作業は、SDSAPIが実行時に自動的に完了し、SDSを使用して長さを手動で変更する作業は必要ありません.
2.2.2バッファオーバーフローの防止C文字列が自身の長さを記録しないことによるもう一つの問題は、バッファオーバーフロー(buffer overflow)を生じやすいことである.C文字列とは異なり、SDSの空間割り当てポリシーはバッファオーバーフローの発生の可能性を完全に根絶している:SDS APISDSを修正する必要がある場合、APIはまずSDS空間が修正に必要な要求を満たしているかどうかを検査し、満足していない場合、APIは、SDSの空間を自動的に変更を実行するために必要なサイズに拡張してから、実際の変更操作を実行するので、SDSを使用すると、SDSの空間サイズを手動で変更する必要もなく、前述したバッファオーバーフローの問題も発生しません.
2.2.3文字列の変更に伴うメモリの再割り当て回数を減らすSDS未使用空間により文字列長と下位データ長との関連が解除された:SDSでは、buf配列の長さは必ずしも文字数に1を加えたものではなく、配列には未使用のバイトを含めることができ、これらのバイトの数はSDSfree属性によって記録される.空間を使用しないことによって,SDSは空間事前割り当てと不活性空間放出の2つの最適化戦略を実現した.
1.空間の事前割り当て
空間事前割り当てSDSの文字列成長動作を最適化するために使用される:SDSAPIが1つのSDSを修正し、SDSを空間拡張する必要がある場合、プログラムはSDSが修正に必要な空間を割り当てるだけでなく、SDSの割り当て額以外の未使用空間も割り当てる.空間事前割り当てポリシーにより、Redisは、文字列成長操作を連続的に実行するために必要なメモリ再割り当て回数を低減することができる.SDSスペースを拡張する前に、SDS APIは未使用スペースが十分かどうかを確認し、十分であれば、APIはメモリ再割り当てを実行することなく、未使用スペースを直接使用します.
2.不活性空間解放
不活性空間解放SDSの文字列短縮動作を最適化するために使用される:SDSAPISDS保存した文字列を短縮する必要がある場合、プログラムは直ちにメモリ再割り当てを使用して短縮されたバイトを回収するのではなく、free属性を使用してこれらのバイトの数を記録し、将来の使用を待つ.不活性空間解放ポリシーにより、SDSは、文字列を短縮するために必要なメモリ再割り当て操作を回避し、将来可能な増加操作を最適化します.SDSも対応するAPIを提供し、必要に応じてSDSの未使用空間を本当に解放する.
2.2.4バイナリセキュリティSDSAPIはすべてバイナリで安全であり、すべてのSDS APISDSbuf配列に格納されたデータをバイナリで処理する.Redisbufは、文字を保存するのではなく、一連のバイナリデータを保存するために使用される.これは,SDSbuf属性をバイト配列と呼ぶ理由である.
2.2.5互換部分C文字列関数