mirror of
https://gitee.com/milvus-io/milvus.git
synced 2024-12-05 13:28:49 +08:00
84 lines
2.4 KiB
Go
84 lines
2.4 KiB
Go
|
package writebuffer
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
|
||
|
"go.uber.org/zap"
|
||
|
|
||
|
"github.com/milvus-io/milvus-proto/go-api/v2/msgpb"
|
||
|
"github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
|
||
|
"github.com/milvus-io/milvus/internal/allocator"
|
||
|
"github.com/milvus-io/milvus/internal/datanode/metacache"
|
||
|
"github.com/milvus-io/milvus/internal/datanode/syncmgr"
|
||
|
"github.com/milvus-io/milvus/internal/storage"
|
||
|
"github.com/milvus-io/milvus/pkg/log"
|
||
|
"github.com/milvus-io/milvus/pkg/mq/msgstream"
|
||
|
"github.com/milvus-io/milvus/pkg/util/merr"
|
||
|
"github.com/milvus-io/milvus/pkg/util/retry"
|
||
|
)
|
||
|
|
||
|
type l0WriteBuffer struct {
|
||
|
*writeBufferBase
|
||
|
|
||
|
l0Segments map[int64]int64 // partitionID => l0 segment ID
|
||
|
|
||
|
syncMgr syncmgr.SyncManager
|
||
|
idAllocator allocator.Interface
|
||
|
}
|
||
|
|
||
|
func NewL0WriteBuffer(sch *schemapb.CollectionSchema, metacache metacache.MetaCache, syncMgr syncmgr.SyncManager, option *writeBufferOption) (WriteBuffer, error) {
|
||
|
if option.idAllocator == nil {
|
||
|
return nil, merr.WrapErrServiceInternal("id allocator is nil when creating l0 write buffer")
|
||
|
}
|
||
|
return &l0WriteBuffer{
|
||
|
l0Segments: make(map[int64]int64),
|
||
|
writeBufferBase: newWriteBufferBase(sch, metacache, syncMgr, option),
|
||
|
syncMgr: syncMgr,
|
||
|
idAllocator: option.idAllocator,
|
||
|
}, nil
|
||
|
}
|
||
|
|
||
|
func (wb *l0WriteBuffer) BufferData(insertMsgs []*msgstream.InsertMsg, deleteMsgs []*msgstream.DeleteMsg, startPos, endPos *msgpb.MsgPosition) error {
|
||
|
wb.mut.Lock()
|
||
|
defer wb.mut.Unlock()
|
||
|
|
||
|
// process insert msgs
|
||
|
_, err := wb.bufferInsert(insertMsgs, startPos, endPos)
|
||
|
if err != nil {
|
||
|
log.Warn("failed to buffer insert data", zap.Error(err))
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
for _, msg := range deleteMsgs {
|
||
|
l0SegmentID := wb.getL0SegmentID(msg.GetPartitionID())
|
||
|
pks := storage.ParseIDs2PrimaryKeys(msg.GetPrimaryKeys())
|
||
|
err := wb.bufferDelete(l0SegmentID, pks, msg.GetTimestamps(), startPos, endPos)
|
||
|
if err != nil {
|
||
|
log.Warn("failed to buffer delete data", zap.Error(err))
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// update buffer last checkpoint
|
||
|
wb.checkpoint = endPos
|
||
|
|
||
|
return wb.triggerAutoSync()
|
||
|
}
|
||
|
|
||
|
func (wb *l0WriteBuffer) getL0SegmentID(partitionID int64) int64 {
|
||
|
segmentID, ok := wb.l0Segments[partitionID]
|
||
|
if !ok {
|
||
|
err := retry.Do(context.Background(), func() error {
|
||
|
var err error
|
||
|
segmentID, err = wb.idAllocator.AllocOne()
|
||
|
return err
|
||
|
})
|
||
|
if err != nil {
|
||
|
log.Error("failed to allocate l0 segment ID", zap.Error(err))
|
||
|
panic(err)
|
||
|
}
|
||
|
wb.l0Segments[partitionID] = segmentID
|
||
|
}
|
||
|
return segmentID
|
||
|
}
|