Select Git revision
ITAUPFilterPool.cpp

Philipp Schäfer authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ITAUPFilterPool.cpp 6.60 KiB
#include <ITAFunctors.h>
#include <ITAUPFilter.h>
#include <ITAUPFilterPool.h>
#include <algorithm>
#include <cassert>
#include <cstdio>
// Debug-Meldung ausgeben
#define VERBOSE 0
ITAUPFilterPool::ITAUPFilterPool( const int iBlocklength, const int iMaxFilterLength, const int iInitialSize )
: m_iBlocklength( iBlocklength )
, m_iMaxFilterLength( iMaxFilterLength )
{
for( int i = 0; i < iInitialSize; i++ )
{
ITAUPFilter* pFilter = new ITAUPFilter( m_iBlocklength, m_iMaxFilterLength );
pFilter->m_pParent = this;
m_lpFreeFilters.push_back( pFilter );
}
}
ITAUPFilterPool::~ITAUPFilterPool( )
{
m_csFilters.enter( );
std::for_each( m_lpFreeFilters.begin( ), m_lpFreeFilters.end( ), deleteFunctor<ITAUPFilter> );
std::for_each( m_lpUsedFilters.begin( ), m_lpUsedFilters.end( ), deleteFunctor<ITAUPFilter> );
std::for_each( m_lpAutoFilters.begin( ), m_lpAutoFilters.end( ), deleteFunctor<ITAUPFilter> );
m_csFilters.leave( );
}
int ITAUPFilterPool::GetBlocklength( ) const
{
return m_iBlocklength;
}
int ITAUPFilterPool::GetMaxFilterlength( ) const
{
return m_iMaxFilterLength;
}
int ITAUPFilterPool::GetNumFreeFilters( ) const
{
m_csFilters.enter( );
int iResult = (int)m_lpFreeFilters.size( );
m_csFilters.leave( );
return iResult;
}
int ITAUPFilterPool::GetNumUsedFilters( ) const
{
m_csFilters.enter( );
int iResult = (int)m_lpUsedFilters.size( ) + (int)m_lpAutoFilters.size( );
m_csFilters.leave( );
return iResult;
}
int ITAUPFilterPool::GetNumTotalFilters( ) const
{
m_csFilters.enter( );
int iResult = (int)m_lpFreeFilters.size( ) + (int)m_lpUsedFilters.size( ) + (int)m_lpAutoFilters.size( );
m_csFilters.leave( );
return iResult;
}
ITAUPFilter* ITAUPFilterPool::RequestFilter( )
{
m_csFilters.enter( );
ITAUPFilter* pFilter = nullptr;
if( m_lpFreeFilters.empty( ) )
{
// Fall: Keine Filter in der Frei-Liste -> Zunchst schauen ob freie Filter in der Auto-Liste
if( !m_lpAutoFilters.empty( ) )
{
for( std::list<ITAUPFilter*>::iterator it = m_lpAutoFilters.begin( ); it != m_lpAutoFilters.end( ); ++it )
{
/*
* Wichtig: Wenn der Filter bereits in der Auto-Liste ist,
* hat der Benutzer fr dieses Filter release() aufgerufen.
* Er braucht den Filter also nicht mehr und darf den
* ihm zuvor genannten Zeiger nicht mehr weiterbenutzen.
* Deshalb kann auch den Filter auch nicht zwischenzeitlich
* in einen anderen Falter einsetzen.
*
* Fazit: Es ist sicher hier nur-lesend zu testen!
*/
assert( ( *it ) != 0 );
if( !( *it )->IsInUse( ) )
{
pFilter = ( *it );
// Filter wieder vergeben
m_lpAutoFilters.erase( it );
#if VERBOSE == 1
{
DEBUG_PRINTF( "[DSMBCFilterPool] Reusing auto filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ),
m_lpAutoFilters.size( ), m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
}
#endif
break;
}
// } else {
// // Nur Meldung machen
// DSMBCFilter::State::StateStruct ss;
// ss.iPrepRefCount = 0;
// ss.iUseRefCount = 0;
// if (pFilter) atomic_read32( &pFilter->m_oState.m_oState, &ss );
//#if VERBOSE==1
// DEBUG_PRINTF("[DSMBCFilterPool] Cannot reusing auto filter 0x%08Xh (preps=%d, uses=%d) [Used %d, Auto %d, Free %d, Total %d]\n",
// pFilter, ss.iPrepRefCount, ss.iUseRefCount, m_lpUsedFilters.size(), m_lpAutoFilters.size(), m_lpFreeFilters.size(),
//getNumTotalFilters()); #endif
// }
}
}
if( pFilter == nullptr )
{
// Fall: Auch kein freies Filter in der Auto-Liste -> Neues Filter erzeugen
pFilter = new ITAUPFilter( m_iBlocklength, m_iMaxFilterLength );
pFilter->m_pParent = this;
#if VERBOSE == 1
DEBUG_PRINTF( "[DSMBCFilterPool] Created new filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ),
m_lpAutoFilters.size( ), m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
#endif
}
m_lpUsedFilters.push_back( pFilter );
}
else
{
// Fall: Freie Filter verfgbar
pFilter = m_lpFreeFilters.back( );
m_lpFreeFilters.pop_back( );
m_lpUsedFilters.push_back( pFilter );
//#if VERBOSE==1
// {
// // Nur Meldung machen
// DSMBCFilter::State::StateStruct ss;
// ss.iPrepRefCount = 0;
// ss.iUseRefCount = 0;
// if (pFilter) atomic_read32( &pFilter->m_oState.m_oState, &ss );
// DEBUG_PRINTF("[DSMBCFilterPool] Freed filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n",
// pFilter, m_lpUsedFilters.size(), m_lpAutoFilters.size(), m_lpFreeFilters.size(), getNumTotalFilters());
// }
//#endif
}
m_csFilters.leave( );
#if VERBOSE == 1
DEBUG_PRINTF( "[DSMBCFilterPool] Request returns filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ), m_lpAutoFilters.size( ),
m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
#endif
return pFilter;
}
void ITAUPFilterPool::ReleaseFilter( ITAUPFilter* pFilter )
{
m_csFilters.enter( );
// Nonsens einfach ignoieren
if( !pFilter )
{
m_csFilters.leave( );
return;
}
#if VERBOSE == 1
DEBUG_PRINTF( "[DSMBCFilterPool] Release filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ), m_lpAutoFilters.size( ),
m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
#endif
// Zunchst die eigene Zust?ndigkeit sicherstellen
std::list<ITAUPFilter*>::iterator it = std::find( m_lpUsedFilters.begin( ), m_lpUsedFilters.end( ), pFilter );
if( it == m_lpUsedFilters.end( ) )
{
// Filter garnicht aus diesem Pool. Ignorieren ...
m_csFilters.leave( );
return;
}
/*
// Schneller und einfacher Test auf Zustndigkeit
if (pFilter->m_pParent != this) {
m_csFilters.leave();
return;
}
*/
if( pFilter->IsInUse( ) )
{
// Ist der Filter noch in Faltern in Benutzung -> Zur Freigabe vormerken (Auto-Liste)
m_lpUsedFilters.erase( it );
m_lpAutoFilters.push_back( pFilter );
m_csFilters.leave( );
#if VERBOSE == 1
DEBUG_PRINTF( "[DSMBCFilterPool] Auto-release filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ), m_lpAutoFilters.size( ),
m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
#endif
return;
}
// Filter wieder in die Frei-Liste
m_lpUsedFilters.erase( it );
m_lpFreeFilters.push_back( pFilter );
#if VERBOSE == 1
DEBUG_PRINTF( "[DSMBCFilterPool] Instant-release filter 0x%08Xh [Used %d, Auto %d, Free %d, Total %d]\n", pFilter, m_lpUsedFilters.size( ), m_lpAutoFilters.size( ),
m_lpFreeFilters.size( ), GetNumTotalFilters( ) );
#endif
m_csFilters.leave( );
}