#include "mkql_vector_spiller_adapter.h" #include "mock_spiller_ut.h" #include namespace NKikimr::NMiniKQL { namespace { template std::vector> CreateSimpleVectorOfSize(size_t size) { std::vector> v; v.reserve(size); for (size_t i = 0; i < size; ++i) { v.push_back(i); } return v; } template void SaveRestoreAndCompareVectors(const std::vector>>& vectors, size_t spillerChunkSizeInBytes) { auto spiller = TVectorSpillerAdapter>(CreateMockSpiller(), spillerChunkSizeInBytes); for (const auto& vec : vectors) { auto copiedVector = vec; spiller.AddData(std::move(copiedVector)); while (!spiller.IsAcceptingData()) { spiller.Update(); } } spiller.Finalize(); while (!spiller.IsAcceptingDataRequests()) { spiller.Update(); } for (const auto& vec : vectors) { spiller.RequestNextVector(); while (!spiller.IsDataReady()) { spiller.Update(); } auto extractedVector = spiller.ExtractVector(); UNIT_ASSERT_VALUES_EQUAL(vec, extractedVector); } } template void RunTestForSingleVector(size_t vectorSize, size_t chunkSize, bool sizeInBytes) { std::vector v = CreateSimpleVectorOfSize(vectorSize); size_t chunkSizeInBytes = sizeInBytes ? chunkSize : chunkSize * sizeof(T); SaveRestoreAndCompareVectors({v}, chunkSizeInBytes); } } Y_UNIT_TEST_SUITE(TVectorSpillerAdapterTest_SingleVector) { Y_UNIT_TEST(VectorOfExactChunkSize) { TScopedAlloc Alloc(__LOCATION__); size_t vectorSize = 5; RunTestForSingleVector(vectorSize, vectorSize, false); RunTestForSingleVector(vectorSize, vectorSize, false); } Y_UNIT_TEST(VectorLargerThanChunkSize) { TScopedAlloc Alloc(__LOCATION__); size_t vectorSize = 10; size_t chunkSize = 3; RunTestForSingleVector(vectorSize, chunkSize, false); RunTestForSingleVector(vectorSize, chunkSize, false); } Y_UNIT_TEST(VectorLargerThanChunkSizePrime) { TScopedAlloc Alloc(__LOCATION__); size_t vectorSize = 10; size_t chunkSizeBytes = 7; RunTestForSingleVector(vectorSize, chunkSizeBytes, true); RunTestForSingleVector(vectorSize, chunkSizeBytes, true); } Y_UNIT_TEST(VectorLessThanChunkSize) { TScopedAlloc Alloc(__LOCATION__); size_t vectorSize = 5; size_t chunkSize = 10; RunTestForSingleVector(vectorSize, chunkSize, false); RunTestForSingleVector(vectorSize, chunkSize, false); } } Y_UNIT_TEST_SUITE(TVectorSpillerAdapterTest_MultipleVectors) { template void ManyDifferentSizes_TestRunner() { std::vector>> vectors; for (int vectorSize = 0; vectorSize <= 100; ++vectorSize) { vectors.push_back(CreateSimpleVectorOfSize(vectorSize)); } SaveRestoreAndCompareVectors(vectors, 20); } Y_UNIT_TEST(ManyDifferentSizes) { TScopedAlloc Alloc(__LOCATION__); ManyDifferentSizes_TestRunner(); ManyDifferentSizes_TestRunner(); } template void ManyDifferentSizesReversed_TestRunner() { std::vector>> vectors; for (int vectorSize = 100; vectorSize >= 0; --vectorSize) { vectors.push_back(CreateSimpleVectorOfSize(vectorSize)); } SaveRestoreAndCompareVectors(vectors, 20); } Y_UNIT_TEST(ManyDifferentSizesReversed) { TScopedAlloc Alloc(__LOCATION__); ManyDifferentSizesReversed_TestRunner(); ManyDifferentSizesReversed_TestRunner(); } template void VectorsInOneChunk_TestRunner() { std::vector>> vectors; size_t totalSize = 0; for (int vectorSize = 1; vectorSize < 5; ++vectorSize) { std::vector v = CreateSimpleVectorOfSize(vectorSize); totalSize += vectorSize; vectors.push_back(v); } SaveRestoreAndCompareVectors(vectors, totalSize * sizeof(int) + 10); } Y_UNIT_TEST(VectorsInOneChunk) { TScopedAlloc Alloc(__LOCATION__); VectorsInOneChunk_TestRunner(); VectorsInOneChunk_TestRunner(); } template void EmptyVectorsInTheMiddle_TestRunner() { std::vector>> vectors; size_t totalSize = 0; for (int vectorSize = 1; vectorSize < 5; ++vectorSize) { std::vector v = CreateSimpleVectorOfSize(vectorSize); totalSize += vectorSize; vectors.push_back(v); } vectors.push_back({}); vectors.push_back({}); for (int vectorSize = 1; vectorSize < 5; ++vectorSize) { std::vector v = CreateSimpleVectorOfSize(vectorSize); totalSize += vectorSize; vectors.push_back(v); } SaveRestoreAndCompareVectors(vectors, totalSize * sizeof(T) + 10); } Y_UNIT_TEST(EmptyVectorsInTheMiddle) { TScopedAlloc Alloc(__LOCATION__); EmptyVectorsInTheMiddle_TestRunner(); EmptyVectorsInTheMiddle_TestRunner(); } template void RequestedVectorPartlyInMemory_TestRunner() { std::vector>> vectors; std::vector> small = CreateSimpleVectorOfSize(1); std::vector> big = CreateSimpleVectorOfSize(10); vectors.push_back(small); vectors.push_back(big); // small vector will also load most of big vector to memory size_t chunkSizeBytes = (big.size() - small.size()) * sizeof(T); SaveRestoreAndCompareVectors(vectors, chunkSizeBytes); } Y_UNIT_TEST(RequestedVectorPartlyInMemory) { TScopedAlloc Alloc(__LOCATION__); RequestedVectorPartlyInMemory_TestRunner(); RequestedVectorPartlyInMemory_TestRunner(); } } } //namespace namespace NKikimr::NMiniKQL