2021-01-15 14:38:36 +08:00
|
|
|
package proxynode
|
2020-11-20 17:53:31 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/zilliztech/milvus-distributed/internal/errors"
|
2021-01-18 19:32:08 +08:00
|
|
|
"github.com/zilliztech/milvus-distributed/internal/proto/commonpb"
|
|
|
|
"github.com/zilliztech/milvus-distributed/internal/proto/milvuspb"
|
2021-01-31 14:55:36 +08:00
|
|
|
"github.com/zilliztech/milvus-distributed/internal/proto/schemapb"
|
|
|
|
"github.com/zilliztech/milvus-distributed/internal/util/typeutil"
|
2020-11-20 17:53:31 +08:00
|
|
|
)
|
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
type MasterClientInterface interface {
|
|
|
|
DescribeCollection(in *milvuspb.DescribeCollectionRequest) (*milvuspb.DescribeCollectionResponse, error)
|
|
|
|
ShowPartitions(in *milvuspb.ShowPartitionRequest) (*milvuspb.ShowPartitionResponse, error)
|
|
|
|
}
|
|
|
|
|
2020-11-30 19:08:32 +08:00
|
|
|
type Cache interface {
|
2021-01-31 14:55:36 +08:00
|
|
|
GetCollectionID(collectionName string) (typeutil.UniqueID, error)
|
|
|
|
GetPartitionID(collectionName string, partitionName string) (typeutil.UniqueID, error)
|
|
|
|
GetCollectionSchema(collectionName string) (*schemapb.CollectionSchema, error)
|
|
|
|
RemoveCollection(collectionName string)
|
2021-02-04 16:09:34 +08:00
|
|
|
RemovePartition(partitionName string)
|
2021-01-31 14:55:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type collectionInfo struct {
|
2021-02-04 16:09:34 +08:00
|
|
|
collID typeutil.UniqueID
|
|
|
|
schema *schemapb.CollectionSchema
|
2021-01-31 14:55:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type MetaCache struct {
|
|
|
|
client MasterClientInterface
|
|
|
|
|
|
|
|
collInfo map[string]*collectionInfo
|
2021-02-04 16:09:34 +08:00
|
|
|
partInfo map[string]typeutil.UniqueID
|
|
|
|
col2par map[string][]string
|
2021-01-31 14:55:36 +08:00
|
|
|
mu sync.RWMutex
|
2020-11-20 17:53:31 +08:00
|
|
|
}
|
|
|
|
|
2020-11-30 19:08:32 +08:00
|
|
|
var globalMetaCache Cache
|
2020-11-20 17:53:31 +08:00
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
func InitMetaCache(client MasterClientInterface) error {
|
|
|
|
var err error
|
|
|
|
globalMetaCache, err = NewMetaCache(client)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
2020-11-20 17:53:31 +08:00
|
|
|
}
|
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
func NewMetaCache(client MasterClientInterface) (*MetaCache, error) {
|
|
|
|
return &MetaCache{
|
|
|
|
client: client,
|
|
|
|
collInfo: map[string]*collectionInfo{},
|
2021-02-04 16:09:34 +08:00
|
|
|
partInfo: map[string]typeutil.UniqueID{},
|
|
|
|
col2par: map[string][]string{},
|
2021-01-31 14:55:36 +08:00
|
|
|
}, nil
|
2020-11-20 17:53:31 +08:00
|
|
|
}
|
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
func (m *MetaCache) readCollectionID(collectionName string) (typeutil.UniqueID, error) {
|
|
|
|
m.mu.RLock()
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
|
|
collInfo, ok := m.collInfo[collectionName]
|
2020-11-20 17:53:31 +08:00
|
|
|
if !ok {
|
2021-01-31 14:55:36 +08:00
|
|
|
return 0, errors.Errorf("can't find collection name:%s", collectionName)
|
2020-11-20 17:53:31 +08:00
|
|
|
}
|
2021-01-31 14:55:36 +08:00
|
|
|
return collInfo.collID, nil
|
2020-11-20 17:53:31 +08:00
|
|
|
}
|
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
func (m *MetaCache) readCollectionSchema(collectionName string) (*schemapb.CollectionSchema, error) {
|
|
|
|
m.mu.RLock()
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
|
|
|
collInfo, ok := m.collInfo[collectionName]
|
|
|
|
if !ok {
|
|
|
|
return nil, errors.Errorf("can't find collection name:%s", collectionName)
|
|
|
|
}
|
|
|
|
return collInfo.schema, nil
|
|
|
|
}
|
|
|
|
|
2021-02-04 16:09:34 +08:00
|
|
|
func (m *MetaCache) readPartitionID(partitionName string) (typeutil.UniqueID, error) {
|
2021-01-31 14:55:36 +08:00
|
|
|
m.mu.RLock()
|
|
|
|
defer m.mu.RUnlock()
|
|
|
|
|
2021-02-04 16:09:34 +08:00
|
|
|
partitionID, ok := m.partInfo[partitionName]
|
2021-01-31 14:55:36 +08:00
|
|
|
if !ok {
|
|
|
|
return 0, errors.Errorf("can't find partition name:%s", partitionName)
|
|
|
|
}
|
|
|
|
return partitionID, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *MetaCache) GetCollectionID(collectionName string) (typeutil.UniqueID, error) {
|
|
|
|
collID, err := m.readCollectionID(collectionName)
|
|
|
|
if err == nil {
|
|
|
|
return collID, nil
|
2020-11-30 19:08:32 +08:00
|
|
|
}
|
2021-01-31 14:55:36 +08:00
|
|
|
m.mu.Lock()
|
|
|
|
defer m.mu.Unlock()
|
2020-12-01 16:41:25 +08:00
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
req := &milvuspb.DescribeCollectionRequest{
|
|
|
|
Base: &commonpb.MsgBase{
|
|
|
|
MsgType: commonpb.MsgType_kDescribeCollection,
|
|
|
|
},
|
|
|
|
CollectionName: collectionName,
|
|
|
|
}
|
|
|
|
coll, err := m.client.DescribeCollection(req)
|
2020-12-02 18:31:56 +08:00
|
|
|
if err != nil {
|
2021-01-31 14:55:36 +08:00
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
if coll.Status.ErrorCode != commonpb.ErrorCode_SUCCESS {
|
|
|
|
return 0, errors.Errorf("%s", coll.Status.Reason)
|
2020-12-02 18:31:56 +08:00
|
|
|
}
|
2020-12-01 19:53:53 +08:00
|
|
|
|
2021-02-04 16:09:34 +08:00
|
|
|
collInfo := &collectionInfo{
|
|
|
|
collID: coll.CollectionID,
|
|
|
|
schema: coll.Schema,
|
|
|
|
}
|
2021-01-31 14:55:36 +08:00
|
|
|
_, ok := m.collInfo[collectionName]
|
|
|
|
if !ok {
|
2021-02-04 16:09:34 +08:00
|
|
|
m.collInfo[collectionName] = collInfo
|
2021-01-31 14:55:36 +08:00
|
|
|
}
|
2021-02-04 16:09:34 +08:00
|
|
|
return collInfo.collID, nil
|
2020-12-03 19:00:11 +08:00
|
|
|
}
|
2021-01-31 14:55:36 +08:00
|
|
|
func (m *MetaCache) GetCollectionSchema(collectionName string) (*schemapb.CollectionSchema, error) {
|
|
|
|
collSchema, err := m.readCollectionSchema(collectionName)
|
|
|
|
if err == nil {
|
|
|
|
return collSchema, nil
|
|
|
|
}
|
|
|
|
m.mu.Lock()
|
|
|
|
defer m.mu.Unlock()
|
2020-12-03 19:00:11 +08:00
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
req := &milvuspb.DescribeCollectionRequest{
|
|
|
|
Base: &commonpb.MsgBase{
|
|
|
|
MsgType: commonpb.MsgType_kDescribeCollection,
|
|
|
|
},
|
|
|
|
CollectionName: collectionName,
|
|
|
|
}
|
|
|
|
coll, err := m.client.DescribeCollection(req)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if coll.Status.ErrorCode != commonpb.ErrorCode_SUCCESS {
|
|
|
|
return nil, errors.Errorf("%s", coll.Status.Reason)
|
|
|
|
}
|
2020-11-30 19:08:32 +08:00
|
|
|
|
2021-02-04 16:09:34 +08:00
|
|
|
collInfo := &collectionInfo{
|
|
|
|
collID: coll.CollectionID,
|
|
|
|
schema: coll.Schema,
|
|
|
|
}
|
2021-01-31 14:55:36 +08:00
|
|
|
_, ok := m.collInfo[collectionName]
|
|
|
|
if !ok {
|
2021-02-04 16:09:34 +08:00
|
|
|
m.collInfo[collectionName] = collInfo
|
2021-01-31 14:55:36 +08:00
|
|
|
}
|
2021-02-04 16:09:34 +08:00
|
|
|
return collInfo.schema, nil
|
2020-11-30 19:08:32 +08:00
|
|
|
}
|
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
func (m *MetaCache) GetPartitionID(collectionName string, partitionName string) (typeutil.UniqueID, error) {
|
2021-02-04 16:09:34 +08:00
|
|
|
partitionID, err := m.readPartitionID(partitionName)
|
2021-01-31 14:55:36 +08:00
|
|
|
if err == nil {
|
|
|
|
return partitionID, nil
|
|
|
|
}
|
|
|
|
m.mu.Lock()
|
|
|
|
defer m.mu.Unlock()
|
|
|
|
|
|
|
|
req := &milvuspb.ShowPartitionRequest{
|
|
|
|
Base: &commonpb.MsgBase{
|
|
|
|
MsgType: commonpb.MsgType_kShowPartitions,
|
|
|
|
},
|
|
|
|
CollectionName: collectionName,
|
|
|
|
}
|
|
|
|
partitions, err := m.client.ShowPartitions(req)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
if partitions.Status.ErrorCode != commonpb.ErrorCode_SUCCESS {
|
|
|
|
return 0, errors.Errorf("%s", partitions.Status.Reason)
|
|
|
|
}
|
|
|
|
if len(partitions.PartitionIDs) != len(partitions.PartitionNames) {
|
|
|
|
return 0, errors.Errorf("partition ids len: %d doesn't equal Partition name len %d",
|
|
|
|
len(partitions.PartitionIDs), len(partitions.PartitionNames))
|
|
|
|
}
|
2021-02-04 16:09:34 +08:00
|
|
|
m.col2par[collectionName] = partitions.PartitionNames
|
2020-11-30 19:08:32 +08:00
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
for i := 0; i < len(partitions.PartitionIDs); i++ {
|
2021-02-04 16:09:34 +08:00
|
|
|
_, ok := m.partInfo[partitions.PartitionNames[i]]
|
2021-01-31 14:55:36 +08:00
|
|
|
if !ok {
|
2021-02-04 16:09:34 +08:00
|
|
|
m.partInfo[partitions.PartitionNames[i]] = partitions.PartitionIDs[i]
|
2021-01-31 14:55:36 +08:00
|
|
|
}
|
|
|
|
}
|
2021-02-04 16:09:34 +08:00
|
|
|
_, ok := m.partInfo[partitionName]
|
2020-11-30 19:08:32 +08:00
|
|
|
if !ok {
|
2021-01-31 14:55:36 +08:00
|
|
|
return 0, errors.Errorf("partitionID of partitionName:%s can not be find", partitionName)
|
2020-11-30 19:08:32 +08:00
|
|
|
}
|
2021-02-04 16:09:34 +08:00
|
|
|
return m.partInfo[partitionName], nil
|
2020-11-20 17:53:31 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-01-31 14:55:36 +08:00
|
|
|
func (m *MetaCache) RemoveCollection(collectionName string) {
|
|
|
|
m.mu.Lock()
|
|
|
|
defer m.mu.Unlock()
|
|
|
|
delete(m.collInfo, collectionName)
|
2021-02-04 16:09:34 +08:00
|
|
|
for _, partitionName := range m.col2par[collectionName] {
|
|
|
|
delete(m.partInfo, partitionName)
|
|
|
|
}
|
|
|
|
delete(m.col2par, collectionName)
|
2020-11-20 17:53:31 +08:00
|
|
|
}
|
|
|
|
|
2021-02-04 16:09:34 +08:00
|
|
|
func (m *MetaCache) RemovePartition(partitionName string) {
|
2021-01-31 14:55:36 +08:00
|
|
|
m.mu.Lock()
|
|
|
|
defer m.mu.Unlock()
|
2021-02-04 16:09:34 +08:00
|
|
|
delete(m.partInfo, partitionName)
|
2020-11-20 17:53:31 +08:00
|
|
|
}
|