Index: src/libchcore/TDataBuffer.cpp =================================================================== diff -u -N -r409a0af1e9fdea72ca016118d76a5a95e53496e8 -r6f082e25ab71169e9e631f139a2eddc4ef45d2e9 --- src/libchcore/TDataBuffer.cpp (.../TDataBuffer.cpp) (revision 409a0af1e9fdea72ca016118d76a5a95e53496e8) +++ src/libchcore/TDataBuffer.cpp (.../TDataBuffer.cpp) (revision 6f082e25ab71169e9e631f139a2eddc4ef45d2e9) @@ -228,7 +228,7 @@ // first the user-facing buffer size if(stBufferSize == 0) { - stBufferSize = DefaultMaxMemory; + stBufferSize = DefaultBufferSize; bResult = false; } else @@ -262,13 +262,13 @@ stMaxMemory = std::max(DefaultMaxMemory, RoundUp(DefaultMaxMemory, stPageSize)); bResult = false; } - else if(stMaxMemory < stPageSize) + else { - size_t stNewSize = RoundUp(stMaxMemory, stBufferSize); - if(stNewSize != stMaxMemory) + size_t stNewSize = RoundUp(stMaxMemory, stPageSize); + if(stMaxMemory != stNewSize) { + stMaxMemory = stNewSize; bResult = false; - stMaxMemory = stPageSize; } } @@ -313,7 +313,7 @@ bool TDataBufferManager::CheckResizeSize(size_t& stNewMaxSize) { - if(m_stPageSize == 0 || m_stMaxMemory == 0 || m_stBufferSize == 0) + if(!IsInitialized()) { stNewMaxSize = 0; return false; @@ -362,11 +362,21 @@ } } +size_t TDataBufferManager::GetRealAllocatedMemorySize() const +{ + return m_stPageSize * (m_vAllocBlocksToFree.size() + m_vVirtualAllocBlocks.size()); +} + bool TDataBufferManager::HasFreeBuffer() const { return !m_listUnusedBuffers.empty(); } +size_t TDataBufferManager::GetCountOfFreeBuffers() const +{ + return m_listUnusedBuffers.size(); +} + bool TDataBufferManager::CanAllocPage() const { if(!IsInitialized()) @@ -445,6 +455,7 @@ { m_vAllocBlocksToFree.push_back(spAllocBlock); } + m_stMaxMemory -= m_stPageSize; } bool TDataBufferManager::GetFreeBuffer(TSimpleDataBuffer& rSimpleBuffer) Index: src/libchcore/TDataBuffer.h =================================================================== diff -u -N -r409a0af1e9fdea72ca016118d76a5a95e53496e8 -r6f082e25ab71169e9e631f139a2eddc4ef45d2e9 --- src/libchcore/TDataBuffer.h (.../TDataBuffer.h) (revision 409a0af1e9fdea72ca016118d76a5a95e53496e8) +++ src/libchcore/TDataBuffer.h (.../TDataBuffer.h) (revision 6f082e25ab71169e9e631f139a2eddc4ef45d2e9) @@ -127,8 +127,11 @@ size_t GetPageSize() const { return m_stPageSize; } size_t GetSimpleBufferSize() const { return m_stBufferSize; } + size_t GetRealAllocatedMemorySize() const; + // buffer retrieval bool HasFreeBuffer() const; // checks if a buffer is available without allocating any new memory + size_t GetCountOfFreeBuffers() const; // how many free buffers are there that can be used without allocating additional memory bool GetFreeBuffer(TSimpleDataBuffer& rSimpleBuffer); void ReleaseBuffer(TSimpleDataBuffer& rSimpleBuffer); Index: tests/libchcore_test/src/TDataBufferManagerTest.cpp =================================================================== diff -u -N -r409a0af1e9fdea72ca016118d76a5a95e53496e8 -r6f082e25ab71169e9e631f139a2eddc4ef45d2e9 --- tests/libchcore_test/src/TDataBufferManagerTest.cpp (.../TDataBufferManagerTest.cpp) (revision 409a0af1e9fdea72ca016118d76a5a95e53496e8) +++ tests/libchcore_test/src/TDataBufferManagerTest.cpp (.../TDataBufferManagerTest.cpp) (revision 6f082e25ab71169e9e631f139a2eddc4ef45d2e9) @@ -37,4 +37,105 @@ } /////////////////////////////////////////////////////////////////////////////// -// TSimpleDataBuffer +// TDataBufferManager + +TEST(TDataBufferManager, CheckBufferConfigBase) +{ + // only max mem - default values + size_t stMaxMem(0); + EXPECT_EQ(chcore::TDataBufferManager::CheckBufferConfig(stMaxMem), false); + EXPECT_EQ(stMaxMem, chcore::TDataBufferManager::DefaultMaxMemory); + + const size_t stTestSize = 103145; + stMaxMem = stTestSize; + EXPECT_EQ(chcore::TDataBufferManager::CheckBufferConfig(stMaxMem), false); + EXPECT_LE(stTestSize, stMaxMem); +} + +TEST(TDataBufferManager, CheckBufferConfigExt) +{ + // detailed config - default values + size_t stMaxMem = 0; + size_t stPageSize(0); + size_t stChunkSize(0); + EXPECT_EQ(chcore::TDataBufferManager::CheckBufferConfig(stMaxMem, stPageSize, stChunkSize), false); + EXPECT_EQ(stMaxMem, chcore::TDataBufferManager::DefaultMaxMemory); + EXPECT_EQ(stPageSize, chcore::TDataBufferManager::DefaultPageSize); + EXPECT_EQ(stChunkSize, chcore::TDataBufferManager::DefaultBufferSize); + + const size_t stTestMaxSize = 1237645; + const size_t stTestPageSize = 34563; + const size_t stTestBufferSize = 120; + stMaxMem = stTestMaxSize; + stPageSize = stTestPageSize; + stChunkSize = stTestBufferSize; + EXPECT_EQ(chcore::TDataBufferManager::CheckBufferConfig(stMaxMem, stPageSize, stChunkSize), false); + EXPECT_LE(stTestMaxSize, stMaxMem); + EXPECT_LE(stTestPageSize, stPageSize); + EXPECT_LE(stTestBufferSize, stChunkSize); +} + +TEST(TDataBufferManager, FailedInitializations) +{ + chcore::TDataBufferManager tBufferManager; + + // failed initializations + EXPECT_THROW(tBufferManager.Initialize(chcore::TDataBufferManager::DefaultMaxMemory - 1), chcore::TCoreException); + EXPECT_EQ(tBufferManager.IsInitialized(), false); + + EXPECT_THROW(tBufferManager.Initialize(chcore::TDataBufferManager::DefaultMaxMemory, chcore::TDataBufferManager::DefaultPageSize - 1, + chcore::TDataBufferManager::DefaultBufferSize), chcore::TCoreException); + EXPECT_EQ(tBufferManager.IsInitialized(), false); + + // succeeded initialization + EXPECT_NO_FATAL_FAILURE(tBufferManager.Initialize(chcore::TDataBufferManager::DefaultPageSize)); + EXPECT_EQ(tBufferManager.IsInitialized(), true); + EXPECT_EQ(tBufferManager.GetMaxMemorySize(), chcore::TDataBufferManager::DefaultPageSize); +} + +class TInitializedBufferManager : public ::testing::Test +{ +protected: + virtual void SetUp() + { + size_t stMaxMemory = 1048034; + + chcore::TDataBufferManager::CheckBufferConfig(stMaxMemory); + tBufferManager.Initialize(stMaxMemory); + } + + chcore::TDataBufferManager tBufferManager; +}; + +TEST_F(TInitializedBufferManager, FailedResize) +{ + EXPECT_TRUE(tBufferManager.IsInitialized()); + + size_t stCurrentMaxSize = tBufferManager.GetMaxMemorySize(); + size_t stCurrentPageSize = tBufferManager.GetPageSize(); + size_t stCurrentBufferSize = tBufferManager.GetSimpleBufferSize(); + + // try to change to something useless, check if nothing breaks inside + EXPECT_THROW(tBufferManager.ChangeMaxMemorySize(0), chcore::TCoreException); + EXPECT_EQ(stCurrentMaxSize ,tBufferManager.GetMaxMemorySize()); + EXPECT_EQ(stCurrentPageSize, tBufferManager.GetPageSize()); + EXPECT_EQ(stCurrentBufferSize, tBufferManager.GetSimpleBufferSize()); +} + +TEST_F(TInitializedBufferManager, ResizeWithSimpleBufferChecks) +{ + EXPECT_TRUE(tBufferManager.IsInitialized()); + EXPECT_EQ((tBufferManager.GetMaxMemorySize() / tBufferManager.GetSimpleBufferSize()), tBufferManager.GetCountOfFreeBuffers()); + + size_t stCurrentMaxSize = tBufferManager.GetMaxMemorySize(); + + // try to change to something useless, check if nothing breaks inside + size_t stNewBufferSize = stCurrentMaxSize / 2; + tBufferManager.CheckResizeSize(stNewBufferSize); // can't assume that it will return true here, since we don't really know what's the buffer size now... + + EXPECT_NO_FATAL_FAILURE(tBufferManager.ChangeMaxMemorySize(stNewBufferSize)); + EXPECT_EQ(tBufferManager.GetMaxMemorySize(), stNewBufferSize); + + EXPECT_TRUE(tBufferManager.HasFreeBuffer()); + EXPECT_EQ((tBufferManager.GetMaxMemorySize() / tBufferManager.GetSimpleBufferSize()), tBufferManager.GetCountOfFreeBuffers()); +}