GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



next up previous contents
Next: Cloning Objects Up: Some Not So Useful Previous: Getting an Object's Type   Contents

Determining Object Equality

As discussed previously, each GAT class has a corresponding ``Equals'' function. In this subsection we will examine this ``Equals'' function.

First one may wonder what such an ``Equals'' function actually does as C is equipped with a extreemely useful ==. As GATObject instances are opaque pointers, one can use the == with which C is equipped to determine the equality of two such GATObject instances. For example, if we had two GATTime instances, timeOne and timeTwo, then we could determine their equality as follows

if( timeOne == timeTwo )
{
  printf("timeOne == timeTwo");
}

This would determine if the two opaque pointers timeOne and timeTwo point to the same region in memory, a useful piece of knowledge. However, it is often not enough.

There exist at least two notions of equivalence one commonly deals with: pysical equivalence, illustrated by the previous example using ==, and semantic equivalence, which is what the ``Equals'' functions implement. For example, two GATTime instances are semantically equivalent if they currespond to the same number of seconds elapsed since 00:00 hours, Jan 1, 1970 UTC, the epoch. However, this semantic equivalence need not imply physical equivalence, which would only occur if the two instances are found to be equivalent using ==.

The example for this section will hopefully clarify these concepts. The full example is as follows

#include "GAT.h"
#include <stdio.h>

int main(void)
{
  GATBool isequal;
  GATTime timeOne;
  GATTime timeTwo;
  GATResult result;
  
  /* Create a GATTime corresponding to 1 hour after the epoch */
  timeOne = GATTime_Create( 3600 );
  
  /* Create a GATTime corresponding to 1 hour after the epoch */
  timeTwo = GATTime_Create( 3600 );
  
  /* Determine physical equivalence of timeOne and timeTwo */
  if( timeOne == timeTwo )
  {
    printf( "timeOne and timeTwo are physically equivalent\n" );
  }
  else
  {
    printf( "timeOne and timeTwo are not physically equivalent\n" );
  }
  
  /* Determine semantic equivalence of timeOne and timeTwo */
  if( (NULL != timeOne) && (NULL != timeTwo) )
  {
    result = GATTime_Equals( timeOne, timeTwo, &isequal );
    if( GAT_SUCCEEDED( result ) )
    {
      if( GATTrue == isequal )
      {
        printf( "timeOne and timeTwo are semantically equivalent\n" );
      }
      else
      {
        printf( "timeOne and timeTwo are not semantically equivalent\n" );
      }
    }
  }
  
  /* Destroy the GATTime timeOne */
  GATTime_Destroy( &timeOne );
  
  /* Destroy the GATTime timeTwo */
  GATTime_Destroy( &timeTwo );
  
  return 0;
}

Let us examine this program.

The lines

#include "GAT.h"
#include <stdio.h>

int main(void)
{
  ...
}

are now standard. They include the required GAT header GAT.h, the standard C header stdio.h, and the standard main function. The next lines

GATBool isequal;
GATTime timeOne;
GATTime timeTwo;
GATResult result;

declare the variable isequal of type GATBool, a type covered in Appendix [*], the variable timeOne and timeTwo, each of type GATTime, and result, a variable of type GATResult. The type GATResult is simply typedef'd to be the GAT primitive type GATint32. Variables of type GATResult are used to return the completion status of a function. Various completion statuses correspond to various GATResult values. The various values and the semantics of the various values will not be covered here as that would take us a bit far afield; however, in Appendix [*] the various values and their semantics are covered in detail. The next lines

/* Create a GATTime corresponding to 1 hour after the epoch */
timeOne = GATTime_Create( 3600 );
  
/* Create a GATTime corresponding to 1 hour after the epoch */
timeTwo = GATTime_Create( 3600 );

create two GATime instances each corresponding to $3600$ seconds after the epoch. The following lines

/* Determine physical equivalence of timeOne and timeTwo */
if( timeOne == timeTwo )
{
  printf( "timeOne and timeTwo are physically equivalent\n" );
}
else
{
  printf( "timeOne and timeTwo are not physically equivalent\n" );
}

determine if the two instances, timeOne and timeTwo, are physically equivalent and print the result of this determination. What will it print? The next lines

/* Determine semantic equivalence of timeOne and timeTwo */
if( (NULL != timeOne) && (NULL != timeTwo) )
{
  result = GATTime_Equals( timeOne, timeTwo, &isequal );
  if( GAT_SUCCEEDED( result ) )
  {
    if( GATTrue == isequal )
    {
      printf( "timeOne and timeTwo are semantically equivalent\n" );
    }
    else
    {
      printf( "timeOne and timeTwo are not semantically equivalent\n" );
    }
  }
}

first check that timeOne and timeTwo are both not NULL. They then call the function

GATResult GATTime_Equals( GATTime timeOne, GATTime timeTwo, GATBool *isequal )

This function determines if the passed GATTime instances, timeOne and timeTwo, are semantically equivalent. It returns the result of this determination in the GATBool pointed to by the passed GATBool*. The completion status of this function is returned through the return value of this function, a GATResult. The next lines

if( GAT_SUCCEEDED( result ) )
{
  ...
}

check that the call to the function GATTime_Equals completed sucessfully through use of the macro GAT_SUCCEEDED. Use of this macro is covered in Appendix [*]. The next lines

if( GATTrue == isequal )
{
  printf( "timeOne and timeTwo are semantically equivalent\n" );
}
else
{
  printf( "timeOne and timeTwo are not semantically equivalent\n" );
}

check the value of isequal against GATTrue and print out the result of this comparison. If isequal has value GATTrue, then timeOne and timeTwo are semantically equivalent. If isequal does not have value GATTrue, then timeOne and timeTwo aren't semantically equivalent. What will this print? The final lines of the program

/* Destroy the GATTime timeOne */
GATTime_Destroy( &timeOne );
  
/* Destroy the GATTime timeTwo */
GATTime_Destroy( &timeTwo );
  
return 0;

simply clean up the allocated GATTime instances and return $0$ from the main function.


next up previous contents
Next: Cloning Objects Up: Some Not So Useful Previous: Getting an Object's Type   Contents
Andre Merzky 2004-05-13