/* -------------------------------------------------------------------- */
/*                                                                      */
/* FILE : sdata.h                                                       */
/*                                                                      */
/* DESC : Sampler data definition.                                      */
/*                                                                      */
/* PROJ : CSA\sampler                                                   */
/*                                                                      */
/* CREATED  16.02.98 19:28    by L&M.                                   */
/* MODIFIED 03.02.99 15:49    by A.V.                                   */
/*                                                                      */
/*                                                                      */
/*                                     1995-98 (c) by Leonid Moiseichuk */
/* -------------------------------------------------------------------- */

/* ==========================[ includes ]============================== */

#include "SData.h"

#ifndef __LIMITS_H
#include <Limits.h>
#endif

#pragma hdrstop

#include <iostream.h>

#ifndef __STDLIB_H
#include <StdLib.h>
#endif

/* ===========================[ methods ]============================== */

static void WriteLine(FILE* Stream, int nStrips = 78)
{
   fprintf( Stream, "\n" );
   for ( int index=0; index<nStrips; index++ ) fprintf( Stream,"-" );
   fprintf( Stream, "\n" );
} // WriteLine

/* --- Class FileMgr --- */

FileHandle FileMgr :: HandleOf( PChar aName )
{
   for ( FileHandle index=0; index<Counter; index++ )
      if ( strcmp(Files[index],aName)==0 ) return index+1 ;

   if ( Counter<MAX_FILES )
   {
      strcpy( Files[ Counter++ ],aName );
      return Counter;
   }
   else return 0;
}  // HandleOf

void FileMgr :: Print( FILE* Stream ) const
{
   fprintf( Stream,"\n\n\t\t‘ЇЁб®Є ®Ўа Ў®в ­­ле д ©«®ў.\n" );

   WriteLine( Stream );
   fprintf( Stream," %4s            %s","NN","€¬п ®Ўа Ў®в ­­®Ј® д ©« " );
   WriteLine( Stream );

   for ( uint index=0; index<Counter; index++ )
   {
      if (index) fprintf( Stream,"\n" );
      fprintf( Stream,"  %2u.\t%s",index+1,Files[index] );
   }
   WriteLine( Stream );
} // Print

void FileMgr :: Put( FILE* Stream ) const
{
   fwrite (&Counter,sizeof(Counter),1,Stream);
   for (uint i = 0; i < Counter; i++)
   {
      fwrite (Files+i,MAXPATH,1,Stream);
   }
}

void FileMgr :: Get( FILE* Stream )
{
   fread (&Counter,sizeof(Counter),1,Stream);
   for (uint i = 0; i < Counter; i++)
   {
      fread (Files+i,MAXPATH,1,Stream);
   }
}


/* --- Class Sample List --- */

/*void SamplerList ::LoadArc(uchar idx, float ProbVal) {
	Conditions[idx].Prob = ProbVal;
	for (uint k = 0; k<SubCounter; k++)
	 if ( (*SubEntriesPtr)[k]->FileID() == Conditions[idx].FileID() &&
	      (*SubEntriesPtr)[k]->LineNo() == Conditions[idx].LineNo() )
	 {  (*SubEntriesPtr)[k]->Prob = ProbVal; break; }
}*/

SumOfInProbsInfo SamplerList::SumOfInProbs() {
 float res = 0;
 int CrsTimes = 0;

 for (uchar k=0; k<SubCounter; k++)
  if ( (*SubEntriesPtr)[k]->Count() )
   for (uchar n=0; n < (*SubEntriesPtr)[k]->Count() ; n++)
    if ( (*SubEntriesPtr)[k]->CondOf(n)->FileID() == FileID() &&
	 (*SubEntriesPtr)[k]->CondOf(n)->LineNo() == LineNo() )
    { if ( !(*SubEntriesPtr)[k]->CondOf(n)->Prob )
       CrsTimes += !(*SubEntriesPtr)[k]->CondOf(n)->CrossTimes;
      res += (*SubEntriesPtr)[k]->CondOf(n)->Prob; break; }

 SumOfInProbsInfo tmp;
 tmp.Prob = res;
 tmp.CrossTimes = CrsTimes;

 return tmp;
};



void SamplerList :: Append( const SamplerRecord& rec )
{
   for ( uchar index=0; index<Counter && !(Conditions[index] == rec) ; index++ ) ;

   if ( index==Counter )
   {
      if ( Counter==MAX_CONDS ) return ;
      Counter ++ ;
   }

   Conditions[ index ] += rec ;
} // Append

void SamplerList :: Print( FILE* Stream, TIME ttime, Tscl Scale) const
{
   if (Counter)
   {
      WriteLine(Stream);
      for (uchar index=0; index<Counter; index++ )
      {
	 if (index) fprintf( Stream,"\n" );
	 Locate::Print(Stream);
	 fprintf( Stream," " );
	 Conditions[ index ].Print(Stream, ttime, Scale);
      }
   }
} // Print

void SamplerList :: Put( FILE* Stream ) const
{
   Locate :: Put (Stream);
   fwrite (&Counter,sizeof(Counter),1,Stream);
   for (uint i = 0; i < Counter; i++)
   {
      Conditions[i].Put (Stream);
   }
}

void SamplerList :: Get( FILE* Stream )
{
   Locate :: Get (Stream);
   fread (&Counter,sizeof(Counter),1,Stream);
   for (uint i = 0; i < Counter; i++)
   {
      Conditions[i].Get (Stream);
   }
}

/* --- Class Access --- */

static void SetProb(SamplerList* Entry) { //IV
  if ( !Entry->Count() ) return;
  SumOfInProbsInfo TempProb;
  TempProb.Prob = 1;

  //the first node has only one outgoing arc
  if (Entry->InArcs == 0) { Entry->CondOf(0)->Prob = 1; }
  else {
    TempProb = Entry->SumOfInProbs();
    if (!TempProb.Prob) return; //Entry musn't be processed in this brunch

    if (Entry->InArcs == 1) {
       long Total = 0;
      //fork, the prob. of the outgoing arc depends on the sum of entering arcs
       for (uchar p=0; p<Entry->Count(); p++)
	Total += Entry->CondOf(p)->CrossTimes;
       for (p=0; p<Entry->Count(); p++)
	Entry->CondOf(p)->Prob = Entry->CondOf(p)->CrossTimes/Total*TempProb.Prob;
    } //InArcs == 1

    if (Entry->InArcs == 2) {
       //it is the last node in simple loop
      if (Entry->Count() == 1)
      {
	if (!TempProb.CrossTimes) { Entry->CondOf(0)->Prob = TempProb.Prob; }
	else{

	}

      }

    }

  }; //else

  Entry->Prob = TempProb.Prob;

  //set recursion for outgoing arcs
 for (uchar n=0; n<Entry->Count(); n++)
  for (uint k = 0; k<Entry->SubCounter; k++)
   if ( (*Entry->SubEntriesPtr)[k]->FileID() == Entry->CondOf(n)->FileID() &&
	(*Entry->SubEntriesPtr)[k]->LineNo() == Entry->CondOf(n)->LineNo() )
   { if ( !(*Entry->SubEntriesPtr)[k]->Prob )
      SetProb( (*Entry->SubEntriesPtr)[k] ); break; }
}


void Access ::MapProbs() {           //IV
  //SubEntriesPtr and SubCounter in Entries[i] must be initialized
  for (uchar k=0; k<Counter; k++) {
   Entries[k]->SubCounter = Counter;
   Entries[k]->SubEntriesPtr = &Entries;

   //every Entries[i] must know the number of InArcs
   if ( Entries[k]->Count() )
    for (uchar n=0; n<Entries[k]->Count(); n++)
     for (uchar t=0; t<Counter; t++)
      if ( Entries[k]->CondOf(n)->LineNo() == Entries[t]->LineNo() &&
	   Entries[k]->CondOf(n)->FileID() == Entries[t]->FileID() )
      {  Entries[t]->InArcs++; break; }

  }

 //  SetProb(Entries[0]);

};

SamplerList* Access :: Search( const Locate& aSample ) const
{
   uint lower = 0;
   uint upper = Counter - 1;

   if( Counter > 0 )
   {
      while( lower < upper && upper!=UINT_MAX )
      {
         uint middle( (lower+upper)>>1 );
         SamplerList* Current( Entries[middle] );

         if( *Current == aSample ) return Current;
         if( *Current <  aSample ) lower = middle+1;
         else upper = middle-1;
      }
   }

   return ( lower == upper && *(Entries[lower]) == aSample)? Entries[lower] : NULL;
} // Search

SamplerList* Access :: Search( const FileHandle nFile, const uint nLine, uint& idx) const
{
   uint lower = 0;
   uint upper = Counter - 1;
   Locate aSample ( nFile, nLine );

   if( Counter > 0 )
   {
      while( lower < upper && upper!=UINT_MAX )
      {
         uint middle( (lower+upper)>>1 );
         SamplerList* Current( Entries[middle] );

         if( *Current == aSample )
         {  idx = middle;
            return Current;
         }
	 if( *Current <  aSample ) lower = middle+1;
         else upper = middle-1;
      }
   }
   if ( lower == upper && *(Entries[lower]) == aSample )
   {  idx = lower;
      return Entries[lower];
   }
   return NULL;
} // Search

void Access :: Append( SamplerList* forAdd )
{
   if ( Counter<MAX_ENTRIES )
   {
      for( uint loc = Counter; loc > 0 && *forAdd < *(Entries[loc-1]); loc-- ) ;

      memmove( Entries+loc+1,Entries+loc,sizeof(*Entries)*(Counter-loc) );
      Counter ++ ;

      Entries[loc] = forAdd;
   }
} // Append

void Access :: Print( FILE* Stream ) const
{
   fprintf( Stream,"\n\n   ’ Ў«Ёж  б १г«мв в ¬Ё Ё§¬ҐаҐ­Ё© ( ЁбЇ®«м§гҐвбп %u Ё§ %u § ЇЁбҐ© )\n",Counter,MAX_ENTRIES );
   WriteLine(Stream);
   //fprintf( Stream ,"€бе.Џ®§. ЏаЁҐ¬.Џ®§.  ЋЎйҐҐ ўаҐ¬п (б.)  Љ®«-ў® Їа®е. ‘।­ҐҐ ўаҐ¬п (б.)" );
   fprintf( Stream ,"€бе.Џ®§. ЏаЁҐ¬.Џ®§.  ЋЎйҐҐ ўаҐ¬п(¬Єб)  Љ®«-ў® Їа®е. ‚Ґа-вм ‘аҐ¤­ҐҐ ўаҐ¬п(¬Єб)"); 
   for ( uint index=0; index<Counter; index++ )
      if ( Entries[index] ) Entries[index]->Print(Stream, timeTrue, corrNum);
} // Print

/* --- Class CallsHandler --- */

CallsHandler :: CallsHandler()
   : LastUsedRec(NULL)
{
   SamplerStorage = new Storage;
   SamplerAccess  = new Access ;
   SamplerFiles   = new FileMgr ;
} // CallsHandler

CallsHandler :: ~CallsHandler()
{
   delete SamplerFiles ;
   delete SamplerAccess;
   delete SamplerStorage;
} // ~CallsHandler

void CallsHandler :: Handle( TIME time, PChar File, uint Line )
{
   SamplerRecord NewRecord;

   (Locate&)NewRecord = Locate( SamplerFiles->HandleOf(File),Line ) ;
   NewRecord.TotalTime  = time ;
   NewRecord.CrossTimes = 1 ;

   if ( LastUsedRec ) LastUsedRec->Append( NewRecord );

   LastUsedRec = SamplerAccess -> Search( NewRecord );

   if ( LastUsedRec==NULL )
   {
      LastUsedRec = SamplerStorage -> Allocate();

      if ( LastUsedRec != NULL )
      {
         *(Locate*)LastUsedRec = NewRecord ;
         SamplerAccess -> Append( LastUsedRec );
      }
   }
} // Handle

void CallsHandler :: Print( FILE* Stream , PChar ProgName ) const
{
   fprintf( Stream,"\n\n\tЋвзҐв ® १г«мв в е Ё§¬ҐаҐ­Ё© ¤«п Їа®Ја ¬¬л %s.",ProgName );
   fprintf( Stream,"\n\n\t‘®§¤ ­ Їа®Ја ¬¬®© Sampler ( ўҐабЁп ®в %s )",__DATE__ );
   fprintf( Stream,"\n\t\t1995-98 (c) ‘ЏЎѓќ’“, Њ®©бҐ©згЄ ‹Ґ®­Ё¤." );
   fprintf( Stream,"\n\t\t2006 (c) ‘ЏЎѓќ’“, ђл¦®ў €ў ­ (¬®¤Ґа­Ё§ жЁп).\n\n" );

   SamplerFiles  -> Print(Stream);
   SamplerAccess -> Print(Stream);
   WriteLine(Stream);
} // Print

void CallsHandler :: PrintCSA( FILE* Stream, PChar ProgName ) const  //IV
{
 fprintf( Stream,"<model type = \"Objects::AMC::Model\" name = \"Sampler graph for %s\">", ProgName);

 if (SamplerAccess->Counter)
 {
   uint AbsorbLine; uchar AbsorbFileID;
   char buf1[20], buf2[20];

   for (uint i = 0; i < SamplerAccess->Counter; i++)
   {
     if (i == SamplerAccess->Counter-1)
     { fprintf( Stream, "\n        <node type = \"Objects::AMC::Top\" name = \"absorb\"></node>");
       AbsorbFileID = SamplerAccess->Entries[i]->FileID();
       AbsorbLine = SamplerAccess->Entries[i]->LineNo();
     }
     else
     { fprintf( Stream, "\n        <node type = \"Objects::AMC::Top\" name = \"%i_%i\"></node>",
       SamplerAccess->Entries[i]->FileID(), SamplerAccess->Entries[i]->LineNo()); };
   }

   for (i = 0; i < SamplerAccess->Counter; i++)
   {
     if ( SamplerAccess->Entries[i]->Count() ) {

      int TotalEntries = 0; uint k;
      for (k = 0; k < SamplerAccess->Entries[i]->Count(); k++)
	 TotalEntries+=SamplerAccess->Entries[i]->CondOf(k)->CrossTimes;

      if (i == SamplerAccess->Counter-1) { sprintf(buf1,"%s","absorb"); } else
       { sprintf(buf1, "%i_%i", SamplerAccess->Entries[i]->FileID(), SamplerAccess->Entries[i]->LineNo()); }

      for (k = 0; k < SamplerAccess->Entries[i]->Count(); k++)
      {
	double precTime = 0.0;
	TIME   corrTime(UINT32(SamplerAccess->TrueTime())*SamplerAccess->Entries[i]->CondOf(k)->CrossTimes);
	precTime = TimeAsMicroSeconds(SamplerAccess->Entries[i]->CondOf(k)->TotalTime - corrTime, SamplerAccess->CorrScale());

	if ( SamplerAccess->Entries[i]->CondOf(k)->FileID() == AbsorbFileID &&
	   SamplerAccess->Entries[i]->CondOf(k)->LineNo() == AbsorbLine)
	{ sprintf(buf2,"%s","absorb"); } else
	{ sprintf(buf2, "%i_%i", SamplerAccess->Entries[i]->CondOf(k)->FileID(),
	  SamplerAccess->Entries[i]->CondOf(k)->LineNo()); }

	fprintf( Stream, "\n        <link type = \"Objects::AMC::Link\" name = \"%s", buf1);
	fprintf( Stream, "-->%s\" probability = \"%.2lf\" intensity = \"%.2lf\" deviation=\"0.0\" source = \"%s\" dest = \"%s\"></link>",
	buf2, (double)SamplerAccess->Entries[i]->CondOf(k)->CrossTimes/TotalEntries,
	 precTime, buf1, buf2);
      }
     }
  }
 }
 fprintf( Stream, "\n        <link type = \"Objects::AMC::Link\" name = \"absorb");
 fprintf( Stream, "-->absorb\" probability = \"1.00\" intensity = \"0.00\" deviation=\"0.0\" source = \"absorb\" dest = \"absorb\"></link>");
 fprintf( Stream,"\n</model>");
}

typedef char TGraphSign[5] ;
static TGraphSign gsEtalon = { 'S','M','P','2','V' } ;

void CallsHandler :: Put( FILE* Stream ) const
{
   fwrite(gsEtalon, sizeof(TGraphSign), 1, Stream);

   SamplerFiles -> Put ( Stream );
   fwrite (&(SamplerAccess->timeTrue),sizeof(SamplerAccess->timeTrue),1,Stream);
   fwrite (&(SamplerAccess->corrNum),sizeof(SamplerAccess->corrNum),1,Stream);
   fwrite (&(SamplerAccess->Counter),sizeof(SamplerAccess->Counter),1,Stream);
   for (uint i = 0; i < SamplerAccess->Counter; i++)
   {
      ( SamplerAccess->Entries[i] ) -> Put ( Stream ) ;
   }
}

int CallsHandler :: Get( FILE* Stream )
{
   delete SamplerStorage;
   SamplerStorage = new Storage;

   delete SamplerAccess;
   SamplerAccess = new Access;

   TGraphSign gSign;
   fread (gSign, sizeof(gSign), 1, Stream);
   if ( memcmp(gSign,gsEtalon,sizeof(TGraphSign)) )
      return 0;

   SamplerFiles -> Get ( Stream );
   fread (&(SamplerAccess->timeTrue),sizeof(SamplerAccess->timeTrue),1,Stream);
   fread (&(SamplerAccess->corrNum),sizeof(SamplerAccess->corrNum),1,Stream);
   fread (&(SamplerAccess->Counter),sizeof(SamplerAccess->Counter),1,Stream);
   for (uint i = 0; i < SamplerAccess->Counter; i++)
   {
      LastUsedRec = SamplerStorage -> Allocate();
      if ( LastUsedRec != NULL )
      {
         LastUsedRec -> Get ( Stream );
         SamplerAccess->Entries[i] = LastUsedRec;
      }
   }
   return 1;
}

/* ----- End of file SData.cpp ----- */
Соседние файлы в папке Samp16