📄 slicedheapmanager.cpp
字号:
//// This file is part of the "More for C++" library//// Copyright (c) 1999-2003 by Thorsten Goertz (thorsten@morefor.org)//// The "More for C++" library is free software; you can redistribute it and/or// modify it under the terms of the license that comes with this package.//// Read "license.txt" for more details.//// THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES// OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.////////////////////////////////////////////////////////////////////////////////#include <cstdlib>#include "slicedheapmanager.hpp"using namespace more::core;////////////////////////////////////////////////////////////////////////////////SlicedHeapManager::SlicedHeapManager( ): m_pFirstSlice( 0 ){}////////////////////////////////////////////////////////////////////////////////void* SlicedHeapManager::createObject( size_t nSizeOfObject){ void* pResult = 0; Slice* pSlice = m_pFirstSlice; while( pResult == 0 && pSlice != 0 ) { pResult = pSlice -> createObject( nSizeOfObject ); pSlice = pSlice -> getNext( ); } if( pResult == 0 ) { m_pFirstSlice = new Slice( nSizeOfObject, m_pFirstSlice ); pResult = m_pFirstSlice -> createObject( nSizeOfObject ); } return pResult;}////////////////////////////////////////////////////////////////////////////////void SlicedHeapManager::destroyObject( void* pObject){ Slice* pSlice = m_pFirstSlice; while( pSlice != 0 ) { if( pSlice -> containsObject( pObject ) ) { pSlice -> destroyObject( pObject ); pSlice = 0; } else { pSlice = pSlice -> getNext( ); } }}////////////////////////////////////////////////////////////////////////////////void SlicedHeapManager::compactHeap( ){ Slice* pPreviousSlice = 0; Slice* pSlice = m_pFirstSlice; while( pSlice != 0 ) { Slice* pNextSlice = pSlice -> getNext( ); pSlice -> compact( ); if( pSlice -> isEmpty( ) ) { if( m_pFirstSlice == pSlice ) { m_pFirstSlice = pNextSlice; } pSlice -> destroy( pPreviousSlice ); delete pSlice; } else { pPreviousSlice = pSlice; } pSlice = pNextSlice; }}////////////////////////////////////////////////////////////////////////////////SlicedHeapManager::Slice::Slice( size_t nSizeOfFirstObject, Slice* pNextSlice): m_nSizeOfSlice( calcSizeOfChunk( nSizeOfFirstObject ) ), m_pNextSlice( pNextSlice ){ Chunk* pChunk; if( m_nSizeOfSlice < 128 * 1024 ) { m_nSizeOfSlice = 128 * 1024; } m_pBytes = new byte[m_nSizeOfSlice]; pChunk = ( Chunk* ) m_pBytes; pChunk -> m_bInUse = false; pChunk -> m_pNextChunk = 0; pChunk -> m_nSizeOfChunk = m_nSizeOfSlice;}////////////////////////////////////////////////////////////////////////////////void* SlicedHeapManager::Slice::createObject( size_t nSizeOfObject){ void* pResult = 0; Chunk* pChunk = ( Chunk* ) m_pBytes; size_t nSizeOfChunk = calcSizeOfChunk( nSizeOfObject ); if( nSizeOfChunk <= m_nSizeOfSlice ) { while( pResult == 0 && pChunk != 0 ) { if( !pChunk -> m_bInUse && pChunk -> m_nSizeOfChunk >= nSizeOfChunk ) { size_t nRemainingSizeOfChunk = pChunk -> m_nSizeOfChunk - nSizeOfChunk; if( nRemainingSizeOfChunk > sizeof( Chunk ) ) { splitChunk( pChunk, nRemainingSizeOfChunk ); pResult = pChunk -> m_pNextChunk + 1; } else { pChunk -> m_bInUse = true; pResult = pChunk + 1; } } else { pChunk = pChunk -> m_pNextChunk; } } } return pResult;}////////////////////////////////////////////////////////////////////////////////bool SlicedHeapManager::Slice::containsObject( void* pObject) const{ byte* pObjectBytes = ( byte* ) pObject; return m_pBytes <= pObjectBytes && pObjectBytes < m_pBytes + m_nSizeOfSlice;}////////////////////////////////////////////////////////////////////////////////void SlicedHeapManager::Slice::destroyObject( void* pObject){ byte* pBytes = ( byte* ) pObject; Chunk* pChunk = ( Chunk* ) pBytes - 1; pChunk -> m_bInUse = false; joinChunks( pChunk );}////////////////////////////////////////////////////////////////////////////////bool SlicedHeapManager::Slice::isEmpty( ) const{ Chunk* pChunk = ( Chunk* ) m_pBytes; return pChunk -> m_bInUse == false && pChunk -> m_pNextChunk == 0;}////////////////////////////////////////////////////////////////////////////////void SlicedHeapManager::Slice::destroy( Slice* pPreviousSlice){ if( pPreviousSlice != 0 ) { pPreviousSlice -> m_pNextSlice = m_pNextSlice; } delete[] m_pBytes; m_pBytes = 0;}////////////////////////////////////////////////////////////////////////////////void SlicedHeapManager::Slice::compact( ){ Chunk* pChunk = ( Chunk* ) m_pBytes; while( pChunk != 0 ) { joinChunks( pChunk ); pChunk = pChunk -> m_pNextChunk; }}////////////////////////////////////////////////////////////////////////////////SlicedHeapManager::Slice* SlicedHeapManager::Slice::getNext( ) const{ return m_pNextSlice;}////////////////////////////////////////////////////////////////////////////////size_t SlicedHeapManager::Slice::calcSizeOfChunk( size_t nSizeOfObject) const{ size_t nResult = sizeof( Chunk ) + nSizeOfObject; size_t nNoOfBytesBehindAlignment = nResult % 8; if( nNoOfBytesBehindAlignment > 0 ) { nResult += 8 - nNoOfBytesBehindAlignment; } return nResult;}////////////////////////////////////////////////////////////////////////////////void SlicedHeapManager::Slice::splitChunk( Chunk* pChunk, size_t nRemainingSize){ byte* pBytes = ( byte* ) pChunk + nRemainingSize; Chunk* pNextChunk = ( Chunk* ) pBytes; pNextChunk -> m_bInUse = true; pNextChunk -> m_pNextChunk = pChunk -> m_pNextChunk; pNextChunk -> m_nSizeOfChunk = pChunk -> m_nSizeOfChunk - nRemainingSize; pChunk -> m_nSizeOfChunk = nRemainingSize; pChunk -> m_pNextChunk = pNextChunk;}////////////////////////////////////////////////////////////////////////////////void SlicedHeapManager::Slice::joinChunks( Chunk* pFirstChunk){ Chunk* pNextChunk = pFirstChunk -> m_pNextChunk; while( pNextChunk != 0 && !pNextChunk -> m_bInUse ) { pFirstChunk -> m_pNextChunk = pNextChunk -> m_pNextChunk; pFirstChunk -> m_nSizeOfChunk += pNextChunk -> m_nSizeOfChunk; pNextChunk = pNextChunk -> m_pNextChunk; }}////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -