List of changes

On-the-fly data compression

IS supports now on-the-fly data compression when passing large information objects between information providers and receivers. Compression is done transparently behind the information provider API before sending information data to the IS server. IS server keeps data in compressed format. Uncompression is done by the receiving API inside an application, which is reading data from the IS server. This approach has an advantage of decreasing the amount of memory and network load for an IS server without increasing its CPU consumption. On the other hand it has also a drawback of increasing CPU consumption for the information senders and receivers. This functionality can be controlled via the environment variable called TDAQ_IS_COMPRESSION_THRESHOLD. This value defines the minimal information object size (in bytes) after which compression will be applied. (The size of information object is calculated as an amount of memory, which is occupied by all the object's attributes.) If this value is not set then default value, which is set to 10000 bytes, is used. One should set this variable to -1 in order to disable the compression.

Defining and using complex IS information classes

User defined IS classes may use another IS classes as types of their attributes. One can still use the OKS Scheme editor application to define a custom IS class. In order to explore the new functionality one can use OKS relationships for that class, which will appear as attributes of respective classes in the generated C++ or Java code. If OKS Cardinality Constraint defined for an IS class relationship is "ONE" then a single value attribute of the respective class will be generated. For any Cardinality Constraint value other the "ONE" a multi-value attribute will be declared, e.g. std::vector of the respective type in C++ class. To see an example one can have a look to the Online Histogramming XML file.

Compatibility Note: There are no incompatible changes in the public API with respect to this new feature. The old code, which is using IS, shall compile and function properly if it is used with old IS custom types (i.e. with types, which don't contain complex attributes).

Missing Functionality Note
: There is one restriction for the applications of the new functionality. An IS information class attribute can not be of the same type as one in which it is declared as well as of any subtype of this type. For example class Person, which is declared as having an attribute of class Child would be invalid if class Child inherits from the class Person. The class Person would be invalid as well (from the IS point of view) is it defines for example an attribute "conjoint" of class Person.


User's code, which is using an instance of ISInfoAny class to read and parse an arbitrary IS information, requires some modifications, if it can deal with the new complex IS information objects. Such code has to accept a new type code value as a result of the ISInfoAny::getAttributeType function. This new value is an additional one defined in the ISType::Basic enumeration and it has the following name ISType::InfoObject. Example below shows how the code, which parses an ISInfoAny can be implemented using recursive function invocation. This example is not very practical, but it illustrates the approach to writing ISInfoAny parsing code.
void printInfoAny( ISInfoAny & isa )
{
   
printInfoAnyHelper( isa, isa.type() );
}

void printInfoAnyHelper( ISInfoAny & isa, ISType & type )

{
    for ( size_t pos = 0; pos < type.entries(); pos++ )
    {
    ISType::Basic typecode = type.entryType( pos );
    if ( typecode == ISType::InfoObject )
    {
       if ( type.entryArray( pos ) )
       {
          size_t size = isa.readArraySize( );
          for( size_t i = 0; i < size; i++ )
          {
             printInfoAnyHelper( isa, type.entryInfoType( pos ) );
          }
       }
       else
       {
          printInfoAnyHelper( isa, type.entryInfoType( pos ) );
       }
    }
    else
    {
       // process simple attributes in the same way as with the previous IS versions
       ...
    }
}
}

Using different types of callbacks for IS subscriptions

The new IS API allows to use different types of callbacks for the ISInfoReceiver::subscribe functions. Previous IS versions support only global C-style functions or static class member functions as callbacks. The new version of the IS supports the following types of callbacks:
  1. Global C-style functions or static class member functions are still supported for backward compatibility.
  2. An instance of a class, which defines void operator()( ISCallbackInfo * ). This operator will be called when a subscribed event occurs.
  3. A combination of an instance of a class with the address of the member function of that class, which has the following syntax: void XXX( ISCallbackInfo * )
Below there are some examples, which show how to use the new subscription facilities:
void info_callback(ISCallbackInfo * ){}

struct InfoCallback
{
    void operator()( ISCallbackInfo * ) {}
};

struct CustomInfoCallback
{
    void callback( ISCallbackInfo * ) {}
};
...

IPCPartition partition( partition_name );
ISInfoReceiver receiver( partition );

receiver.subscribe( info_name, info_callback );
receiver.subscribe( info_name, InfoCallback() );

CustomInfoCallback custom_info_callback;
// Note that custom_info_callback is not copied. User is responsible for making
// sure that this object is not destroyed until the call to the unsubscribe function
receiver.subscribe( info_name, &CustomInfoCallback::callback, &custom_info_callback );

Changes in the IS code generator

There are several minor changes in the code, which is produced by the is_generator.sh script:
  1. By default std::vector is used for the multi-value attributes of the generated IS information classes. Using C-style arrays is deprecated, but still possible by specifying the "-a" command line parameter. Note however that the generated classes in this case will declare (and don't define) the copy constructor and copy operator, which makes instances of these classes noncopyable.
  2. The generator uses different convention for the names of the generated Enumeration types. The old version was using the attribute name plus "_E" token at the end. For example the following XML attribute:
<attribute name="sex" description="Person's sex" type="enum" range="male,female"/>
produced the following declaration in the C++ class:
class Person: public ISInfo
{
    enum sex_E { male, female };
    ...
};

The new generator uses the attribute name with inverted case of the first letter as name of the enumeration, e.g.:
class Person: public ISInfo
{
    enum Sex { male, female };
    ...
};

Changes in the IS utilities

is_ls
In order to support the proper formatting while printing out complex attributes, the output, which is produced by the is_ls utility has been slightly modified - if both "-D" and "-v" command line arguments are used, is_ls prints attribute description followed by the attribute value (not vice versa as it was before).
is_monitor
The IS monitor application displays values of the complex attributes as a list of comma separated tokens in square brackets, e.g. [ 1, "test", 3.27 ].  Each token inside brackets represents a value of an individual attribute of a complex IS information attribute.

To be implemented