mirror of
https://gitee.com/milvus-io/milvus.git
synced 2024-12-04 12:59:23 +08:00
aef4e41e91
Signed-off-by: zhenshan.cao <zhenshan.cao@zilliz.com>
206 lines
5.0 KiB
Go
206 lines
5.0 KiB
Go
package master
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/zilliztech/milvus-distributed/internal/proto/commonpb"
|
|
"github.com/zilliztech/milvus-distributed/internal/proto/milvuspb"
|
|
)
|
|
|
|
type createIndexTask struct {
|
|
baseTask
|
|
req *milvuspb.CreateIndexRequest
|
|
indexBuildScheduler *IndexBuildScheduler
|
|
indexLoadScheduler *IndexLoadScheduler
|
|
segManager SegmentManager
|
|
}
|
|
|
|
func (task *createIndexTask) Type() commonpb.MsgType {
|
|
return commonpb.MsgType_kCreateIndex
|
|
}
|
|
|
|
func (task *createIndexTask) Ts() (Timestamp, error) {
|
|
return task.req.Base.Timestamp, nil
|
|
}
|
|
|
|
func (task *createIndexTask) Execute() error {
|
|
collMeta, err := task.mt.GetCollectionByName(task.req.CollectionName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
var fieldID int64 = -1
|
|
for _, fieldSchema := range collMeta.Schema.Fields {
|
|
if fieldSchema.Name == task.req.FieldName {
|
|
fieldID = fieldSchema.FieldID
|
|
break
|
|
}
|
|
}
|
|
if fieldID == -1 {
|
|
return fmt.Errorf("can not find field name %s", task.req.FieldName)
|
|
}
|
|
|
|
// pre checks
|
|
isIndexable, err := task.mt.IsIndexable(collMeta.ID, fieldID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !isIndexable {
|
|
return fmt.Errorf("field %s is not vector", task.req.FieldName)
|
|
}
|
|
|
|
// modify schema
|
|
if err := task.mt.UpdateFieldIndexParams(task.req.CollectionName, task.req.FieldName, task.req.ExtraParams); err != nil {
|
|
return err
|
|
}
|
|
// check if closed segment has the same index build history
|
|
for _, segID := range collMeta.SegmentIDs {
|
|
segMeta, err := task.mt.GetSegmentByID(segID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if segMeta.CloseTime == 0 {
|
|
continue
|
|
}
|
|
hasIndexMeta, err := task.mt.HasFieldIndexMeta(segID, fieldID, task.req.ExtraParams)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if hasIndexMeta {
|
|
// load index
|
|
indexMeta, err := task.mt.GetFieldIndexMeta(segID, fieldID, task.req.ExtraParams)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = task.indexLoadScheduler.Enqueue(&IndexLoadInfo{
|
|
segmentID: segID,
|
|
fieldID: fieldID,
|
|
fieldName: task.req.FieldName,
|
|
indexFilePaths: indexMeta.IndexFilePaths,
|
|
indexParams: indexMeta.IndexParams,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
// create index
|
|
for _, kv := range segMeta.BinlogFilePaths {
|
|
if kv.FieldID != fieldID {
|
|
continue
|
|
}
|
|
err := task.indexBuildScheduler.Enqueue(&IndexBuildInfo{
|
|
segmentID: segID,
|
|
fieldID: fieldID,
|
|
binlogFilePath: kv.BinlogFiles,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// close unfilled segment
|
|
return task.segManager.ForceClose(collMeta.ID)
|
|
}
|
|
|
|
type describeIndexTask struct {
|
|
baseTask
|
|
req *milvuspb.DescribeIndexRequest
|
|
resp *milvuspb.DescribeIndexResponse
|
|
}
|
|
|
|
func (task *describeIndexTask) Type() commonpb.MsgType {
|
|
return commonpb.MsgType_kDescribeIndex
|
|
}
|
|
|
|
func (task *describeIndexTask) Ts() (Timestamp, error) {
|
|
return task.req.Base.Timestamp, nil
|
|
}
|
|
|
|
func (task *describeIndexTask) Execute() error {
|
|
collMeta, err := task.mt.GetCollectionByName(task.req.CollectionName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var fieldID int64 = -1
|
|
for _, fieldSchema := range collMeta.Schema.Fields {
|
|
if fieldSchema.Name == task.req.FieldName {
|
|
fieldID = fieldSchema.FieldID
|
|
break
|
|
}
|
|
}
|
|
if fieldID == -1 {
|
|
return fmt.Errorf("can not find field %s", task.req.FieldName)
|
|
}
|
|
indexParams, err := task.mt.GetFieldIndexParams(collMeta.ID, fieldID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
description := &milvuspb.IndexDescription{
|
|
IndexName: "", // todo add IndexName to master meta_table
|
|
Params: indexParams,
|
|
}
|
|
task.resp.IndexDescriptions = []*milvuspb.IndexDescription{description}
|
|
return nil
|
|
}
|
|
|
|
type getIndexStateTask struct {
|
|
baseTask
|
|
req *milvuspb.IndexStateRequest
|
|
runtimeStats *RuntimeStats
|
|
resp *milvuspb.IndexStateResponse
|
|
}
|
|
|
|
func (task *getIndexStateTask) Type() commonpb.MsgType {
|
|
return commonpb.MsgType_kGetIndexState
|
|
}
|
|
|
|
func (task *getIndexStateTask) Ts() (Timestamp, error) {
|
|
return task.req.Base.Timestamp, nil
|
|
}
|
|
|
|
func (task *getIndexStateTask) Execute() error {
|
|
// get field id, collection id
|
|
collMeta, err := task.mt.GetCollectionByName(task.req.CollectionName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var fieldID int64 = -1
|
|
for _, fieldSchema := range collMeta.Schema.Fields {
|
|
if fieldSchema.Name == task.req.FieldName {
|
|
fieldID = fieldSchema.FieldID
|
|
break
|
|
}
|
|
}
|
|
if fieldID == -1 {
|
|
return fmt.Errorf("can not find field %s", task.req.FieldName)
|
|
}
|
|
|
|
// total segment nums
|
|
totalSegmentNums := len(collMeta.SegmentIDs)
|
|
|
|
indexParams, err := task.mt.GetFieldIndexParams(collMeta.ID, fieldID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// get completed segment nums from querynode's runtime stats
|
|
relatedSegments := task.runtimeStats.GetTotalNumOfRelatedSegments(collMeta.ID, fieldID, indexParams)
|
|
task.resp = &milvuspb.IndexStateResponse{
|
|
Status: &commonpb.Status{
|
|
ErrorCode: commonpb.ErrorCode_SUCCESS,
|
|
},
|
|
}
|
|
|
|
if int64(totalSegmentNums) == relatedSegments {
|
|
task.resp.State = commonpb.IndexState_FINISHED
|
|
} else {
|
|
task.resp.State = commonpb.IndexState_INPROGRESS
|
|
}
|
|
return nil
|
|
}
|