Inspirel banner

YAMI4 Tip #3 - Shallow Parameters

Contrary to many other messaging solutions, YAMI4 comes with the object model that is ready to use out of the box. In other words, it is possible to structure the message content in a way that is readable at the receiver side, even if the receipient is written in different programming language or is running on a different hardware platform.

The part of YAMI4 that provides this functionality is called parameters and is basically a dictionary of typed entries. Parameters have their implementations in all supported programming languages, so that a parameters object created by (for example) a Java client can be properly recognized by a C++ server.

In C++ the parameters object is designed to own its data values by default. In other words, it behaves like a regular value container:

void send_message(const char * name, const char * surname)
{
    yami::parameters params;

    params.set_string("name", name);
    params.set_string("surname", surname);
    
    // ...
}

In the example above the params object owns all its entries, so that its use is safe even if the source values change or become invalid due to their shorter lifetime - that is, after setting "name" and "surname" above the original string values can disappear and it has no impact on the parameters object that already has the given values internally stored by copy.

This default behaviour is safe and is therefore recommended for most use cases. However, this safety comes at a price, which is the cost of making the internal copy of the data - this can become expensive with large values, which can be particularly relevant with binary fields. This cost can be visible in both time (it takes time to make a copy) and space (the copy needs its own memory buffer).

To help in such performance- and resource-intensive scenarios, the parameters object in C++ offers so called "shallow" fields, which keep reference to the given data without creating internal copies. The shallow variants of appropriate setters exist for both strings and binary values and can be used like this:

void send_message(const char * name, size_t name_length)
{
    yami::parameters params;

    params.set_string_shallow("name", name, name_length);
    
    // ...
}

Above, the params object will have the field "name" that keeps the reference to the given string instead of creating an internal copy. This allows to reduce the time and space requirements of this operation. The programmer has to ensure that the given value buffer exists as long as the parameters object refers to it. Note that shallow fields work only with explicit pointers and buffer sizes - this allows to avoid computation of the string length and in the case of binary fields this approach to handling data is very natural.

Note also that "shallow" fields do not represent a separate type in the YAMI4 type model. Regular (by copy) string fields and shallow string fields have the same type and from the point of view of the receiver they are equivalent.

Previous tip: Default Objects

Next tip: Truly Non-Blocking Send