ReadConditions and QueryConditions

ReadConditions are created by your application, but triggered by Connext DDS. ReadConditions provide a way for you to specify the DDS data samples that you want to wait for, by indicating the desired sample-states, view-states, and instance-states1These states are described in See "The SampleInfo Structure".. Then Connext DDS will trigger the ReadCondition when suitable DDS samples are available.

A QueryCondition is a special ReadCondition that allows you to specify a query expression and parameters, so you can filter on the locally available (already received) data. QueryConditions use the same SQL-based filtering syntax as ContentFilteredTopics for query expressions, parameters, etc. Unlike ContentFilteredTopics, QueryConditions are applied to data already received, so they do not affect the reception of data.

Multiple mask combinations can be associated with a single content filter. This is important because the maximum number of content filters that may be created per DataReader is 32, but more than 32 QueryConditions may be created per DataReader, if they are different mask-combinations of the same content filter.

ReadConditions and QueryConditions are created by using the DataReader’s create_readcondition() and create_querycondition() operations. For example:

DDSReadCondition* my_read_condition = 
	reader->create_readcondition(
DDS_NOT_READ_SAMPLE_STATE,
DDS_ANY_VIEW_STATE,
DDS_ANY_INSTANCE_STATE);
DDSQueryCondition* my_query_condition = 
	reader->create_querycondition(	
			DDS_NOT_READ_SAMPLE_STATE,
			DDS_ANY_VIEW_STATE,
			DDS_ANY_INSTANCE_STATE 
			query_expression, 
			query_parameters);

You can also use the alternative DataReader operations, create_readcondition_w_params() and create_querycondition_w_params(), which perform the same action as create_readcondition() and create_querycondition(), but allow the application to explicitly set the masks in the DDS_ReadConditionParams and DDS_QueryConditionParams structures (see DDS_ReadConditionParams and DDS_QueryConditionParams).

In addition, create_readcondition_w_params() and create_querycondition_w_params() allow selecting between TopicQuery samples and LIVE samples (see Topic Queries).

If you are using a ReadCondition to simply detect the presence of new data, consider using a StatusCondition (StatusConditions) with the DATA_AVAILABLE_STATUS instead, which will perform better in this situation.

A DataReader can have multiple attached ReadConditions and QueryConditions. A ReadCondition or QueryCondition may only be attached to one DataReader.

To delete a ReadCondition or QueryCondition, use the DataReader’s delete_readcondition() operation:

DDS_ReturnCode_t  delete_readcondition (DDSReadCondition *condition)

After a ReadCondition is triggered, use the FooDataReader’s read/take “with condition” operations (see read_w_condition and take_w_condition) to access the DDS samples.

ReadCondition and QueryCondition Operations lists the operations available on ReadConditions.

ReadCondition and QueryCondition Operations

Operation

Description

get_datareader

Returns the DataReader to which the ReadCondition or QueryCondition is attached.

get_instance_state_mask

Returns the instance states that were specified when the ReadCondition or QueryCondition was created. These are the DDS sample’s instance states that Connext DDS checks to determine whether or not to trigger the ReadCondition or QueryCondition .

get_sample_state_mask

Returns the sample-states that were specified when the ReadCondition or QueryCondition was created. These are the sample states that Connext DDS checks to determine whether or not to trigger the ReadCondition or QueryCondition.

get_view_state_mask

Returns the view-states that were specified when the ReadCondition or QueryCondition was created. These are the view states that Connext DDS checks to determine whether or not to trigger the ReadCondition or QueryCondition.

get_stream_kind_mask

Retrieves the stream kind mask for the condition.

DDS_ReadConditionParams

Type

Field Name

Description

DDS_SampleStateMask

sample_states

Sample state of the data samples that are of interest.

DDS_ViewStateMask

view_states

View state of the data samples that are of interest.

DDS_InstanceStateMask

instance_states

Instance state of the data samples that are of interest.

DDS_StreamKindMask

stream_kinds

Stream kind of the data samples that are of interest.

DDS_QueryConditionParams

Type

Field Name

Description

struct DDS_ReadConditionParams

as_readconditionparam

Read condition parameters

char *

query_expression

Expression for the query.

struct DDS_StringSeq

query_parameters

Parameters for the query expression.

How ReadConditions are Triggered

A ReadCondition has a trigger_value that determines whether the attached WaitSet is BLOCKED or UNBLOCKED. Unlike the StatusCondition, the trigger_value of the ReadCondition is tied to the presence of at least one DDS sample with a sample-state, view-state, and instance-state that matches those set in the ReadCondition. Furthermore, for the QueryCondition to have a trigger_value==TRUE, the data associated with the DDS sample must be such that the query_expression evaluates to TRUE.

The trigger_value of a ReadCondition depends on the presence of DDS samples on the associated DataReader. This implies that a single ‘take’ operation can potentially change the trigger_value of several ReadConditions or QueryConditions. For example, if all DDS samples are taken, any ReadConditions and QueryConditions associated with the DataReader that had trigger_value==TRUE before will see the trigger_value change to FALSE. Note that this does not guarantee that WaitSet objects that were separately attached to those conditions will not be awakened. Once we have trigger_value==TRUE on a condition, it may wake up the attached WaitSet, the condition transitioning to trigger_value==FALSE does not necessarily 'unwakeup' the WaitSet, since 'unwakening' may not be possible. The consequence is that an application blocked on a WaitSet may return from wait() with a list of conditions, some of which are no longer “active.” This is unavoidable if multiple threads are concurrently waiting on separate WaitSet objects and taking data associated with the same DataReader.

Consider the following example: A ReadCondition that has asample_state_mask = {NOT_READ} will have a trigger_value of TRUE whenever a new DDS sample arrives and will transition to FALSE as soon as all the newly arrived DDS samples are either read (so their status changes to READ) or taken (so they are no longer managed by Connext DDS). However, if the same ReadCondition had a sample_state_mask = {READ, NOT_READ}, then the trigger_value would only become FALSE once all the newly arrived DDS samples are taken (it is not sufficient to just read them, since that would only change the SampleState to READ), which overlaps the mask on the ReadCondition.

QueryConditions

A QueryCondition is a special ReadCondition that allows your application to also specify a filter on the locally available data.

The query expression is similar to a SQL WHERE clause and can be parameterized by arguments that are dynamically changeable by the set_query_parameters() operation.

QueryConditions are triggered in the same manner as ReadConditions, with the additional requirement that the DDS sample must also satisfy the conditions of the content filter associated with the QueryCondition.

QueryCondition Operations

Operation

Description

get_query_expression

Returns the query expression specified when the QueryCondition was created.

get_query_parameters

Returns the query parameters associated with the QueryCondition. That is, the parameters specified on the last successful call to set_query_parameters(), or if set_query_parameters() was never called, the arguments specified when the QueryCondition was created.

set_query_parameters

Changes the query parameters associated with the QueryCondition.

© 2018 RTI