2021-05-21 10:30:41 +00:00
|
|
|
// Copyright (C) 2019-2020 Zilliz. All rights reserved.//
|
2021-04-19 03:35:38 +00:00
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
|
|
|
|
// with the License. You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// 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-06-22 02:42:07 +00:00
|
|
|
package datacoord
|
2021-01-22 11:43:27 +00:00
|
|
|
|
|
|
|
import (
|
2021-03-23 08:57:59 +00:00
|
|
|
"context"
|
2021-01-22 11:43:27 +00:00
|
|
|
"testing"
|
2021-08-19 06:08:10 +00:00
|
|
|
"time"
|
2021-01-22 11:43:27 +00:00
|
|
|
|
2021-05-21 10:30:41 +00:00
|
|
|
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
2021-04-22 06:45:57 +00:00
|
|
|
"github.com/milvus-io/milvus/internal/proto/datapb"
|
2021-07-23 13:58:33 +00:00
|
|
|
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
2021-04-09 01:55:04 +00:00
|
|
|
|
2021-01-22 11:43:27 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestAllocSegment(t *testing.T) {
|
2021-03-23 08:57:59 +00:00
|
|
|
ctx := context.Background()
|
2021-01-22 11:43:27 +00:00
|
|
|
Params.Init()
|
|
|
|
mockAllocator := newMockAllocator()
|
|
|
|
meta, err := newMemoryMeta(mockAllocator)
|
|
|
|
assert.Nil(t, err)
|
2021-06-03 11:06:33 +00:00
|
|
|
segmentManager := newSegmentManager(meta, mockAllocator)
|
2021-01-22 11:43:27 +00:00
|
|
|
|
2021-01-23 06:41:29 +00:00
|
|
|
schema := newTestSchema()
|
2021-08-23 09:59:51 +00:00
|
|
|
collID, err := mockAllocator.allocID(ctx)
|
2021-01-23 06:41:29 +00:00
|
|
|
assert.Nil(t, err)
|
2021-07-07 06:02:01 +00:00
|
|
|
meta.AddCollection(&datapb.CollectionInfo{ID: collID, Schema: schema})
|
2021-07-23 13:58:33 +00:00
|
|
|
|
|
|
|
t.Run("normal allocation", func(t *testing.T) {
|
|
|
|
allocations, err := segmentManager.AllocSegment(ctx, collID, 100, "c1", 100)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.EqualValues(t, 1, len(allocations))
|
|
|
|
assert.EqualValues(t, 100, allocations[0].NumOfRows)
|
|
|
|
assert.NotEqualValues(t, 0, allocations[0].SegmentID)
|
|
|
|
assert.NotEqualValues(t, 0, allocations[0].ExpireTime)
|
|
|
|
})
|
2021-01-22 11:43:27 +00:00
|
|
|
}
|
|
|
|
|
2021-05-21 10:30:41 +00:00
|
|
|
func TestLoadSegmentsFromMeta(t *testing.T) {
|
2021-08-23 09:59:51 +00:00
|
|
|
ctx := context.Background()
|
2021-01-22 11:43:27 +00:00
|
|
|
Params.Init()
|
|
|
|
mockAllocator := newMockAllocator()
|
|
|
|
meta, err := newMemoryMeta(mockAllocator)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
2021-01-23 06:41:29 +00:00
|
|
|
schema := newTestSchema()
|
2021-08-23 09:59:51 +00:00
|
|
|
collID, err := mockAllocator.allocID(ctx)
|
2021-01-23 06:41:29 +00:00
|
|
|
assert.Nil(t, err)
|
2021-07-07 06:02:01 +00:00
|
|
|
meta.AddCollection(&datapb.CollectionInfo{ID: collID, Schema: schema})
|
2021-01-22 11:43:27 +00:00
|
|
|
|
2021-05-21 10:30:41 +00:00
|
|
|
sealedSegment := &datapb.SegmentInfo{
|
|
|
|
ID: 1,
|
|
|
|
CollectionID: collID,
|
|
|
|
PartitionID: 0,
|
|
|
|
InsertChannel: "",
|
|
|
|
State: commonpb.SegmentState_Sealed,
|
|
|
|
MaxRowNum: 100,
|
|
|
|
LastExpireTime: 1000,
|
|
|
|
}
|
|
|
|
growingSegment := &datapb.SegmentInfo{
|
|
|
|
ID: 2,
|
|
|
|
CollectionID: collID,
|
|
|
|
PartitionID: 0,
|
|
|
|
InsertChannel: "",
|
|
|
|
State: commonpb.SegmentState_Growing,
|
|
|
|
MaxRowNum: 100,
|
|
|
|
LastExpireTime: 1000,
|
|
|
|
}
|
|
|
|
flushedSegment := &datapb.SegmentInfo{
|
|
|
|
ID: 3,
|
|
|
|
CollectionID: collID,
|
|
|
|
PartitionID: 0,
|
|
|
|
InsertChannel: "",
|
|
|
|
State: commonpb.SegmentState_Flushed,
|
|
|
|
MaxRowNum: 100,
|
|
|
|
LastExpireTime: 1000,
|
|
|
|
}
|
2021-07-12 09:24:25 +00:00
|
|
|
err = meta.AddSegment(NewSegmentInfo(sealedSegment))
|
2021-05-21 10:30:41 +00:00
|
|
|
assert.Nil(t, err)
|
2021-07-12 09:24:25 +00:00
|
|
|
err = meta.AddSegment(NewSegmentInfo(growingSegment))
|
2021-05-21 10:30:41 +00:00
|
|
|
assert.Nil(t, err)
|
2021-07-12 09:24:25 +00:00
|
|
|
err = meta.AddSegment(NewSegmentInfo(flushedSegment))
|
2021-01-22 11:43:27 +00:00
|
|
|
assert.Nil(t, err)
|
2021-02-02 10:53:10 +00:00
|
|
|
|
2021-06-03 11:06:33 +00:00
|
|
|
segmentManager := newSegmentManager(meta, mockAllocator)
|
2021-07-12 09:24:25 +00:00
|
|
|
segments := segmentManager.segments
|
2021-05-21 10:30:41 +00:00
|
|
|
assert.EqualValues(t, 2, len(segments))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSaveSegmentsToMeta(t *testing.T) {
|
|
|
|
Params.Init()
|
|
|
|
mockAllocator := newMockAllocator()
|
|
|
|
meta, err := newMemoryMeta(mockAllocator)
|
2021-01-22 11:43:27 +00:00
|
|
|
assert.Nil(t, err)
|
2021-05-21 10:30:41 +00:00
|
|
|
|
|
|
|
schema := newTestSchema()
|
2021-08-23 09:59:51 +00:00
|
|
|
collID, err := mockAllocator.allocID(context.Background())
|
2021-02-02 10:53:10 +00:00
|
|
|
assert.Nil(t, err)
|
2021-07-07 06:02:01 +00:00
|
|
|
meta.AddCollection(&datapb.CollectionInfo{ID: collID, Schema: schema})
|
2021-06-03 11:06:33 +00:00
|
|
|
segmentManager := newSegmentManager(meta, mockAllocator)
|
2021-07-23 13:58:33 +00:00
|
|
|
allocations, err := segmentManager.AllocSegment(context.Background(), collID, 0, "c1", 1000)
|
2021-05-21 10:30:41 +00:00
|
|
|
assert.Nil(t, err)
|
2021-07-23 13:58:33 +00:00
|
|
|
assert.EqualValues(t, 1, len(allocations))
|
2021-06-23 08:56:11 +00:00
|
|
|
_, err = segmentManager.SealAllSegments(context.Background(), collID)
|
2021-05-21 10:30:41 +00:00
|
|
|
assert.Nil(t, err)
|
2021-07-23 13:58:33 +00:00
|
|
|
segment := meta.GetSegment(allocations[0].SegmentID)
|
2021-07-07 06:02:01 +00:00
|
|
|
assert.NotNil(t, segment)
|
2021-07-23 13:58:33 +00:00
|
|
|
assert.EqualValues(t, segment.LastExpireTime, allocations[0].ExpireTime)
|
2021-05-21 10:30:41 +00:00
|
|
|
assert.EqualValues(t, commonpb.SegmentState_Sealed, segment.State)
|
2021-01-22 11:43:27 +00:00
|
|
|
}
|
2021-07-12 09:24:25 +00:00
|
|
|
|
|
|
|
func TestDropSegment(t *testing.T) {
|
|
|
|
Params.Init()
|
|
|
|
mockAllocator := newMockAllocator()
|
|
|
|
meta, err := newMemoryMeta(mockAllocator)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
schema := newTestSchema()
|
2021-08-23 09:59:51 +00:00
|
|
|
collID, err := mockAllocator.allocID(context.Background())
|
2021-07-12 09:24:25 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
meta.AddCollection(&datapb.CollectionInfo{ID: collID, Schema: schema})
|
|
|
|
segmentManager := newSegmentManager(meta, mockAllocator)
|
2021-07-23 13:58:33 +00:00
|
|
|
allocations, err := segmentManager.AllocSegment(context.Background(), collID, 0, "c1", 1000)
|
2021-07-12 09:24:25 +00:00
|
|
|
assert.Nil(t, err)
|
2021-07-23 13:58:33 +00:00
|
|
|
assert.EqualValues(t, 1, len(allocations))
|
|
|
|
segID := allocations[0].SegmentID
|
2021-07-12 09:24:25 +00:00
|
|
|
segment := meta.GetSegment(segID)
|
|
|
|
assert.NotNil(t, segment)
|
|
|
|
|
|
|
|
segmentManager.DropSegment(context.Background(), segID)
|
|
|
|
segment = meta.GetSegment(segID)
|
|
|
|
assert.NotNil(t, segment)
|
|
|
|
}
|
2021-07-23 13:58:33 +00:00
|
|
|
|
|
|
|
func TestAllocRowsLargerThanOneSegment(t *testing.T) {
|
|
|
|
Params.Init()
|
|
|
|
mockAllocator := newMockAllocator()
|
|
|
|
meta, err := newMemoryMeta(mockAllocator)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
schema := newTestSchema()
|
2021-08-23 09:59:51 +00:00
|
|
|
collID, err := mockAllocator.allocID(context.Background())
|
2021-07-23 13:58:33 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
meta.AddCollection(&datapb.CollectionInfo{ID: collID, Schema: schema})
|
|
|
|
|
|
|
|
var mockPolicy = func(schema *schemapb.CollectionSchema) (int, error) {
|
|
|
|
return 1, nil
|
|
|
|
}
|
|
|
|
segmentManager := newSegmentManager(meta, mockAllocator, withCalUpperLimitPolicy(mockPolicy))
|
|
|
|
allocations, err := segmentManager.AllocSegment(context.TODO(), collID, 0, "c1", 2)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.EqualValues(t, 2, len(allocations))
|
|
|
|
assert.EqualValues(t, 1, allocations[0].NumOfRows)
|
|
|
|
assert.EqualValues(t, 1, allocations[1].NumOfRows)
|
|
|
|
}
|
2021-08-12 02:48:08 +00:00
|
|
|
|
|
|
|
func TestExpireAllocation(t *testing.T) {
|
|
|
|
Params.Init()
|
|
|
|
mockAllocator := newMockAllocator()
|
|
|
|
meta, err := newMemoryMeta(mockAllocator)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
schema := newTestSchema()
|
2021-08-23 09:59:51 +00:00
|
|
|
collID, err := mockAllocator.allocID(context.Background())
|
2021-08-12 02:48:08 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
meta.AddCollection(&datapb.CollectionInfo{ID: collID, Schema: schema})
|
|
|
|
|
|
|
|
var mockPolicy = func(schema *schemapb.CollectionSchema) (int, error) {
|
|
|
|
return 10000000, nil
|
|
|
|
}
|
|
|
|
segmentManager := newSegmentManager(meta, mockAllocator, withCalUpperLimitPolicy(mockPolicy))
|
|
|
|
// alloc 100 times and expire
|
|
|
|
var maxts Timestamp
|
|
|
|
var id int64 = -1
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
allocs, err := segmentManager.AllocSegment(context.TODO(), collID, 0, "ch1", 100)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.EqualValues(t, 1, len(allocs))
|
|
|
|
if id == -1 {
|
|
|
|
id = allocs[0].SegmentID
|
|
|
|
} else {
|
|
|
|
assert.EqualValues(t, id, allocs[0].SegmentID)
|
|
|
|
}
|
|
|
|
if allocs[0].ExpireTime > maxts {
|
|
|
|
maxts = allocs[0].ExpireTime
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
segment := meta.GetSegment(id)
|
|
|
|
assert.NotNil(t, segment)
|
|
|
|
assert.EqualValues(t, 100, len(segment.allocations))
|
|
|
|
segmentManager.ExpireAllocations("ch1", maxts)
|
|
|
|
segment = meta.GetSegment(id)
|
|
|
|
assert.NotNil(t, segment)
|
|
|
|
assert.EqualValues(t, 0, len(segment.allocations))
|
|
|
|
}
|
2021-08-19 06:08:10 +00:00
|
|
|
|
|
|
|
func TestGetFlushableSegments(t *testing.T) {
|
|
|
|
t.Run("get flushable segments between small interval", func(t *testing.T) {
|
|
|
|
Params.Init()
|
|
|
|
mockAllocator := newMockAllocator()
|
|
|
|
meta, err := newMemoryMeta(mockAllocator)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
|
|
|
|
schema := newTestSchema()
|
2021-08-23 09:59:51 +00:00
|
|
|
collID, err := mockAllocator.allocID(context.Background())
|
2021-08-19 06:08:10 +00:00
|
|
|
assert.Nil(t, err)
|
|
|
|
meta.AddCollection(&datapb.CollectionInfo{ID: collID, Schema: schema})
|
|
|
|
segmentManager := newSegmentManager(meta, mockAllocator)
|
|
|
|
allocations, err := segmentManager.AllocSegment(context.TODO(), collID, 0, "c1", 2)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.EqualValues(t, 1, len(allocations))
|
|
|
|
|
|
|
|
ids, err := segmentManager.SealAllSegments(context.TODO(), collID)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.EqualValues(t, 1, len(ids))
|
|
|
|
assert.EqualValues(t, allocations[0].SegmentID, ids[0])
|
|
|
|
|
|
|
|
ids, err = segmentManager.GetFlushableSegments(context.TODO(), "c1", allocations[0].ExpireTime)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.EqualValues(t, 1, len(ids))
|
|
|
|
assert.EqualValues(t, allocations[0].SegmentID, ids[0])
|
|
|
|
|
|
|
|
meta.SetLastFlushTime(allocations[0].SegmentID, time.Now())
|
|
|
|
ids, err = segmentManager.GetFlushableSegments(context.TODO(), "c1", allocations[0].ExpireTime)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Empty(t, ids)
|
|
|
|
|
|
|
|
meta.SetLastFlushTime(allocations[0].SegmentID, time.Now().Local().Add(-flushInterval))
|
|
|
|
ids, err = segmentManager.GetFlushableSegments(context.TODO(), "c1", allocations[0].ExpireTime)
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.EqualValues(t, 1, len(ids))
|
|
|
|
assert.EqualValues(t, allocations[0].SegmentID, ids[0])
|
|
|
|
})
|
|
|
|
}
|