mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-07 01:28:27 +08:00
- Introduce dynamic buffer sizing to avoid generating small binlogs during import - Refactor import slot calculation based on CPU and memory constraints - Implement dynamic pool sizing for sync manager and import tasks according to CPU core count issue: https://github.com/milvus-io/milvus/issues/43131 --------- Signed-off-by: bigsheeper <yihao.dai@zilliz.com>
158 lines
5.3 KiB
Go
158 lines
5.3 KiB
Go
// 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
|
|
// 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.
|
|
|
|
package importv2
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// TestMemoryAllocatorBasicOperations tests basic memory allocation and release operations
|
|
func TestMemoryAllocatorBasicOperations(t *testing.T) {
|
|
// Create memory allocator with 1GB system memory
|
|
ma := NewMemoryAllocator(1024 * 1024 * 1024)
|
|
|
|
// Test initial state
|
|
assert.Equal(t, int64(0), ma.(*memoryAllocator).usedMemory)
|
|
|
|
// Test memory allocation for task 1
|
|
success := ma.TryAllocate(1, 50*1024*1024) // 50MB for task 1
|
|
assert.True(t, success)
|
|
assert.Equal(t, int64(50*1024*1024), ma.(*memoryAllocator).usedMemory)
|
|
|
|
// Test memory allocation for task 2
|
|
success = ma.TryAllocate(2, 50*1024*1024) // 50MB for task 2
|
|
assert.True(t, success)
|
|
assert.Equal(t, int64(100*1024*1024), ma.(*memoryAllocator).usedMemory)
|
|
|
|
// Test memory release for task 1
|
|
ma.Release(1, 50*1024*1024)
|
|
assert.Equal(t, int64(50*1024*1024), ma.(*memoryAllocator).usedMemory)
|
|
|
|
// Test memory release for task 2
|
|
ma.Release(2, 50*1024*1024)
|
|
assert.Equal(t, int64(0), ma.(*memoryAllocator).usedMemory)
|
|
}
|
|
|
|
// TestMemoryAllocatorMemoryLimit tests memory limit enforcement
|
|
func TestMemoryAllocatorMemoryLimit(t *testing.T) {
|
|
// Create memory allocator with 1GB system memory
|
|
ma := NewMemoryAllocator(1024 * 1024 * 1024)
|
|
|
|
// Get the memory limit based on system memory and configuration percentage
|
|
memoryLimit := ma.(*memoryAllocator).systemTotalMemory
|
|
// Use a reasonable test size that should be within limits
|
|
testSize := memoryLimit / 10 // Use 10% of available memory
|
|
|
|
// Allocate memory up to the limit
|
|
success := ma.TryAllocate(1, testSize)
|
|
assert.True(t, success)
|
|
assert.Equal(t, testSize, ma.(*memoryAllocator).usedMemory)
|
|
|
|
// Try to allocate more memory than available (should fail)
|
|
success = ma.TryAllocate(2, memoryLimit)
|
|
assert.False(t, success)
|
|
assert.Equal(t, testSize, ma.(*memoryAllocator).usedMemory) // Should remain unchanged
|
|
|
|
// Release the allocated memory
|
|
ma.Release(1, testSize)
|
|
assert.Equal(t, int64(0), ma.(*memoryAllocator).usedMemory)
|
|
}
|
|
|
|
// TestMemoryAllocatorConcurrentAccess tests concurrent memory allocation and release
|
|
func TestMemoryAllocatorConcurrentAccess(t *testing.T) {
|
|
// Create memory allocator with 1GB system memory
|
|
ma := NewMemoryAllocator(1024 * 1024 * 1024)
|
|
|
|
// Test concurrent memory requests
|
|
done := make(chan bool, 10)
|
|
for i := 0; i < 10; i++ {
|
|
taskID := int64(i + 1)
|
|
go func() {
|
|
success := ma.TryAllocate(taskID, 50*1024*1024) // 50MB each
|
|
if success {
|
|
ma.Release(taskID, 50*1024*1024)
|
|
}
|
|
done <- true
|
|
}()
|
|
}
|
|
|
|
// Wait for all goroutines to complete
|
|
for i := 0; i < 10; i++ {
|
|
<-done
|
|
}
|
|
|
|
// Verify final state - should be 0 or the sum of remaining allocations
|
|
// depending on memory limit and concurrent execution
|
|
finalMemory := ma.(*memoryAllocator).usedMemory
|
|
assert.GreaterOrEqual(t, finalMemory, int64(0))
|
|
}
|
|
|
|
// TestMemoryAllocatorNegativeRelease tests handling of negative memory release
|
|
func TestMemoryAllocatorNegativeRelease(t *testing.T) {
|
|
// Create memory allocator with 1GB system memory
|
|
ma := NewMemoryAllocator(1024 * 1024 * 1024)
|
|
|
|
// Allocate some memory
|
|
success := ma.TryAllocate(1, 100*1024*1024) // 100MB
|
|
assert.True(t, success)
|
|
assert.Equal(t, int64(100*1024*1024), ma.(*memoryAllocator).usedMemory)
|
|
|
|
// Release more than allocated (should not go negative)
|
|
ma.Release(1, 200*1024*1024) // 200MB
|
|
assert.Equal(t, int64(0), ma.(*memoryAllocator).usedMemory) // Should be reset to 0
|
|
}
|
|
|
|
// TestMemoryAllocatorMultipleTasks tests memory management for multiple tasks
|
|
func TestMemoryAllocatorMultipleTasks(t *testing.T) {
|
|
// Create memory allocator with 1GB system memory
|
|
ma := NewMemoryAllocator(1024 * 1024 * 1024)
|
|
|
|
// Allocate memory for multiple tasks with smaller sizes
|
|
taskIDs := []int64{1, 2, 3, 4, 5}
|
|
sizes := []int64{20, 30, 25, 15, 35} // Total: 125MB
|
|
|
|
for i, taskID := range taskIDs {
|
|
success := ma.TryAllocate(taskID, sizes[i]*1024*1024)
|
|
assert.True(t, success)
|
|
}
|
|
|
|
// Verify total used memory
|
|
expectedTotal := int64(0)
|
|
for _, size := range sizes {
|
|
expectedTotal += size * 1024 * 1024
|
|
}
|
|
assert.Equal(t, expectedTotal, ma.(*memoryAllocator).usedMemory)
|
|
|
|
// Release memory for specific tasks
|
|
ma.Release(2, 30*1024*1024) // Release task 2
|
|
ma.Release(4, 15*1024*1024) // Release task 4
|
|
|
|
// Verify updated memory usage
|
|
expectedTotal = (20 + 25 + 35) * 1024 * 1024 // 80MB
|
|
assert.Equal(t, expectedTotal, ma.(*memoryAllocator).usedMemory)
|
|
|
|
// Release remaining tasks
|
|
ma.Release(1, 20*1024*1024)
|
|
ma.Release(3, 25*1024*1024)
|
|
ma.Release(5, 35*1024*1024)
|
|
|
|
// Verify final state
|
|
assert.Equal(t, int64(0), ma.(*memoryAllocator).usedMemory)
|
|
}
|