Using Data Structures

You can declare both input and output ports as well as parameters as type datastruct. If you do the Data Structure property becomes visible. A click on the green icon in the input field opens the Select Data Structure dialog.

Type checking

When you connect the ports of primitives and modules you should be careful because MLDesigner provides only a basic checking mechanism concerning compatability of datastruct types. No error will appear when you connect incompatible Datastruct ports. You must take care to connect ports that output and receive the same data structure. To keep compatibility with the scalar type, connecting a datastruct port with an int port or a float port is allowed. It is, however, necessary to check if the datastruct port type outputs or receives a data structure of type Integer or Float.

Import Libraries

Every data structure belongs to an XML Library. There are noneditable system libraries which are loaded every time you start MLDesigner and it is possible to define new libraries and add your own defined data structures to a library.

The Import Libraries parameter field is normally filled in automatically and is a reference to the location where data structures or shared model instances such as memories or events used in a particular system are stored.

These user defined data structures are only visible and available while the library within which they were defined is open in the Model Editor window.

A data structure is described by two different classes. The first class describes its type information such as name and inheritance. The second class is specific to the data structure instance and contains the value information.

The name of the type information class always ends with the class suffix (for example, DataStructureClass, VectorClass, ...). Objects of this class can be changed during the design phase and these changes modify the structure of data structures. During the simulation phase no changes over instances of this kind are allowed. The other type of classes represents the value part of a data structure. Instances of this classes are used in simulation process.

Every data structure value object holds a reference to its class object which should be unique for each defined data structure. This brings improvements in two directions: it uses less memory, putting all the common information in a single instance and it brings also speed improvements: duplicating a value object takes less time due to its smaller size and less member variables that needs to be copied.

A third type of data structure class that represents a reference to a value object exists. This is the TypeRef class, the base class for all data structure references, and it defines almost all the methods different data structures can implement. More specific the name of reference classes is suffixed by the letter R. Their purpose is to handle the creation, copying and releasing of data structure values that are to be used in simulation. These classes save you from all the overhead of creating and deleting data structures, making primitive programming much easier.

Data structures are organized in a hierarchy with Root as the parent of all data structures. Every data structure must have a parent, and this can be Root or another data structure of the same type. You can extend a composite data structure from Root or from another composite data structure and this means that all its members will be inherited by the newly created data structure. The same is also true for enumerations, in which case the enumeration will inherit all elements from its parent.

Data Structure string representation

Every data structure is characterized by a Name, a Full Name and a Unique Name.

Name
The name of the data structure (for example, TCPProtocol).
Full Name
Consists of the parents’ names and the data structure name separated by periods (for example, Root.NetworkProtocol.TCPProtocol).
Unique Name
Is composed of Library Name and Full Name separated by colon (for example, SystemDS:Root.NetworkProtocol.TCPProtocol).

It is possible to save and to set values of a data structure from a string. This is called the string representation of a data structure. The syntax of this is composed of the Unique Name and a string that represents its value between curly braces. This value string differs depending on the type of the data structure, and will be described separately for each data structure. Based on this string representation it is possible to set default values for parameters of Data Structure types, Memories and Events.

Data Structure types

Data Structure types in MLDesigner are grouped by their functionality in three branches as follows:

Base Data Structures

These Data Structures are used for operations with integers, floats or strings. If you want to use these types you must consider that they are classes which simulate scalar type, and systems which use them run slower compared to those that use only scalar types. Using them makes sense only if they are part of a system which contains complex data structures.

The following Data Structures are provided as basic types.

Name

Class Name

Description

Float

FloatType

Used to manipulate float scalar type.

Integer

IntType

Used to manipulate integer scalar type.

List

ListType

Represents a list of data structures.

Pointer

PointerType

A handle to any C++ object.

String

StringType

Used to manipulate strings.

BitVector

BitVector

This Data Structure is a vector of bits and thus consisting only of elements with the value 0 or 1.

FloatVector

FloatVector

A vector of float values.

IntVector

IntVector

A vector of integer values.

MVL4BitVector

MVL4BitVector

Data Structure to represent the multivalued logic standard. Elements can have the value 0, 1 , X or Z

ENUM

EnumType

For operations that use enumerations.

Numerical data structures (Integer and Float) support base mathematical operations such as addition, subtraction, multiplication and division. In Enumerations values are saved as strings, and as elements they have a special class that contains index and value for each element. That’s why EnumType provides various methods to get it’s elements as strings or as element objects.

The string representation for a base data structure is composed of its value surrounded by curly braces (for example, Root.Integer{123}).

Vector Data Structures

For Vectors two kinds of data structures exist: numeric and generic Vectors. For every Vector you can set or change the length. The generic Vector can hold any kind of MLDesigner data structure but if you need to save only scalar values it is much faster to use numeric Vectors, as they are optimized for this usage. Also, you can set a default value that all elements will hold on initialization.

Numeric Vectors

For Numeric Vector types the string representation must contain the length followed by a colon and the vector’s elements. If an element is repeated consecutively you can specify between [ ] how many times it is repeated. The last value in the string is multiplied as a default value for all the elements that remained unset.

Example:

{Root.IntVector{10:123}}, Vector with 10 elements all elements set to 123.

{Root.IntVector{10:8[4] 4 23}}, will create the Vector 8 8 8 8 4 23 23 23 23 23.

Generic Vectors

The generic Vector is implemented as a vector of pointers to data structure objects, so you can store any type of data structures. On initialization, this vector has all elements set to NULL, and you have to set every element one by one.

It is possible to derive the generic vector which means you define a new vector that at initialization has all elements set to the defaults of a data structure previously specified. As a string representation it is possible for a generic Vector to specify a Vector’s length together with the data structure name to initialize all elements.

Example:

Root.VECTOR {10:SystemDS:Root.NetworkProtocol.TCPProtocol
            {Name,{192,168,0,1},{192,168,0,2},110,110}}
, means a vector of ten TCPProtocol elements.

Composite Data Structures

This type of Data Structure can be used to model complex data and it can have any kind of Data Structure types as members. Working with this might not be so intuitive. If you want to access a member you first have to search for it by its name, and then get the data inside.

In case of composite Data Structures, values for members are listed in the order they exist in the Data Structure, separated by commas. This applies recursively to composite data members.

Example:

SystemDS:Root.NetworkProtocol.TCPProtocol{Name,{192,168,0,1},{192,168,0,2},110,110}

It is important to preserve the members’ order in this string representation, because the values are assigned based on this order. For more information on how to use composite data structures see Using Data Structures in the Programming section.