SIS
Symmetric Index Structures
/Users/dbr/ma/src/bas/lml/tarjanTable.c
Go to the documentation of this file.
00001 #include "base.h"
00002 
00003 #define NUM_OF_POS_TO_LOOK_BACK_IN_TARJAN_TABLE (10000)
00004 
00005 typedef struct tTarjanTableBuildHelp{
00006     UINT alphabetSize;
00007     UINT lastPos;
00008     UINT symbolSize;
00009     const Automaton * aut;
00010 } TarjanTableBuildHelp;
00011 
00012 static UINT Add( TarjanTable * tt, TarjanTableBuildHelp * help, UINT state ){
00013     UINT numberOfTransitions, i, j, code, tr, maxCode;
00014     boolean posFound;
00015     const void * label;
00016 
00017     numberOfTransitions = help->aut->statesNumberOfTransitions->seq[state];
00018     if( numberOfTransitions == 0 ){
00019         return 0;
00020     }
00021     if( NUM_OF_POS_TO_LOOK_BACK_IN_TARJAN_TABLE < 0 || help->lastPos - 1 < NUM_OF_POS_TO_LOOK_BACK_IN_TARJAN_TABLE ){
00022         i = 1;
00023     }
00024     else{
00025         i = help->lastPos - NUM_OF_POS_TO_LOOK_BACK_IN_TARJAN_TABLE;
00026     }
00027     tr = help->aut->statesTransitions->seq[state];
00028     posFound = bFALSE;
00029     for( ; i + help->alphabetSize < tt->table->seqAlloced; i++ ){
00030         for( j = 0; j < numberOfTransitions; j++ ){
00031             label = mVoidSequenceElement( help->aut->transitionsLabel, tr + j );
00032             code = SymbolToUINT( label, help->symbolSize );
00033             code = mAlphabetGetCode( tt->alph, code );
00034             if( tt->table->seq[i + code] != NO ){
00035                 break;
00036             }
00037         }
00038         if( j < numberOfTransitions ){
00039             continue;
00040         }
00041         posFound = bTRUE;
00042         break;
00043     }
00044     if( !posFound ){
00045         i = help->lastPos + help->alphabetSize;
00046         i += (i/4);
00047 
00048         tt->table->seq = Realloc( tt->table->seq, i, sizeof(UINT) );
00049 
00050         for( j = tt->table->seqAlloced; j < i; j++ ){
00051             tt->table->seq[j] = NO;
00052         }
00053         tt->table->seqAlloced = i;
00054         i = help->lastPos;
00055     }
00056     maxCode = 0;
00057     for( j = 0; j < numberOfTransitions; j++ ){
00058         label = mVoidSequenceElement( help->aut->transitionsLabel, tr + j );
00059         code = SymbolToUINT( label, help->symbolSize );
00060         code = mAlphabetGetCode( tt->alph, code );
00061         if( maxCode < code ){
00062             maxCode = code;
00063         }
00064         tt->table->seq[i+code] = tr + j;
00065     }
00066     if( tt->table->seqStored < i + help->alphabetSize ){
00067         tt->table->seqStored = i + help->alphabetSize;
00068     }
00069     if( help->lastPos <= i + maxCode ){
00070         help->lastPos = i + maxCode + 1;
00071     }
00072     return i;
00073 }
00074 
00075 TarjanTable * TarjanTableInit( Alphabet * alph, const Automaton * aut ){
00076     TarjanTableBuildHelp help;
00077     TarjanTable * tt;
00078     UINT i;
00079 
00080 
00081     tt = Malloc( 1, sizeof(TarjanTable) );
00082     tt->alph = alph;
00083     tt->statesTransitions = UINTSequenceInit2( mAutomatonGetStatesStored(aut), 1 );
00084     help.alphabetSize = mAlphabetGetSize(alph);
00085     if(help.alphabetSize == 0 ){
00086         help.alphabetSize = 1;
00087     }
00088     help.lastPos = 1;
00089     help.symbolSize = NO;
00090     switch( aut->type ){
00091         case AUTOMATON_TYPE_SYMBOL:
00092             help.symbolSize = mAutomatonGetLabelSize( aut );
00093             break;
00094         case AUTOMATON_TYPE_SYMBOL_UINT:
00095             help.symbolSize = mAutomatonGetLabelSize( aut ) - sizeof(UINT);
00096             break;
00097     }
00098     help.aut = aut;
00099     tt->table = UINTSequenceInit2( 4*help.alphabetSize, 1 );
00100     for( i = 0; i < tt->table->seqAlloced; i++ ){
00101         tt->table->seq[i] = NO;
00102     }
00103     tt->table->seqStored = help.alphabetSize;
00104     for( i = 0; i < mAutomatonGetStatesStored(aut); i++ ){
00105         tt->statesTransitions->seq[i] = Add( tt, &help, i );
00106     }
00107     tt->statesTransitions->seqStored = i;
00108     UINTSequenceShrink( tt->table );
00109     return tt;
00110 }
00111 
00112 void TarjanTableFree( TarjanTable * tt ){
00113     UINTSequenceFree( tt->statesTransitions );
00114     UINTSequenceFree( tt->table );
00115     Free( tt );
00116 }
00117 
00118 void TarjanTableWrite( const TarjanTable * tt, FILE * fp ){
00119     UINTSequenceWrite( tt->statesTransitions, fp );
00120     UINTSequenceWrite( tt->table, fp );
00121     AlphabetWrite( tt->alph, fp );
00122 }
00123 
00124 TarjanTable * TarjanTableRead( FILE * fp ){
00125     TarjanTable * tt;
00126 
00127     tt = Malloc( 1, sizeof(TarjanTable) );
00128     tt->statesTransitions = UINTSequenceRead( fp );
00129     tt->table = UINTSequenceRead( fp );
00130     tt->alph = AlphabetRead( fp );
00131     return tt;
00132 }
00133