2021-11-29 20:13:50 +08:00
// Licensed to the LF AI & Data foundation under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
2021-04-19 13:47:10 +08:00
// with the License. You may obtain a copy of the License at
//
2021-11-29 20:13:50 +08:00
// http://www.apache.org/licenses/LICENSE-2.0
2021-04-19 13:47:10 +08:00
//
2021-11-29 20:13:50 +08:00
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
2021-04-19 13:47:10 +08:00
2021-01-16 10:12:14 +08:00
package querynode
2020-08-25 15:45:19 +08:00
2020-09-01 16:23:39 +08:00
/ *
2020-10-23 18:01:24 +08:00
# cgo CFLAGS : - I $ { SRCDIR } / . . / core / output / include
2020-09-01 16:23:39 +08:00
2020-10-31 15:11:47 +08:00
# cgo LDFLAGS : - L $ { SRCDIR } / . . / core / output / lib - lmilvus_segcore - Wl , - rpath = $ { SRCDIR } / . . / core / output / lib
2020-09-01 16:23:39 +08:00
2020-11-25 10:31:51 +08:00
# include "segcore/collection_c.h"
# include "segcore/segment_c.h"
2020-09-01 16:23:39 +08:00
* /
2020-08-25 15:45:19 +08:00
import "C"
2021-01-18 10:38:41 +08:00
import (
2021-06-19 18:38:07 +08:00
"errors"
"fmt"
2021-06-15 12:41:40 +08:00
"math"
"sync"
2021-06-09 11:37:55 +08:00
"unsafe"
"go.uber.org/zap"
2021-01-18 10:38:41 +08:00
"github.com/golang/protobuf/proto"
2021-04-22 14:45:57 +08:00
"github.com/milvus-io/milvus/internal/log"
"github.com/milvus-io/milvus/internal/proto/schemapb"
2021-01-18 10:38:41 +08:00
)
2020-08-25 15:45:19 +08:00
2021-10-14 14:02:41 +08:00
// Collection is a wrapper of the underlying C-structure C.CCollection
2020-08-25 15:45:19 +08:00
type Collection struct {
2021-06-15 20:06:10 +08:00
collectionPtr C . CCollection
id UniqueID
partitionIDs [ ] UniqueID
schema * schemapb . CollectionSchema
2021-06-15 12:41:40 +08:00
2021-11-26 01:33:16 +08:00
channelMu sync . RWMutex
vChannels [ ] Channel
pChannels [ ] Channel
2021-11-09 09:27:04 +08:00
vDeltaChannels [ ] Channel
pDeltaChannels [ ] Channel
2021-06-19 18:38:07 +08:00
loadType loadType
releaseMu sync . RWMutex // guards release
releasedPartitions map [ UniqueID ] struct { }
releaseTime Timestamp
2020-08-25 15:45:19 +08:00
}
2021-09-28 22:40:05 +08:00
// ID returns collection id
2020-11-09 16:27:11 +08:00
func ( c * Collection ) ID ( ) UniqueID {
2020-12-10 16:31:09 +08:00
return c . id
2020-11-09 16:27:11 +08:00
}
2020-08-25 15:45:19 +08:00
2021-10-01 23:44:33 +08:00
// Schema returns the schema of collection
2021-01-18 10:38:41 +08:00
func ( c * Collection ) Schema ( ) * schemapb . CollectionSchema {
return c . schema
}
2021-10-03 00:38:13 +08:00
// addPartitionID would add a partition id to partition id list of collection
2021-02-05 10:53:11 +08:00
func ( c * Collection ) addPartitionID ( partitionID UniqueID ) {
2021-06-26 16:08:11 +08:00
c . releaseMu . Lock ( )
defer c . releaseMu . Unlock ( )
log . Debug ( "queryNode collection add a partition" , zap . Int64 ( "collection" , c . id ) , zap . Int64 ( "partitionID" , partitionID ) )
2021-02-05 10:53:11 +08:00
c . partitionIDs = append ( c . partitionIDs , partitionID )
2021-06-26 16:08:11 +08:00
log . Debug ( "queryNode collection info after add a partition" , zap . Int64 ( "collectionID" , c . id ) , zap . Int64s ( "partitions" , c . partitionIDs ) , zap . Any ( "releasePartitions" , c . releasedPartitions ) )
2021-02-05 10:53:11 +08:00
}
2021-10-03 00:40:03 +08:00
// removePartitionID remove the partition id from partition id list of collection
2021-02-05 10:53:11 +08:00
func ( c * Collection ) removePartitionID ( partitionID UniqueID ) {
tmpIDs := make ( [ ] UniqueID , 0 )
for _ , id := range c . partitionIDs {
2021-04-29 15:59:08 +08:00
if id != partitionID {
2021-02-05 10:53:11 +08:00
tmpIDs = append ( tmpIDs , id )
}
}
c . partitionIDs = tmpIDs
}
2021-10-03 00:52:02 +08:00
// addVChannels add virtual channels to collection
2021-06-15 20:06:10 +08:00
func ( c * Collection ) addVChannels ( channels [ ] Channel ) {
2021-11-17 23:37:11 +08:00
c . channelMu . Lock ( )
defer c . channelMu . Unlock ( )
2021-09-07 15:45:59 +08:00
OUTER :
for _ , dstChan := range channels {
for _ , srcChan := range c . vChannels {
if dstChan == srcChan {
log . Debug ( "vChannel has been existed in collection's vChannels" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "vChannel" , dstChan ) ,
)
continue OUTER
}
}
log . Debug ( "add vChannel to collection" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "vChannel" , dstChan ) ,
)
c . vChannels = append ( c . vChannels , dstChan )
}
2021-05-28 15:40:32 +08:00
}
2021-10-04 08:16:44 +08:00
// getVChannels get virtual channels of collection
2021-06-15 20:06:10 +08:00
func ( c * Collection ) getVChannels ( ) [ ] Channel {
2021-11-17 23:37:11 +08:00
c . channelMu . RLock ( )
defer c . channelMu . RUnlock ( )
2021-11-26 01:33:16 +08:00
tmpChannels := make ( [ ] Channel , len ( c . vChannels ) )
copy ( tmpChannels , c . vChannels )
return tmpChannels
}
// removeVChannel remove the virtual channel from collection
func ( c * Collection ) removeVChannel ( channel Channel ) {
c . channelMu . Lock ( )
defer c . channelMu . Unlock ( )
tmpChannels := make ( [ ] Channel , 0 )
for _ , vChannel := range c . vChannels {
if channel != vChannel {
tmpChannels = append ( tmpChannels , vChannel )
}
}
c . vChannels = tmpChannels
2021-11-29 20:11:49 +08:00
log . Debug ( "remove vChannel from collection" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "channel" , channel ) ,
)
2021-06-15 20:06:10 +08:00
}
2021-10-04 08:18:59 +08:00
// addPChannels add physical channels to physical channels of collection
2021-06-15 20:06:10 +08:00
func ( c * Collection ) addPChannels ( channels [ ] Channel ) {
2021-11-17 23:37:11 +08:00
c . channelMu . Lock ( )
defer c . channelMu . Unlock ( )
2021-09-07 15:45:59 +08:00
OUTER :
for _ , dstChan := range channels {
for _ , srcChan := range c . pChannels {
if dstChan == srcChan {
log . Debug ( "pChannel has been existed in collection's pChannels" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "pChannel" , dstChan ) ,
)
continue OUTER
}
}
log . Debug ( "add pChannel to collection" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "pChannel" , dstChan ) ,
)
c . pChannels = append ( c . pChannels , dstChan )
}
2021-06-15 20:06:10 +08:00
}
2021-10-04 08:22:51 +08:00
// getPChannels get physical channels of collection
2021-06-15 20:06:10 +08:00
func ( c * Collection ) getPChannels ( ) [ ] Channel {
2021-11-17 23:37:11 +08:00
c . channelMu . RLock ( )
defer c . channelMu . RUnlock ( )
2021-11-26 01:33:16 +08:00
tmpChannels := make ( [ ] Channel , len ( c . pChannels ) )
copy ( tmpChannels , c . pChannels )
return tmpChannels
2021-05-28 15:40:32 +08:00
}
2021-11-09 09:27:04 +08:00
// addPChannels add physical channels to physical channels of collection
func ( c * Collection ) addPDeltaChannels ( channels [ ] Channel ) {
2021-11-26 01:33:16 +08:00
c . channelMu . Lock ( )
defer c . channelMu . Unlock ( )
2021-11-09 09:27:04 +08:00
OUTER :
for _ , dstChan := range channels {
for _ , srcChan := range c . pDeltaChannels {
if dstChan == srcChan {
log . Debug ( "pChannel has been existed in collection's pChannels" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "pChannel" , dstChan ) ,
)
continue OUTER
}
}
log . Debug ( "add pChannel to collection" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "pChannel" , dstChan ) ,
)
c . pDeltaChannels = append ( c . pDeltaChannels , dstChan )
}
}
// getPChannels get physical channels of collection
func ( c * Collection ) getPDeltaChannels ( ) [ ] Channel {
2021-11-26 01:33:16 +08:00
c . channelMu . RLock ( )
defer c . channelMu . RUnlock ( )
tmpChannels := make ( [ ] Channel , len ( c . pDeltaChannels ) )
copy ( tmpChannels , c . pDeltaChannels )
return tmpChannels
2021-11-09 09:27:04 +08:00
}
func ( c * Collection ) getVDeltaChannels ( ) [ ] Channel {
2021-11-26 01:33:16 +08:00
c . channelMu . RLock ( )
defer c . channelMu . RUnlock ( )
tmpChannels := make ( [ ] Channel , len ( c . vDeltaChannels ) )
copy ( tmpChannels , c . vDeltaChannels )
return tmpChannels
2021-11-09 09:27:04 +08:00
}
// addVChannels add virtual channels to collection
func ( c * Collection ) addVDeltaChannels ( channels [ ] Channel ) {
2021-11-26 01:33:16 +08:00
c . channelMu . Lock ( )
defer c . channelMu . Unlock ( )
2021-11-09 09:27:04 +08:00
OUTER :
for _ , dstChan := range channels {
for _ , srcChan := range c . vDeltaChannels {
if dstChan == srcChan {
log . Debug ( "vDeltaChannel has been existed in collection's vDeltaChannels" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "vChannel" , dstChan ) ,
)
continue OUTER
}
}
log . Debug ( "add vDeltaChannel to collection" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "vDeltaChannel" , dstChan ) ,
)
c . vDeltaChannels = append ( c . vDeltaChannels , dstChan )
}
}
2021-11-26 01:33:16 +08:00
func ( c * Collection ) removeVDeltaChannel ( channel Channel ) {
c . channelMu . Lock ( )
defer c . channelMu . Unlock ( )
tmpChannels := make ( [ ] Channel , 0 )
for _ , vChannel := range c . vDeltaChannels {
if channel != vChannel {
tmpChannels = append ( tmpChannels , vChannel )
}
}
c . vDeltaChannels = tmpChannels
2021-11-29 20:11:49 +08:00
log . Debug ( "remove vDeltaChannel from collection" ,
zap . Any ( "collectionID" , c . ID ( ) ) ,
zap . Any ( "channel" , channel ) ,
)
2021-11-26 01:33:16 +08:00
}
2021-10-05 11:17:29 +08:00
// setReleaseTime records when collection is released
2021-06-15 12:41:40 +08:00
func ( c * Collection ) setReleaseTime ( t Timestamp ) {
c . releaseMu . Lock ( )
defer c . releaseMu . Unlock ( )
c . releaseTime = t
}
2021-10-05 11:15:14 +08:00
// getReleaseTime gets the time when collection is released
2021-06-15 12:41:40 +08:00
func ( c * Collection ) getReleaseTime ( ) Timestamp {
c . releaseMu . RLock ( )
defer c . releaseMu . RUnlock ( )
return c . releaseTime
}
2021-10-05 11:19:23 +08:00
// addReleasedPartition records the partition to indicate that this partition has been released
2021-06-19 18:38:07 +08:00
func ( c * Collection ) addReleasedPartition ( partitionID UniqueID ) {
c . releaseMu . Lock ( )
defer c . releaseMu . Unlock ( )
2021-06-26 16:08:11 +08:00
log . Debug ( "queryNode collection release a partition" , zap . Int64 ( "collectionID" , c . id ) , zap . Int64 ( "partition" , partitionID ) )
2021-06-19 18:38:07 +08:00
c . releasedPartitions [ partitionID ] = struct { } { }
2021-06-26 16:08:11 +08:00
partitions := make ( [ ] UniqueID , 0 )
for _ , id := range c . partitionIDs {
if id != partitionID {
partitions = append ( partitions , id )
}
}
c . partitionIDs = partitions
log . Debug ( "queryNode collection info after release a partition" , zap . Int64 ( "collectionID" , c . id ) , zap . Int64s ( "partitions" , c . partitionIDs ) , zap . Any ( "releasePartitions" , c . releasedPartitions ) )
}
2021-10-05 22:38:44 +08:00
// deleteReleasedPartition remove the released partition record from collection
2021-06-26 16:08:11 +08:00
func ( c * Collection ) deleteReleasedPartition ( partitionID UniqueID ) {
c . releaseMu . Lock ( )
defer c . releaseMu . Unlock ( )
log . Debug ( "queryNode collection reload a released partition" , zap . Int64 ( "collectionID" , c . id ) , zap . Int64 ( "partition" , partitionID ) )
delete ( c . releasedPartitions , partitionID )
log . Debug ( "queryNode collection info after reload a released partition" , zap . Int64 ( "collectionID" , c . id ) , zap . Int64s ( "partitions" , c . partitionIDs ) , zap . Any ( "releasePartitions" , c . releasedPartitions ) )
2021-06-19 18:38:07 +08:00
}
2021-10-05 22:40:34 +08:00
// checkReleasedPartitions returns error if any partition has been released
2021-06-19 18:38:07 +08:00
func ( c * Collection ) checkReleasedPartitions ( partitionIDs [ ] UniqueID ) error {
c . releaseMu . RLock ( )
defer c . releaseMu . RUnlock ( )
for _ , id := range partitionIDs {
if _ , ok := c . releasedPartitions [ id ] ; ok {
return errors . New ( "partition has been released" +
", collectionID = " + fmt . Sprintln ( c . ID ( ) ) +
", partitionID = " + fmt . Sprintln ( id ) )
}
}
return nil
}
2021-10-05 22:44:00 +08:00
// setLoadType set the loading type of collection, which is loadTypeCollection or loadTypePartition
2021-06-19 18:38:07 +08:00
func ( c * Collection ) setLoadType ( l loadType ) {
c . loadType = l
}
2021-10-06 23:34:24 +08:00
// getLoadType get the loadType of collection, which is loadTypeCollection or loadTypePartition
2021-06-19 18:38:07 +08:00
func ( c * Collection ) getLoadType ( ) loadType {
return c . loadType
}
2021-10-06 23:36:13 +08:00
// newCollection returns a new Collection
2021-01-18 10:38:41 +08:00
func newCollection ( collectionID UniqueID , schema * schemapb . CollectionSchema ) * Collection {
2020-09-21 18:16:06 +08:00
/ *
2020-11-09 16:27:11 +08:00
CCollection
2020-12-10 16:31:09 +08:00
NewCollection ( const char * schema_proto_blob ) ;
2020-10-24 10:45:57 +08:00
* /
2021-01-18 10:38:41 +08:00
schemaBlob := proto . MarshalTextString ( schema )
2020-12-10 16:31:09 +08:00
cSchemaBlob := C . CString ( schemaBlob )
collection := C . NewCollection ( cSchemaBlob )
var newCollection = & Collection {
2021-06-19 18:38:07 +08:00
collectionPtr : collection ,
id : collectionID ,
schema : schema ,
vChannels : make ( [ ] Channel , 0 ) ,
pChannels : make ( [ ] Channel , 0 ) ,
2021-11-09 09:27:04 +08:00
vDeltaChannels : make ( [ ] Channel , 0 ) ,
pDeltaChannels : make ( [ ] Channel , 0 ) ,
2021-06-19 18:38:07 +08:00
releasedPartitions : make ( map [ UniqueID ] struct { } ) ,
2020-12-10 16:31:09 +08:00
}
2021-03-26 18:40:04 +08:00
C . free ( unsafe . Pointer ( cSchemaBlob ) )
2020-10-24 10:45:57 +08:00
2021-03-05 09:21:35 +08:00
log . Debug ( "create collection" , zap . Int64 ( "collectionID" , collectionID ) )
2021-06-15 12:41:40 +08:00
newCollection . setReleaseTime ( Timestamp ( math . MaxUint64 ) )
2020-11-09 16:27:11 +08:00
return newCollection
2020-08-25 15:45:19 +08:00
}
2020-11-05 10:52:50 +08:00
2021-10-06 23:38:00 +08:00
// deleteCollection delete collection and free the collection memory
2020-11-09 16:27:11 +08:00
func deleteCollection ( collection * Collection ) {
/ *
void
deleteCollection ( CCollection collection ) ;
* /
cPtr := collection . collectionPtr
C . DeleteCollection ( cPtr )
2021-03-05 09:21:35 +08:00
collection . collectionPtr = nil
log . Debug ( "delete collection" , zap . Int64 ( "collectionID" , collection . ID ( ) ) )
collection = nil
2020-11-05 10:52:50 +08:00
}