Sleipnir
src/triei.h
00001 /*****************************************************************************
00002 * This file is provided under the Creative Commons Attribution 3.0 license.
00003 *
00004 * You are free to share, copy, distribute, transmit, or adapt this work
00005 * PROVIDED THAT you attribute the work to the authors listed below.
00006 * For more information, please see the following web page:
00007 * http://creativecommons.org/licenses/by/3.0/
00008 *
00009 * This file is a component of the Sleipnir library for functional genomics,
00010 * authored by:
00011 * Curtis Huttenhower (chuttenh@princeton.edu)
00012 * Mark Schroeder
00013 * Maria D. Chikina
00014 * Olga G. Troyanskaya (ogt@princeton.edu, primary contact)
00015 *
00016 * If you use this library, the included executable tools, or any related
00017 * code in your work, please cite the following publication:
00018 * Curtis Huttenhower, Mark Schroeder, Maria D. Chikina, and
00019 * Olga G. Troyanskaya.
00020 * "The Sleipnir library for computational functional genomics"
00021 *****************************************************************************/
00022 #ifndef TRIEI_H
00023 #define TRIEI_H
00024 
00025 #include <vector>
00026 
00027 namespace Sleipnir {
00028 
00029 template<class tType> class CTrie;
00030 template<class tType> class CTrieIteratorImpl;
00031 
00032 template<class tType>
00033 class CTrieImpl {
00034     friend class CTrieIteratorImpl<tType>;
00035 protected:
00036     CTrieImpl( const tType& Undef ) : m_Undef(Undef), m_aabData(NULL) { }
00037 
00038     void Delete( unsigned char** aabData, size_t iDepth = 0 ) const {
00039         unsigned char   i;
00040 
00041         if( !aabData || ( iDepth >= m_vecbSizes.size( ) ) )
00042             return;
00043 
00044         for( i = 0; i < m_vecbSizes[ iDepth ]; ++i )
00045             Delete( (unsigned char**)aabData[ i ], iDepth + 1 );
00046         delete[] aabData; }
00047 
00048     std::vector<unsigned char>  m_vecbSizes;
00049     unsigned char**             m_aabData;
00050     const tType&                m_Undef;
00051 };
00052 
00053 template<class tType>
00054 class CTrieIteratorImpl {
00055 protected:
00056     CTrieIteratorImpl( const CTrie<tType>& Trie ) : m_Trie(Trie) {
00057         size_t              iDepth;
00058         unsigned char       b;
00059         unsigned char***    paabData;
00060 
00061         m_vecbPosition.resize( m_Trie.GetSize( ) );
00062         m_vecpaaPosition.resize( m_Trie.GetSize( ) );
00063         if( !m_Trie.m_aabData ) {
00064             for( iDepth = 0; iDepth < m_vecpaaPosition.size( ); ++iDepth )
00065                 m_vecpaaPosition[ iDepth ] = NULL;
00066             return; }
00067 
00068         paabData = (unsigned char***)&m_Trie.m_aabData;
00069         for( iDepth = 0; ( iDepth + 1 ) < m_vecbPosition.size( ); ++iDepth )
00070             for( b = 0; b < m_Trie.GetSize( iDepth ); ++b )
00071                 if( (*paabData)[ b ] ) {
00072                     m_vecbPosition[ iDepth ] = b;
00073                     m_vecpaaPosition[ iDepth ] = paabData;
00074                     paabData = (unsigned char***)&(*paabData)[ b ];
00075                     break; }
00076         for( b = 0; b < m_Trie.GetSize( iDepth ); ++b )
00077             if( *(tType*)&(*paabData)[ b ] != m_Trie.m_Undef ) {
00078                 m_vecbPosition[ iDepth ] = b;
00079                 m_vecpaaPosition[ iDepth ] = paabData;
00080                 break; } }
00081 
00082     CTrieIteratorImpl( const CTrieIteratorImpl& Iter ) : m_Trie(Iter.m_Trie) {
00083 
00084         m_vecbPosition.resize( Iter.m_vecbPosition.size( ) );
00085         std::copy( Iter.m_vecbPosition.begin( ), Iter.m_vecbPosition.end( ), m_vecbPosition.begin( ) );
00086         m_vecpaaPosition.resize( Iter.m_vecpaaPosition.size( ) );
00087         std::copy( Iter.m_vecpaaPosition.begin( ), Iter.m_vecpaaPosition.end( ), m_vecpaaPosition.begin( ) ); }
00088 
00089     tType* GetValue( ) const {
00090 
00091         return (tType*)&(*m_vecpaaPosition[ m_vecpaaPosition.size( ) - 1 ])[
00092             m_vecbPosition[ m_vecbPosition.size( ) - 1 ] ]; }
00093 
00094     bool NextDown( size_t iDepth, bool fReset ) {
00095         unsigned char   b;
00096 
00097         for( ; ( iDepth + 1 ) < m_vecbPosition.size( ); ++iDepth ) {
00098             for( b = m_vecbPosition[ iDepth ]; b < m_Trie.GetSize( iDepth ); ++b )
00099                 if( (*m_vecpaaPosition[ iDepth ])[ b ] )
00100                     break;
00101             if( b >= m_Trie.GetSize( iDepth ) )
00102                 return false;
00103             m_vecbPosition[ iDepth ] = b;
00104             m_vecbPosition[ iDepth + 1 ] = 0;
00105             m_vecpaaPosition[ iDepth + 1 ] = (unsigned char***)&(*m_vecpaaPosition[ iDepth ])[ b ]; }
00106         for( b = ( fReset ? 0 : ( m_vecbPosition[ iDepth ] + 1 ) ); b < m_Trie.GetSize( iDepth ); ++b )
00107             if( *(tType*)&(*m_vecpaaPosition[ iDepth ])[ b ] != m_Trie.m_Undef ) {
00108                 m_vecbPosition[ iDepth ] = b;
00109                 return true; }
00110 
00111         return false; }
00112 
00113     size_t NextUp( ) {
00114         size_t          iDepth;
00115         unsigned char   b;
00116 
00117         for( iDepth = m_vecbPosition.size( ) - 2; iDepth != -1; --iDepth )
00118             for( b = ( m_vecbPosition[ iDepth ] + 1 ); b < m_Trie.GetSize( iDepth ); ++b )
00119                 if( (*m_vecpaaPosition[ iDepth ])[ b ] ) {
00120                     m_vecbPosition[ iDepth ] = b;
00121                     return iDepth; }
00122 
00123         m_vecpaaPosition[ m_vecpaaPosition.size( ) - 1 ] = NULL;
00124         return -1; }
00125 
00126     const CTrie<tType>&             m_Trie;
00127     std::vector<unsigned char>      m_vecbPosition;
00128     std::vector<unsigned char***>   m_vecpaaPosition;
00129 };
00130 
00131 }
00132 
00133 #endif // TRIEI_H