mirror of
https://gitee.com/milvus-io/milvus.git
synced 2024-12-02 11:59:00 +08:00
enhance: speed up minor functions calls in datacoord (#32389)
Related to https://github.com/milvus-io/milvus/issues/32165 1. nodeid based channel store access should use map access instead of iteration. 2. The join-ish functions calls are slow when # collections/segments increases (e.g. 10k). e.g. getNumRowsOfCollectionUnsafe is O(num_segments); GetAllCollectionNumRows is of O(num_collections*num_segments). Signed-off-by: yiwangdr <yiwangdr@gmail.com>
This commit is contained in:
parent
93f0c262c1
commit
037de8e4d3
@ -551,11 +551,9 @@ func (c *ChannelManagerImpl) Match(nodeID int64, channel string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ch := range info.Channels {
|
if _, ok := info.Channels[channel]; ok {
|
||||||
if ch.GetName() == channel {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,44 +399,36 @@ func (c *ChannelStore) GetNodesChannels() []*NodeChannelInfo {
|
|||||||
|
|
||||||
// GetBufferChannelInfo returns all unassigned channels.
|
// GetBufferChannelInfo returns all unassigned channels.
|
||||||
func (c *ChannelStore) GetBufferChannelInfo() *NodeChannelInfo {
|
func (c *ChannelStore) GetBufferChannelInfo() *NodeChannelInfo {
|
||||||
for id, info := range c.channelsInfo {
|
if info, ok := c.channelsInfo[bufferID]; ok {
|
||||||
if id == bufferID {
|
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNode returns the channel info of a given node.
|
// GetNode returns the channel info of a given node.
|
||||||
func (c *ChannelStore) GetNode(nodeID int64) *NodeChannelInfo {
|
func (c *ChannelStore) GetNode(nodeID int64) *NodeChannelInfo {
|
||||||
for id, info := range c.channelsInfo {
|
if info, ok := c.channelsInfo[nodeID]; ok {
|
||||||
if id == nodeID {
|
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChannelStore) GetNodeChannelCount(nodeID int64) int {
|
func (c *ChannelStore) GetNodeChannelCount(nodeID int64) int {
|
||||||
for id, info := range c.channelsInfo {
|
if info, ok := c.channelsInfo[nodeID]; ok {
|
||||||
if id == nodeID {
|
|
||||||
return len(info.Channels)
|
return len(info.Channels)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete removes the given node from the channel store and returns its channels.
|
// Delete removes the given node from the channel store and returns its channels.
|
||||||
func (c *ChannelStore) Delete(nodeID int64) ([]RWChannel, error) {
|
func (c *ChannelStore) Delete(nodeID int64) ([]RWChannel, error) {
|
||||||
for id, info := range c.channelsInfo {
|
if info, ok := c.channelsInfo[nodeID]; ok {
|
||||||
if id == nodeID {
|
|
||||||
if err := c.remove(nodeID); err != nil {
|
if err := c.remove(nodeID); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
delete(c.channelsInfo, id)
|
delete(c.channelsInfo, nodeID)
|
||||||
return lo.Values(info.Channels), nil
|
return lo.Values(info.Channels), nil
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +385,7 @@ func (m *indexMeta) GetSegmentIndexState(collID, segmentID UniqueID, indexID Uni
|
|||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *indexMeta) GetIndexedSegments(collectionID int64, fieldIDs []UniqueID) []int64 {
|
func (m *indexMeta) GetIndexedSegments(collectionID int64, segmentIDs, fieldIDs []UniqueID) []int64 {
|
||||||
m.RLock()
|
m.RLock()
|
||||||
defer m.RUnlock()
|
defer m.RUnlock()
|
||||||
|
|
||||||
@ -412,11 +412,13 @@ func (m *indexMeta) GetIndexedSegments(collectionID int64, fieldIDs []UniqueID)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret := make([]int64, 0)
|
ret := make([]int64, 0)
|
||||||
for sid, indexes := range m.segmentIndexes {
|
for _, sid := range segmentIDs {
|
||||||
|
if indexes, ok := m.segmentIndexes[sid]; ok {
|
||||||
if checkSegmentState(indexes) {
|
if checkSegmentState(indexes) {
|
||||||
ret = append(ret, sid)
|
ret = append(ret, sid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@ -614,17 +614,17 @@ func TestMeta_GetIndexedSegment(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.Run("success", func(t *testing.T) {
|
t.Run("success", func(t *testing.T) {
|
||||||
segments := m.GetIndexedSegments(collID, []int64{fieldID})
|
segments := m.GetIndexedSegments(collID, []int64{segID}, []int64{fieldID})
|
||||||
assert.Len(t, segments, 1)
|
assert.Len(t, segments, 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("no index on field", func(t *testing.T) {
|
t.Run("no index on field", func(t *testing.T) {
|
||||||
segments := m.GetIndexedSegments(collID, []int64{fieldID + 1})
|
segments := m.GetIndexedSegments(collID, []int64{segID}, []int64{fieldID + 1})
|
||||||
assert.Len(t, segments, 0)
|
assert.Len(t, segments, 0)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("no index", func(t *testing.T) {
|
t.Run("no index", func(t *testing.T) {
|
||||||
segments := m.GetIndexedSegments(collID+1, []int64{fieldID})
|
segments := m.GetIndexedSegments(collID+1, []int64{segID}, []int64{fieldID})
|
||||||
assert.Len(t, segments, 0)
|
assert.Len(t, segments, 0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -321,8 +321,11 @@ func (m *meta) GetAllCollectionNumRows() map[int64]int64 {
|
|||||||
m.RLock()
|
m.RLock()
|
||||||
defer m.RUnlock()
|
defer m.RUnlock()
|
||||||
ret := make(map[int64]int64, len(m.collections))
|
ret := make(map[int64]int64, len(m.collections))
|
||||||
for collectionID := range m.collections {
|
segments := m.segments.GetSegments()
|
||||||
ret[collectionID] = m.getNumRowsOfCollectionUnsafe(collectionID)
|
for _, segment := range segments {
|
||||||
|
if isSegmentHealthy(segment) {
|
||||||
|
ret[segment.GetCollectionID()] += segment.GetNumOfRows()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
@ -1053,14 +1056,7 @@ func (m *meta) GetFlushingSegments() []*SegmentInfo {
|
|||||||
func (m *meta) SelectSegments(selector SegmentInfoSelector) []*SegmentInfo {
|
func (m *meta) SelectSegments(selector SegmentInfoSelector) []*SegmentInfo {
|
||||||
m.RLock()
|
m.RLock()
|
||||||
defer m.RUnlock()
|
defer m.RUnlock()
|
||||||
var ret []*SegmentInfo
|
return m.segments.GetSegmentsBySelector(selector)
|
||||||
segments := m.segments.GetSegments()
|
|
||||||
for _, info := range segments {
|
|
||||||
if selector(info) {
|
|
||||||
ret = append(ret, info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddAllocation add allocation in segment
|
// AddAllocation add allocation in segment
|
||||||
|
@ -93,6 +93,16 @@ func (s *SegmentsInfo) GetSegments() []*SegmentInfo {
|
|||||||
return segments
|
return segments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SegmentsInfo) GetSegmentsBySelector(selector SegmentInfoSelector) []*SegmentInfo {
|
||||||
|
var segments []*SegmentInfo
|
||||||
|
for _, segment := range s.segments {
|
||||||
|
if selector(segment) {
|
||||||
|
segments = append(segments, segment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return segments
|
||||||
|
}
|
||||||
|
|
||||||
// GetCompactionTo returns the segment that the provided segment is compacted to.
|
// GetCompactionTo returns the segment that the provided segment is compacted to.
|
||||||
// Return (nil, false) if given segmentID can not found in the meta.
|
// Return (nil, false) if given segmentID can not found in the meta.
|
||||||
// Return (nil, true) if given segmentID can be found not no compaction to.
|
// Return (nil, true) if given segmentID can be found not no compaction to.
|
||||||
|
@ -92,9 +92,12 @@ func FilterInIndexedSegments(handler Handler, mt *meta, segments ...*SegmentInfo
|
|||||||
vecFieldIDs = append(vecFieldIDs, field.GetFieldID())
|
vecFieldIDs = append(vecFieldIDs, field.GetFieldID())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
segmentIDs := lo.Map(segmentList, func(seg *SegmentInfo, _ int) UniqueID {
|
||||||
|
return seg.GetID()
|
||||||
|
})
|
||||||
|
|
||||||
// get indexed segments which finish build index on all vector field
|
// get indexed segments which finish build index on all vector field
|
||||||
indexed := mt.indexMeta.GetIndexedSegments(collection, vecFieldIDs)
|
indexed := mt.indexMeta.GetIndexedSegments(collection, segmentIDs, vecFieldIDs)
|
||||||
if len(indexed) > 0 {
|
if len(indexed) > 0 {
|
||||||
indexedSet := typeutil.NewUniqueSet(indexed...)
|
indexedSet := typeutil.NewUniqueSet(indexed...)
|
||||||
for _, segment := range segmentList {
|
for _, segment := range segmentList {
|
||||||
|
Loading…
Reference in New Issue
Block a user