import (
"encoding/binary"
)
const batchHeaderLen = 12
const invalidBatchCount = 1<<32 - 1
// Batch is a sequence of Sets and/or Deletes that are applied atomically.
type Batch struct {
// Data is the wire format of a batch's log entry:
// - 8 bytes for a sequence number of the first batch element,
// or zeroes if the batch has not yet been applied,
// - 4 bytes for the count: the number of elements in the batch,
// or "\xff\xff\xff\xff" if the batch is invalid,
// - count elements, being:
// - one byte for the kind: delete (0) or set (1),
// - the varint-string user key,
// - the varint-string value (if kind == set).
// The sequence number and count are stored in little-endian order.
data []byte
}
// Set adds an action to the batch that sets the key to map to the value.
func (b *Batch) Set(key, value []byte) {
if len(b.data) == 0 {
b.init(len(key) + len(value) + 2*binary.MaxVarintLen64 + batchHeaderLen)
}
if b.increment() {
b.data = append(b.data, byte(internalKeyKindSet))
b.appendStr(key)
b.appendStr(value)
}
}
// Delete adds an action to the batch that deletes the entry for key.
func (b *Batch) Delete(key []byte) {
if len(b.data) == 0 {
b.init(len(key) + binary.MaxVarintLen64 + batchHeaderLen)
}
if b.increment() {
b.data = append(b.data, byte(internalKeyKindDelete))
b.appendStr(key)
}
}
func (b *Batch) init(cap int) {
n := 256
for n < cap {
n *= 2
}
b.data = make([]byte, batchHeaderLen, n)
}
// seqNumData returns the 8 byte little-endian sequence number. Zero means that
// the batch has not yet been applied.
func (b *Batch) seqNumData() []byte {
return b.data[:8]
}
// countData returns the 4 byte little-endian count data. "\xff\xff\xff\xff"
// means that the batch is invalid.
func (b *Batch) countData() []byte {
return b.data[8:12]
}
func (b *Batch) increment() (ok bool) {
p := b.countData() // [8:12]
for i := range p {
p[i]++
if p[i] != 0x00 {
return true
} //
}
// The countData was "\xff\xff\xff\xff". Leave it as it was.
p[0] = 0xff
p[1] = 0xff
p[2] = 0xff
p[3] = 0xff
return false
}
func (b *Batch) appendStr(s []byte) {
var buf [binary.MaxVarintLen64]byte
n := binary.PutUvarint(buf[:], uint64(len(s)))
b.data = append(b.data, buf[:n]...)
b.data = append(b.data, s...)
}
func (b *Batch) setSeqNum(seqNum uint64) {
binary.LittleEndian.PutUint64(b.seqNumData(), seqNum)
}
func (b *Batch) seqNum() uint64 {
return binary.LittleEndian.Uint64(b.seqNumData())
}
func (b *Batch) count() uint32 {
return binary.LittleEndian.Uint32(b.countData())
}
// 返回迭代器
func (b *Batch) iter() batchIter {
return b.data[batchHeaderLen:]
}
type batchIter []byte
// next returns the next operation in this batch.
// The final return value is false if the batch is corrupt.
func (t *batchIter) next() (kind internalKeyKind, ukey []byte, value []byte, ok bool) {
p := *t
if len(p) == 0 {
return 0, nil, nil, false
}
kind, *t = internalKeyKind(p[0]), p[1:]
if kind > internalKeyKindMax {
return 0, nil, nil, false
}
ukey, ok = t.nextStr()
if !ok {
return 0, nil, nil, false
}
if kind != internalKeyKindDelete {
value, ok = t.nextStr()
if !ok {
return 0, nil, nil, false
}
}
return kind, ukey, value, true
}
func (t *batchIter) nextStr() (s []byte, ok bool) {
p := *t
u, numBytes := binary.Uvarint(p)
if numBytes <= 0 {
return nil, false
}
p = p[numBytes:] //
if u > uint64(len(p)) {
return nil, false
}
s, *t = p[:u], p[u:]
return s, true
}
一個(gè)巧妙的迭代器
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門怕篷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來历筝,“玉大人,你說我怎么就攤上這事廊谓∈嶂恚” “怎么了?”我有些...
- 文/不壞的土叔 我叫張陵蒸痹,是天一觀的道長春弥。 經(jīng)常有香客問我,道長叠荠,這世上最難降的妖魔是什么匿沛? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮榛鼎,結(jié)果婚禮上逃呼,老公的妹妹穿的比我還像新娘。我一直安慰自己者娱,他們只是感情好蜘渣,可當(dāng)我...
- 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肺然,像睡著了一般蔫缸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上际起,一...
- 文/蒼蘭香墨 我猛地睜開眼娇豫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了博脑?” 一聲冷哼從身側(cè)響起驻谆,我...
- 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奈嘿,沒想到半個(gè)月后貌虾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡裙犹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年尽狠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叶圃。...
- 正文 年R本政府宣布赫舒,位于F島的核電站悍及,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏接癌。R本人自食惡果不足惜心赶,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缺猛。 院中可真熱鬧缨叫,春花似錦、人聲如沸荔燎。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽有咨。三九已至琐簇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間座享,已是汗流浹背婉商。 一陣腳步聲響...
- 正文 我出身青樓,卻偏偏與公主長得像淳衙,于是被迫代替她去往敵國和親蘑秽。 傳聞我的和親對象是個(gè)殘疾皇子饺著,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 潛能營第三課,易仁永澄老師帶來他的目標(biāo)管理肠牲。課程內(nèi)容落地實(shí)用幼衰,直達(dá)核心。下面是我課后復(fù)盤的手繪導(dǎo)圖~ 課程內(nèi)容很多...