milvus/internal/storage/binlog_reader.go
neza2017 9cbebc0221 Add binlog unittest
Signed-off-by: neza2017 <yefu.chen@zilliz.com>
2020-12-10 14:52:42 +08:00

94 lines
2.2 KiB
Go

package storage
import (
"bytes"
"encoding/binary"
"strconv"
"github.com/zilliztech/milvus-distributed/internal/errors"
)
type BinlogReader struct {
magicNumber int32
descriptorEvent
currentEventReader *EventReader
buffer *bytes.Buffer
bufferLength int
currentOffset int32
isClose bool
}
func (reader *BinlogReader) NextEventReader() (*EventReader, error) {
if reader.isClose {
return nil, errors.New("bin log reader is closed")
}
if reader.currentEventReader != nil {
reader.currentOffset = reader.currentEventReader.NextPosition
if err := reader.currentEventReader.Close(); err != nil {
return nil, err
}
reader.currentEventReader = nil
}
if reader.buffer.Len() <= 0 {
return nil, nil
}
eventReader, err := newEventReader(reader.descriptorEvent.PayloadDataType, reader.buffer)
if err != nil {
return nil, err
}
reader.currentEventReader = eventReader
return reader.currentEventReader, nil
}
func (reader *BinlogReader) readMagicNumber() (int32, error) {
if err := binary.Read(reader.buffer, binary.LittleEndian, &reader.magicNumber); err != nil {
return -1, err
}
reader.currentOffset = 4
if reader.magicNumber != MagicNumber {
return -1, errors.New("parse magic number failed, expected: " + strconv.Itoa(int(MagicNumber)) +
", actual: " + strconv.Itoa(int(reader.magicNumber)))
}
return reader.magicNumber, nil
}
func (reader *BinlogReader) readDescriptorEvent() (*descriptorEvent, error) {
event, err := ReadDescriptorEvent(reader.buffer)
reader.currentOffset = event.NextPosition
if err != nil {
return nil, err
}
reader.descriptorEvent = *event
return &reader.descriptorEvent, nil
}
func (reader *BinlogReader) Close() error {
if reader.isClose {
return nil
}
reader.isClose = true
if reader.currentEventReader != nil {
if err := reader.currentEventReader.Close(); err != nil {
return err
}
}
return nil
}
func NewBinlogReader(data []byte) (*BinlogReader, error) {
reader := &BinlogReader{
buffer: bytes.NewBuffer(data),
bufferLength: len(data),
isClose: false,
}
if _, err := reader.readMagicNumber(); err != nil {
return nil, err
}
if _, err := reader.readDescriptorEvent(); err != nil {
return nil, err
}
return reader, nil
}