Creating Structured Data Maps and Streams

The memory that must be allocated to create maps and streams can either be allocated by the client application to create message-independent maps and streams (refer to Message-Independent Maps and Streams), or it can be automatically allocated by the API to create message‑dependent maps and streams (refer to Message-Dependent Maps and Streams).

Message-independent maps and streams are available for all of the messaging APIs; whereas, message-dependent maps and streams are available for only the C and .NET APIs.

Message-Independent Maps and Streams

Typically, a map or stream is created in application memory that is independent of a particular message. This allows a container to be added to other containers or to the binary message parts of more than just one message. Using a message‑independent container can be useful if you want to add it repeatedly to different messages or to existing containers as a common container.

For the Java, JavaScript, Node.js, and .NET APIs, when a container is created, memory is allocated for it from the heap.

For the C API, you must pass in pointers to the location to receive the container pointer and to the location to create the container.

The following sections discuss how to use containers that are message‑independent:

Creating Structured Data Maps

To Create Structured Data Maps

Language

Call

Java

  • XMLMessageProducer.createMap()

  • JCSMPFactory.createMap()

C

solClient_container_createMap()

.NET

SDTUtils.CreateMap(...)

Once the application is done with the map, explicitly call Dispose() to ensure that allocated memory is freed.

JavaScript and Node.js

Create a new solace.SDTMapContainer object

Creating Structured Data Streams

To Create Structured Data Streams

Language

Call

Java

  • XMLMessageProducer.createStream()

  • JCSMPFactory.createStream()

C

solClient_container_createStream(...)

.NET

SDTUtils.CreateStream(...) and pass in the maximum size (in bytes) for the stream.

Once the application is done with the stream, explicitly call Dispose() to ensure that allocated memory is freed.

JavaScript and Node.js

Create a new solace.SDTStreamContainer object

Copying Content from Containers to Messages

To copy data from a container into a message’s binary attachment, call one of the functions or methods listed below. Pass in the message the content is for and the container with the content to be copied in. For the C API, pointers to the message and the container are used.

If a binary attachment is present before the function or method is called, it is removed before the new data is copied in.

After the function or method is called, any further changes to the container contents are not propagated to the referenced message.

To Copy Container Content to Messages

Language

Call

Java

Not applicable

C

solClient_msg_
setBinaryAttachmentContainer(...)

.NET

SDTUtils.SetSDTContainer(...)

JavaScript and Node.js

Not applicable

Adding Content from Containers to Messages by Reference

To add data from a map or a stream into a message’s binary attachment through a container reference call a method or function listed in the table below and pass a reference to the message to receive the contents and the container with the contents that are to be added.

If the message already has a binary attachment, it is removed and only the referenced map is transmitted.

C API

Adding data from a map or a stream into a message’s binary attachment through an opaque container pointer reference can improve system performance because it avoids copying application memory into the message binary attachment.

When the solClient_session_sendMsg() function is called, and the message is sent, the binary attachment contents are copied directly from the application memory to the transmit socket or buffer.

After solClient_msg_setBinaryAttachmentContainerPtr() is called, any further changes to the container data can result in corrupt container contents for the transmitted message, so the container must not be modified until the message has been successfully transmitted and acknowledged (if it is a Guaranteed message).

Adding Content from Containers by Reference

Language

Call

Java

  • MapMessage.setMap(SDTMap map)

  • StreamMessage.setStream(SDTStream stream)

C

solClient_msg_setBinaryAttachmentContainerPtr(solClient_opaqueMsg_pt msg_p, solClient_opaqueContainer_pt cont_p)

.NET

Not applicable

JavaScript and Node.js

Create a new SDT field object, passing in the SDT map or stream container object to be added by reference using solace.SDTField.create(...), then pass the SDT field object to message.setSdtContainer(...).

Adding Containers to Existing Containers

To add an existing container to a map or stream, call one of the functions or methods listed in the table below and pass in the parent container and the subcontainers that you want to add to it.

C API

Pointers to the message and the container are used. In addition, if the parent container is a map, you must also pass in the name of the field to add the container, and if the parent container is a stream, the name parameter must be NULL.

To Add Containers to Existing Containers

Language

Call

Java

  • SDTMap.putMap(String key, SDTMap value)

    Associates the specified key with the value in the map.

  • SDTMap.putStream(String key, SDTStream value)

    Associates the specified key with the value in the map.

  • SDTStream.writeMap(SDTMap value)

    Writes a map to a stream.

  • SDTStream.writeStream(SDTStream value)

    Writes a stream to a stream.

C

solClient_container_addContainer(...)

.NET

  • IMapContainer.AddSDTContainer(...)

  • IStreamContainer.AddSDTContainer(...)

JavaScript and Node.js

Create a new SDT field object, passing in the SDT map or stream container object to be added using solace.SDTField.create(...), then use the addField(...) method to add it to the SDT map or stream container.

Message-Dependent Maps and Streams

For the C and .NET APIs, containers can also be created directly in the binary attachment of a message using the memory block managed by the messaging API; the container is then dependent on that particular message and cannot be reused by other messages. For the Java, JavaScript, and Node.js API, containers can only be created independent of a particular message.

Creating Message-Dependent Maps and Streams

When using the C or .NET APIs, a client can create a map or stream of structured data directly in the binary attachment of a message. Structured data added in this manner is not created in an application memory-based container that can be reused. However, it does avoid a memory copy operation, and it off-loads the task of memory management from the application so that the messaging API is responsible for managing the memory allocated for the container.

To create message-dependent maps or streams, call one of the methods listed below to create a map or stream directly in the binary attachment of a specific message.

To Create Message-Dependent Maps and Streams

Language

Call

Java

Not applicable

C

  • solClient_msg_createBinaryAttachmentMap(...)

  • solClient_msg_createBinaryAttachmentStream(...)

.NET

  • SDTUtils.CreateMap(...)

  • SDTUtils.CreateStream(...)

JavaScript and Node.js

Not applicable

When using one of these functions or methods, you must specify the size (in bytes) of the datablock to allocate for the creation of the map or stream.

If a specific datablock size is set, and it is too small for the subsequently created map or stream, a larger datablock is allocated when data is added, and the existing structured data is copied into the new buffer. This reallocation can negatively affect performance.

If you want to use the smallest amount of messaging API memory, set a value of 0 for the size parameter. In this case, the API uses the smallest possible datablock (by default 10,240 bytes) to build the containers. If this is not enough, a reallocation occurs, and all existing data is copied into the new, larger buffer.

Data fields, submaps, and substreams can be created using SDT add methods or functions. Applications that receive messages can also do this before retransmitting or forwarding the data. For a comprehensive list of the available container methods and functions, refer to the Solace Messaging APIs documentation for the appropriate messaging API.

Deleting fields results in a buffer copy of the remainder of the map.