バイナリデータとビット単位の状態を管理する
13683 ワード
ビット単位のOP、それは何ですか?
A bitwise operation that operates on a bit string, a bit array, or a binary numeral at the level of individual bits - Wikipedia
なぜバイナリの状態を保存?
シリアル化されたバイナリ形式のデータのエンコードは、文字列形式よりも効率的です.だからこそ、GOBやProtobufsのようなデータエンコーダはJSON & XMLよりも効率的です.
データを保存するために必要なスペースの量を減らします.彼らはフィールド名や空白のようなスペースを取る余分なゴミを含んでいない.
状態を保存したり、バイナリ形式でデータをシリアル化するという欠点は、厳格さです.彼らは厳密な形式に従っているので、両方のエンコーダ&デコーダは、データ形式に新しい変更を処理する方法を更新する必要があります.
さあ、私たちには
position
つのタイプint 8フィールド(半径、経度、および緯度)のみを持つ.バイナリ形式のフィールドを{toBinary(rad)}{toBinary(lat)}{toBinary(long)}
If the radius
30(11110)latitude
は20(10100)でありlongitude
50(110010)私たちのシリアル化されたバイナリ形式で保存{toBinary(30)}{toBinary(20)}{toBinary(50)} = {00011110}{00010100}{00110010} = 000111100001010000110010
それは16進数で表される1e1432
JSONでこれを保存するならば{"rad":30,"lat":20, "long": 50}
JSON形式はバイナリ形式より多くのメモリを受け取り、フィールド名のスペースを必要としますが、バイナリ形式では、フィールドがバイトの位置に基づいてどこに属しているかわかります.これは二値の状態を記憶する空間効率を示した.私たちがもはや位置オブジェクトで半径フィールドを必要としないと言いましょう.
JSON形式を使用した場合、radiusフィールドを削除するとエンコードとデコード規則には影響しません.
我々が以前からバイナリ直列化された形式を使用するならば、我々はエンコーダとデコーダが半径分野への変化を意識していることを確認しなければなりません.
ときに
{toBinary(rad)}{toBinary(lat)}{toBinary(long)}
うん、もう一つは{toBinary(lat)}{toBinary(long)}
注意*フィールドのVaulesとデータの不一致が正確にエンコード/デコードされません.エンコーダとデコーダが同期していないならば、我々は最初のバイトとして0を通過しなければなりません.これを行うと、以前の位置オブジェクトの書式を保持し、最新の状態で無視できます.
簡易ユースケース
我々は、グループやメディア(SMS、メール、プッシュ)のグループ通知を通知サービスがあります.
この通知サービスは、預金と引き出しの2つの通知の種類があります.
{
"deposit": {
"push": {
"state": true,
"can_edit": true
},
"email": {
"state": true,
"can_edit": false
},
"sms": {
"state": true,
"can_edit": false
}
},
"withdrawal": {
"push": {
"state": true,
"can_edit": true
},
"email": {
"state": true,
"can_edit": false
}
}
}
ですから、JSONオブジェクトをバイナリシリアル化形式で保存する方法を考え出すことです.このようなもの0001011100000111
JSONから行く→バイナリ
バイナリは0と1だけで構成され、これはブール値を表すことができます.バイナリのあらゆるビット位置は2の力です.そして、ちょうど10進の各々の位置が10(1 , 10100)の力であるように.
上記のJSON表現をバイナリにフォーマットするには、まず通知カテゴリの内容を平らにします.
{
"deposit": {
"push_state": true,
"push_can_edit": true,
"email_state": true,
"email_can_edit": false,
"sms_state": true,
"sms_can_edit": false
},
"withdrawal": {
"push_state": true,
"push_can_edit": true,
"email_state": true,
"email_can_edit": false,
"sms_state": false, //false cus it's empty
"sms_can_edit": false//false cus it's empty
}
}
それが平らになったので、我々はバイトで各々のフィールドを代表したいです.バイトが個々のビットとしてフィールドを表すことができるように、バイトは8ビットでできています.フィールドタイプはBOOLですので
1
表すtrue
and 0
表すfalse
.そこでフィールドをビット位置にマップします.
push_state => 1st bit
push_can_edit => 2nd bit
email_state => 3rd bit
email_can_edit => 4th bit
sms_state => 5th bit
sms_can_edit => 6th bit
現在の通知設定を表すことができます{
"deposit": "00010111",
"withdrawal": "00000111"
}
上記のJSONをバイト単位で変更したい([]バイト).これを行うには、通知カテゴリのバイト配列にインデックス位置を設定する必要があります.長さ2(2つの通知カテゴリー)の私たちのバイト配列のために.
deposit_vaue
配列内の1番目の値となりますwithdrawal_value
二番目.[]byte{deposit_value,withdrawal_value}
[]byte{0b00010111,0b00000111} = 0001011100000111 = 0x1707
今、我々は最終的に我々の通知設定を表すことができます0001011100000111 #binary format
1707 #hexidecimal format
[]byte{23,7} #in code
set , unset & check演算子
通知設定オブジェクトを保存するためにバイナリシリアル化形式を持っているので、次のステップは通知設定のバイナリ表現を更新します.それを電話しましょう
bitNotifcationSetting
.私たちはセットを使用し、unset&ビット演算子をチェックしてビットのビットを操作する
bitNotifcationSetting
.セット演算子:これを1秒に設定する.
set_op(data, nth_flag) => data | nth_flag
Unset演算子:このとき、n番目のビットを0に設定します.unset_op(data, nth_flag) => data & ^(nth_flag)
チェックビット演算子:これをチェックします.check_bit_op(data, nth_flag) => (data & (nth_flag) != 0
golang playground example 通知媒体状態の更新
SMS状態を更新したいとしましょう.
チェックサムBittleオペ(*)
to c*heck if the
` ssSum状態`ビットは編集可能です.set_op(bitNotifcationSetting, sms_state_flag)
設定するsms_state
ビットを1/trueまたは呼び出しunset_op(bitNotifcationSetting, sms_state_flag)
セットsms_state
ビットを0にする結論
ここで使用されるバイナリ形式は、使用されるメモリスペースを減らすのを助けることができて、キャッシュをより多くの最近の値に対応するためにクリーンアップする必要なしで、メモの通知設定についてのさらなる情報を保持することができます.
ここで使用している例は、フィールドタイプがBooleanで、ビットを取るので簡単です.可変長の文字列と型のようなより複雑な型に対して、バイナリ形式を使用すると、外部ライブラリの助けなしで自分で管理するのは少し難しいでしょう.
もっと複雑な方法でBitcoin encodes transaction バイナリ形式へのオブジェクト.
続きを読む
Reference
この問題について(バイナリデータとビット単位の状態を管理する), 我々は、より多くの情報をここで見つけました https://dev.to/kayslaycode/managing-state-with-binary-data-bitwise-op-lcoテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol