Listing 1 Definition of the Predictor

enum ReturnValue
 {
   Failure,
   Success
 };

const DEF_CARDINAL=500;         //number of commands a_matrix can hold
const DEF_DELTA_CARDINAL=100;   //increment of cardinal_a_matrix
const MAX_SIZE_COMMAND=50;      //maximum size of command

class predictor
 {
       int num_commands;       //current number of unique commands
       int cardinal_a_matrix;  //max number of commands a_matrix can hold
       int *a_matrix;          //pointer to the adjacency matrix
       char *commands;         //list of unique commands
       int last_ordinal;       //index of last command

       ReturnValue size(int cardinality);  //malloc or remalloc to create
                                     // approp. a_matrix & commands
       int is_unique(char *command);       //checks commands[] for command
                                     // <0 =>No,else=>index of command
       ReturnValue insert(char *command);  //add command to commands
       ReturnValue update(int ordinal);    //increment a_matrix entry

   public:
       predictor()
        {
          num_commands=0;
          cardinal_a_matrix=DEF_CARDINAL;
          size(cardinal_a_matrix);
          last_ordinal=-1;
        }
       predictor(int cardinality)  //overload constructor
        {
          num_commands=0;
          cardinal_a_matrix=cardinality;
          size(cardinal_a_matrix);
          last_ordinal=-1;
        }
       ~predictor()            //destructor
        {
          cardinal_a_matrix=0;
          free(a_matrix);
          free(commands);
        }

       ReturnValue PutNextCommand(char *);
       ReturnValue GetNextCommand(char *);
       int WhenNextCommand(char *);
 };


ReturnValue predictor::PutNextCommand(char *command)
 {
   int ordinal;

   if(num_commands+1 >= cardinal_a_matrix)  //no space ?
    {
       cardinal_a_matrix+=DEF_DELTA_CARDINAL;
       if(size(cardinal_a_matrix)==Failure)//can not allocate space
          return(Failure);
    }

   if((ordinal=is_unique(command))==-l)     //command encountered before?
    {
       if(insert(command) == Failure)      //no - add it
          return(Failure);
       ordinal=num_commands;               //new ordinal number of command
    }

   return(update(ordinal));                //return appropriate value
 }


ReturnValue predictor::GetNextCommand(char *command)
 {
   int ordinal,max=0,i;
   int *last_command;

   //note: assumes a_matrix is stored in row major fashion

   last_command=a_matrix+                  //calculate row of last_command
          last_ordinal*
          cardinal_a_matrix*sizeof(int);  //size of a row
   //Note: With certain compilers, sizeof(int) is unnecessary

   for(i=0; i<num_commands; ++i)           //do MAX() function
    {
       if(*(last_command+i*sizeof(int))>max)
        {
          max=*(last_command+i*sizeof(int));
          ordinal =i;
        }
    }

   if(max>0)
    {
      strcpy(command,commands*MAX_SIZE_COMMAND);
      return(Success);
    }
   else
    {
      command=NULL;
      return(Failure);
    }
 }

int predictor::WhenNextCommand(char *command)
 {
   int count=1;
   int old_last_ordinal=last_ordinal;  //save state of predictor
   int any_cycle[num_commands];        //check to see if we have cycled
   int i;
   char pcommand[MAX_SIZE_COMMAND];

   //zero
   for(i=0; i<num_commands; ++i)
      any_cycle[i]=0;

   while(GetNextCommand(command)==Success)
    {
      if(!strcmp(pcommand,command))    //found the command
         break;

      i=is_unique(pcommand);           //find index of predicted command
      if(!any_cyle[i]^1)               //test and check
       {
         count=0;                      //we have cycled - failure
         break;
       }

      ++count;
    }
   return(count);
 }

/* End of File */