Слияние кода завершено, страница обновится автоматически
package rosedb
import (
"encoding/binary"
"github.com/rosedblabs/wal"
"github.com/valyala/bytebufferpool"
)
// LogRecordType is the type of the log record.
type LogRecordType = byte
const (
// LogRecordNormal is the normal log record type.
LogRecordNormal LogRecordType = iota
// LogRecordDeleted is the deleted log record type.
LogRecordDeleted
// LogRecordBatchFinished is the batch finished log record type.
LogRecordBatchFinished
)
// type batchId keySize valueSize expire
//
// 1 + 10 + 5 + 5 + 10 = 31
const maxLogRecordHeaderSize = binary.MaxVarintLen32*2 + binary.MaxVarintLen64*2 + 1
// LogRecord is the log record of the key/value pair.
// It contains the key, the value, the record type and the batch id
// It will be encoded to byte slice and written to the wal.
type LogRecord struct {
Key []byte
Value []byte
Type LogRecordType
BatchId uint64
Expire int64
}
// IsExpired checks whether the log record is expired.
func (lr *LogRecord) IsExpired(now int64) bool {
return lr.Expire > 0 && lr.Expire <= now
}
// IndexRecord is the index record of the key.
// It contains the key, the record type and the position of the record in the wal.
// Only used in start up to rebuild the index.
type IndexRecord struct {
key []byte
recordType LogRecordType
position *wal.ChunkPosition
}
// +-------------+-------------+-------------+--------------+---------------+---------+--------------+
// | type | batch id | key size | value size | expire | key | value |
// +-------------+-------------+-------------+--------------+---------------+--------+--------------+
//
// 1 byte varint(max 10) varint(max 5) varint(max 5) varint(max 10) varint varint
func encodeLogRecord(logRecord *LogRecord, header []byte, buf *bytebufferpool.ByteBuffer) []byte {
header[0] = logRecord.Type
var index = 1
// batch id
index += binary.PutUvarint(header[index:], logRecord.BatchId)
// key size
index += binary.PutVarint(header[index:], int64(len(logRecord.Key)))
// value size
index += binary.PutVarint(header[index:], int64(len(logRecord.Value)))
// expire
index += binary.PutVarint(header[index:], logRecord.Expire)
// copy header
_, _ = buf.Write(header[:index])
// copy key
_, _ = buf.Write(logRecord.Key)
// copy value
_, _ = buf.Write(logRecord.Value)
return buf.Bytes()
}
// decodeLogRecord decodes the log record from the given byte slice.
func decodeLogRecord(buf []byte) *LogRecord {
recordType := buf[0]
var index uint32 = 1
// batch id
batchId, n := binary.Uvarint(buf[index:])
index += uint32(n)
// key size
keySize, n := binary.Varint(buf[index:])
index += uint32(n)
// value size
valueSize, n := binary.Varint(buf[index:])
index += uint32(n)
// expire
expire, n := binary.Varint(buf[index:])
index += uint32(n)
// copy key
key := make([]byte, keySize)
copy(key[:], buf[index:index+uint32(keySize)])
index += uint32(keySize)
// copy value
value := make([]byte, valueSize)
copy(value[:], buf[index:index+uint32(valueSize)])
return &LogRecord{Key: key, Value: value, Expire: expire,
BatchId: batchId, Type: recordType}
}
func encodeHintRecord(key []byte, pos *wal.ChunkPosition) []byte {
// SegmentId BlockNumber ChunkOffset ChunkSize
// 5 5 10 5 = 25
// see binary.MaxVarintLen64 and binary.MaxVarintLen32
buf := make([]byte, 25)
var idx = 0
// SegmentId
idx += binary.PutUvarint(buf[idx:], uint64(pos.SegmentId))
// BlockNumber
idx += binary.PutUvarint(buf[idx:], uint64(pos.BlockNumber))
// ChunkOffset
idx += binary.PutUvarint(buf[idx:], uint64(pos.ChunkOffset))
// ChunkSize
idx += binary.PutUvarint(buf[idx:], uint64(pos.ChunkSize))
// key
result := make([]byte, idx+len(key))
copy(result, buf[:idx])
copy(result[idx:], key)
return result
}
func decodeHintRecord(buf []byte) ([]byte, *wal.ChunkPosition) {
var idx = 0
// SegmentId
segmentId, n := binary.Uvarint(buf[idx:])
idx += n
// BlockNumber
blockNumber, n := binary.Uvarint(buf[idx:])
idx += n
// ChunkOffset
chunkOffset, n := binary.Uvarint(buf[idx:])
idx += n
// ChunkSize
chunkSize, n := binary.Uvarint(buf[idx:])
idx += n
// Key
key := buf[idx:]
return key, &wal.ChunkPosition{
SegmentId: wal.SegmentID(segmentId),
BlockNumber: uint32(blockNumber),
ChunkOffset: int64(chunkOffset),
ChunkSize: uint32(chunkSize),
}
}
func encodeMergeFinRecord(segmentId wal.SegmentID) []byte {
buf := make([]byte, 4)
binary.LittleEndian.PutUint32(buf, segmentId)
return buf
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )