2021-01-19 11:37:16 +08:00
|
|
|
package datanode
|
|
|
|
|
|
|
|
import (
|
2021-01-21 09:55:25 +08:00
|
|
|
"log"
|
2021-01-19 11:37:16 +08:00
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/zilliztech/milvus-distributed/internal/errors"
|
2021-01-21 09:55:25 +08:00
|
|
|
"github.com/zilliztech/milvus-distributed/internal/proto/internalpb2"
|
2021-01-19 11:37:16 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type collectionReplica interface {
|
|
|
|
|
|
|
|
// collection
|
|
|
|
getCollectionNum() int
|
|
|
|
addCollection(collectionID UniqueID, schemaBlob string) error
|
|
|
|
removeCollection(collectionID UniqueID) error
|
|
|
|
getCollectionByID(collectionID UniqueID) (*Collection, error)
|
|
|
|
getCollectionByName(collectionName string) (*Collection, error)
|
2021-01-22 09:36:40 +08:00
|
|
|
getCollectionIDByName(collectionName string) (UniqueID, error)
|
2021-01-19 11:37:16 +08:00
|
|
|
hasCollection(collectionID UniqueID) bool
|
|
|
|
|
2021-01-21 09:55:25 +08:00
|
|
|
// segment
|
2021-01-22 09:36:40 +08:00
|
|
|
addSegment(segmentID UniqueID, collName string, partitionName string) error
|
2021-01-21 09:55:25 +08:00
|
|
|
removeSegment(segmentID UniqueID) error
|
|
|
|
hasSegment(segmentID UniqueID) bool
|
|
|
|
updateSegmentRowNums(segmentID UniqueID, numRows int64) error
|
|
|
|
getSegmentStatisticsUpdates(segmentID UniqueID) (*internalpb2.SegmentStatisticsUpdates, error)
|
2021-01-22 09:36:40 +08:00
|
|
|
getSegmentByID(segmentID UniqueID) (*Segment, error)
|
2021-01-19 11:37:16 +08:00
|
|
|
}
|
|
|
|
|
2021-01-21 09:55:25 +08:00
|
|
|
type (
|
|
|
|
Segment struct {
|
2021-01-22 09:36:40 +08:00
|
|
|
segmentID UniqueID
|
|
|
|
collectionID UniqueID
|
|
|
|
partitionName string
|
|
|
|
numRows int64
|
|
|
|
memorySize int64
|
2021-01-21 09:55:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
collectionReplicaImpl struct {
|
|
|
|
mu sync.RWMutex
|
|
|
|
collections []*Collection
|
|
|
|
segments []*Segment
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2021-01-19 11:37:16 +08:00
|
|
|
//----------------------------------------------------------------------------------------------------- collection
|
2021-01-21 09:55:25 +08:00
|
|
|
|
2021-01-22 09:36:40 +08:00
|
|
|
func (colReplica *collectionReplicaImpl) getSegmentByID(segmentID UniqueID) (*Segment, error) {
|
|
|
|
// GOOSE TODO: read write lock
|
2021-01-21 09:55:25 +08:00
|
|
|
colReplica.mu.RLock()
|
|
|
|
defer colReplica.mu.RUnlock()
|
2021-01-22 09:36:40 +08:00
|
|
|
|
|
|
|
for _, segment := range colReplica.segments {
|
|
|
|
if segment.segmentID == segmentID {
|
|
|
|
return segment, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, errors.Errorf("cannot find segment, id = %v", segmentID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) addSegment(segmentID UniqueID, collName string, partitionName string) error {
|
|
|
|
colReplica.mu.Lock()
|
|
|
|
defer colReplica.mu.Unlock()
|
2021-01-21 09:55:25 +08:00
|
|
|
log.Println("Add Segment", segmentID)
|
2021-01-22 09:36:40 +08:00
|
|
|
collID, err := colReplica.getCollectionIDByName(collName)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-01-21 09:55:25 +08:00
|
|
|
seg := &Segment{
|
2021-01-22 09:36:40 +08:00
|
|
|
segmentID: segmentID,
|
|
|
|
collectionID: collID,
|
|
|
|
partitionName: partitionName,
|
2021-01-21 09:55:25 +08:00
|
|
|
}
|
|
|
|
colReplica.segments = append(colReplica.segments, seg)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) removeSegment(segmentID UniqueID) error {
|
2021-01-22 09:36:40 +08:00
|
|
|
colReplica.mu.Lock()
|
|
|
|
defer colReplica.mu.Unlock()
|
2021-01-21 09:55:25 +08:00
|
|
|
|
|
|
|
for index, ele := range colReplica.segments {
|
|
|
|
if ele.segmentID == segmentID {
|
|
|
|
log.Println("Removing segment:", segmentID)
|
|
|
|
numOfSegs := len(colReplica.segments)
|
|
|
|
colReplica.segments[index] = colReplica.segments[numOfSegs-1]
|
|
|
|
colReplica.segments = colReplica.segments[:numOfSegs-1]
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return errors.Errorf("Error, there's no segment %v", segmentID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) hasSegment(segmentID UniqueID) bool {
|
|
|
|
colReplica.mu.RLock()
|
|
|
|
defer colReplica.mu.RUnlock()
|
|
|
|
|
|
|
|
for _, ele := range colReplica.segments {
|
|
|
|
if ele.segmentID == segmentID {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) updateSegmentRowNums(segmentID UniqueID, numRows int64) error {
|
2021-01-22 09:36:40 +08:00
|
|
|
colReplica.mu.Lock()
|
|
|
|
defer colReplica.mu.Unlock()
|
2021-01-21 09:55:25 +08:00
|
|
|
|
|
|
|
for _, ele := range colReplica.segments {
|
|
|
|
if ele.segmentID == segmentID {
|
|
|
|
log.Printf("updating segment(%v) row nums: (%v)", segmentID, numRows)
|
|
|
|
ele.memorySize = 0
|
|
|
|
ele.numRows += numRows
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return errors.Errorf("Error, there's no segment %v", segmentID)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) getSegmentStatisticsUpdates(segmentID UniqueID) (*internalpb2.SegmentStatisticsUpdates, error) {
|
|
|
|
colReplica.mu.RLock()
|
|
|
|
defer colReplica.mu.RUnlock()
|
|
|
|
|
|
|
|
for _, ele := range colReplica.segments {
|
|
|
|
if ele.segmentID == segmentID {
|
|
|
|
updates := &internalpb2.SegmentStatisticsUpdates{
|
|
|
|
SegmentID: segmentID,
|
|
|
|
MemorySize: ele.memorySize,
|
|
|
|
NumRows: ele.numRows,
|
|
|
|
}
|
|
|
|
return updates, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, errors.Errorf("Error, there's no segment %v", segmentID)
|
2021-01-19 11:37:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) getCollectionNum() int {
|
|
|
|
colReplica.mu.RLock()
|
|
|
|
defer colReplica.mu.RUnlock()
|
|
|
|
|
|
|
|
return len(colReplica.collections)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) addCollection(collectionID UniqueID, schemaBlob string) error {
|
|
|
|
colReplica.mu.Lock()
|
|
|
|
defer colReplica.mu.Unlock()
|
|
|
|
|
|
|
|
var newCollection = newCollection(collectionID, schemaBlob)
|
|
|
|
colReplica.collections = append(colReplica.collections, newCollection)
|
2021-01-21 09:55:25 +08:00
|
|
|
log.Println("Create collection: ", newCollection.Name())
|
2021-01-19 11:37:16 +08:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-01-22 09:36:40 +08:00
|
|
|
func (colReplica *collectionReplicaImpl) getCollectionIDByName(collName string) (UniqueID, error) {
|
|
|
|
colReplica.mu.RLock()
|
|
|
|
defer colReplica.mu.RUnlock()
|
|
|
|
|
|
|
|
for _, collection := range colReplica.collections {
|
|
|
|
if collection.Name() == collName {
|
|
|
|
return collection.ID(), nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0, errors.Errorf("There is no collection name=%v", collName)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-01-19 11:37:16 +08:00
|
|
|
func (colReplica *collectionReplicaImpl) removeCollection(collectionID UniqueID) error {
|
2021-01-21 09:55:25 +08:00
|
|
|
// GOOSE TODO: optimize
|
2021-01-19 11:37:16 +08:00
|
|
|
colReplica.mu.Lock()
|
|
|
|
defer colReplica.mu.Unlock()
|
|
|
|
|
|
|
|
tmpCollections := make([]*Collection, 0)
|
|
|
|
for _, col := range colReplica.collections {
|
|
|
|
if col.ID() != collectionID {
|
|
|
|
tmpCollections = append(tmpCollections, col)
|
|
|
|
} else {
|
2021-01-21 09:55:25 +08:00
|
|
|
log.Println("Drop collection : ", col.Name())
|
2021-01-19 11:37:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
colReplica.collections = tmpCollections
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) getCollectionByID(collectionID UniqueID) (*Collection, error) {
|
|
|
|
colReplica.mu.RLock()
|
|
|
|
defer colReplica.mu.RUnlock()
|
|
|
|
|
|
|
|
for _, collection := range colReplica.collections {
|
|
|
|
if collection.ID() == collectionID {
|
|
|
|
return collection, nil
|
|
|
|
}
|
|
|
|
}
|
2021-01-21 09:55:25 +08:00
|
|
|
return nil, errors.Errorf("cannot find collection, id = %v", collectionID)
|
2021-01-19 11:37:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) getCollectionByName(collectionName string) (*Collection, error) {
|
|
|
|
colReplica.mu.RLock()
|
|
|
|
defer colReplica.mu.RUnlock()
|
|
|
|
|
|
|
|
for _, collection := range colReplica.collections {
|
|
|
|
if collection.Name() == collectionName {
|
|
|
|
return collection, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-21 09:55:25 +08:00
|
|
|
return nil, errors.Errorf("Cannot found collection: %v", collectionName)
|
2021-01-19 11:37:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (colReplica *collectionReplicaImpl) hasCollection(collectionID UniqueID) bool {
|
|
|
|
colReplica.mu.RLock()
|
|
|
|
defer colReplica.mu.RUnlock()
|
|
|
|
|
|
|
|
for _, col := range colReplica.collections {
|
|
|
|
if col.ID() == collectionID {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|