General changes
The new IS version uses the new efficient internal format for
information marshaling and unmarshaling, which save CPU cycles for
these operations, and result in more compact data representation lowing
the network bandwidth for the IS data exchange. These changes are not
very much visible for small information objects because the dominating
time in this case is given by the network latency. But in case of large
information objects (for example histograms with thousands
bins) the performance gain is very dramatic.
Changes in API
There are some (very limited) changes in the old IS API as well as some
new features, which are listed in this paragraph.
Changes in the old public API
- Names of the header files have been changed. Now there is one
header file per IS class, which has the same name as the class itself
but without capitalization. For example:
#include <is/infodictionary.h> // if you want to use the ISInfoDictionary class
#include <is/infoiterator.h> // if you want to use the ISInfoIterator class
etc...
This changes affect also the code,
which is generated from XML files by the IS generator utility. This
code now includes <is/info.h> file instead of the
<is/isinfo.h> as before. It is recommended to regenerate your
classes.
- The name of the enumeration, which defines the reason for
invoking an IS callback function, has been changed from the
ISInfoReason to the ISInfo::Reason to be in line with the other IS type
definitions. The values of this enumeration have to be referenced as
ISInfo::Created, ISInfo::Updated and ISInfo::Deleted instead of the
ISInfoCreated, ISInfoUpdated and ISInfoDeleted as it was in the
previous IS version.
New facilities
- Now there are two possible ways of subscribing to the changes in
the IS repository. First of all one can subscribe for receiving the
whole information object each time it is changed (as it was before). In
addition to that one can subscribe for receiving only
notification about changes without transporting the whole information
object over network. This may significantly reduce network load in case
of large information objects (for example histograms). For example in
order to to use the old subscription mechanism one has to define the
following function:
void info_callback(ISCallbackInfo * isc) { ... }
and pass pointer to this function to the ISInfoReceiver::subscribe
method. The new IS API keeps this possibility, but in addition to that
one can define the following callback function:
void event_callback(ISCallbackEvent * isc) { ... }
and call the ISInfoReceiver::subscribe with the pointer to this
function in order to receive only the notification about changes. The
only difference between the ISCallbackEvent and the ISCallbackInfo
classes is that the former one does not have the "value" function,
which can be used the get the value of the changed information object.
- IS implements now some sort of polymorphism for the information
objects. It was already possible in previous versions to use
inheritance for the information classes. For instance, the IS example,
which is included to the release, defines two classes in the XML file:
Person class with the name, birthday and sex attributes and the
Employee class, which inherits the Person and defines one more
attribute salary. In the new IS version it is possible to read from the
IS repository an information of the type Employee using the object of
the type Person. In the previous IS version the status, which was
returned by the ISInfoDictionary::getValue function was set to
ISInfo::IncompatibleType. In the current version the status would be
ISInfo::Success and the name, birthday and sex attributes of the Person
object will be set to the values of the Employee object from the IS
repository.
In order to expose this new feature to
user code the ISType class provides now more advanced functions for
types comparison:
This function can be used to check
whether given type is direct base type of the type tt.
This function can be used to check
whether given type is direct subtype of the type tt.
This function can be used to check
whether given type is compatible with type tt. Compatibility means that given
type is either the same type or the direct base type of the type tt. This function is not
reversible, i.e. if type T is compatible with the type V, the type V
is compatible with the type T only in case the both types are identical.
All this functions compare the
structure of the corresponding IS types (i.e. the type and order of the
attributes) but do not take into account names of the corresponding IS
types. The equality operator does both checks:
- ISType::operator==( const ISType & tt ) const;
it returns true only in case
the
given type has the same structure and name as the type tt.
Changes in the old
"private" API
IS provides an API, which was always
considered to be private for, but
due to the lack of C++ constructs, which may allow to hide this API in
an easy way, it was still possible to use it from external
applications. Now this API has been changed and, in case somebody is
using it, some instructions are given for how to migrate to this new
API. People, who never tried to provide their own ISostream and
ISistream classes may skip this section without loosing anything.
This point is the custom user ISostream and ISistream based classes,
which one can use as an interface for storing and retrieving the IS
information to and from another storage then the standard IS repository
server. Before it was possible to define your own classes, which
inherit from the ISostream and ISistream ones and override their
virtual
functions, which are used to read and write IS information attributes.
The objects of these new classes can be passed to the
ISInfo::publishGuts and ISInfo::refreshGuts functions in order to
serialize or deserialize a particular IS object.
Now the ISostream and ISistream classes are defined as templates in
order to reduce the amount of duplicated code and make the code less
error prone. However it is still possible to provide custom
implementations, but this should be done in different way as comparing
with the old IS implementation. Let's consider custom implementation of
the ISostream class. Now there are two possibilities of providing such
implementation:
- Using class with template operator and function:
One has to define a class with
one template operator for writing simple attributes and one template
function for writing array attributes. The following example shows how
to implement the IS output stream, which will put IS information to the
standard output. (A real example can be found in the
is/internal/datastream.h file)
struct MyISOutDatastream
{
template <typename T> void operator<<( const T & val ) {
std::cout << val << std::endl;
}
template <typename T> void put( const T * val, size_t size ) {
for ( size_t i = 0; i < size; i++ )
std::cout << val[i] << " ";
std::cout << std::endl;
}
};
- Using plain C++ class:
In this case the MyISOutDatastream can
be declared as a plain C++ class, which has to provide the
operator<< and the put function for each base type supported by
the IS. For the list of supported types one can see the
is/internal/types.h file.
Then you can write the
following code in order to put an IS object to your own stream:
void f1( ISInfo & info ) {
MyISOutDatastream mout;
is::ostream_tie<MyISOutDatastream> out( mout );
info.publishGuts( out );
}
To be implemented