Filtering during the exchange process is performed by a DDS::ContentFilteredTopic, which is created by the DDS::DataReader as a way of specifying a subset of the data samples that it wishes to receive.
Filtering samples that have already been received by the DDS::DataReader is performed by creating a DDS::QueryCondition, which can then used to check for matching samples, be alerted when matching samples arrive, or retrieve matching samples through use of the DDS::TypedDataReader::read_w_condition or DDS::TypedDataReader::take_w_condition functions. (Conditions may also be used with the APIs DDS::TypedDataReader::read_next_instance_w_condition and DDS::TypedDataReader::take_next_instance_w_condition.)
Filtering may be performed on any topic, either keyed or un-keyed, except the Built-in Topics. Filtering may be perfomed on any field, subset of fields, or combination of fields, subject only to the limitations of the filter syntax, and some restrictions against filtering some sparse value types of the Dynamic Data API.
RTI Data Distribution Service contains built in support for filtering using SQL syntax, described in the Queries and Filters Syntax module.
filter_expression
and expression_parameters
, futher specifies the values of the data which the DDS::DataReader wishes to receive.Once the DDS::ContentFilteredTopic has been created, a DDS::DataReader can be created using the filtered topic. The filter's characteristics are exchanged between the DDS::DataReader and any matching DDS::DataWriter during the discovery processs.
If the DDS::DataWriter allows (by DDS::DataWriterResourceLimitsQosPolicy::max_remote_reader_filters) and the number of filtered DDS::DataReader is less than or equal to 32, and the DDS::DataReader 's is empty, then the DDS::DataWriter will performing filtering and send to the DDS::DataReader only those samples that meet the filtering criteria.
If disallowed by the DDS::DataWriter, or if more than 32 DDS::DataReader require filtering, or the DDS::DataReader has set the , then the DDS::DataWriter sends all samples to the DDS::DataReader, and the DDS::DataReader discards any samples that do not meet the filtering criteria.
Although the filter_expression
cannot be changed once the DDS::ContentFilteredTopic has been created, the expression_parameters
can be modified using DDS::ContentFilteredTopic::set_expression_parameters. Any changes made to the filtering criteria by means of DDS::ContentFilteredTopic::set_expression_parameters, will be conveyed to any connected DDS::DataWriter. New samples will be subject to the modified filtering criteria, but samples that have already been accepted or rejected are unaffected. However, if the DDS::DataReader connects to a DDS::DataWriter that re-sends its data, the re-sent samples will be subjected to the new filtering criteria.
DDS::QueryCondition may be created on a disabled DDS::DataReader, or after the DDS::DataReader has been enabled. If the DDS::DataReader is enabled, and has already recevied and stored samples in its queue, then all data samples in the are filtered against the DDS::QueryCondition filter criteria at the time that the DDS::QueryCondition is created. (Note that an exclusive lock is held on the DDS::DataReader sample queue for the duration of the DDS::QueryCondition creation).
Once created, incoming samples are filtered against all DDS::QueryCondition filter criteria at the time of their arrival and storage into the DDS::DataReader queue.
The number of DDS::QueryCondition filters that an individual DDS::DataReader may create is set by DDS::DataReaderResourceLimitsQosPolicy::max_query_condition_filters, to an upper maximum of 32.
Foo:
String cft_param_list[] = {"1", "100"}; StringSeq cft_parameters = new StringSeq(java.util.Arrays.asList(cft_param_list)); ContentFilteredTopic cft = participant.create_contentfilteredtopic( "ContentFilteredTopic", topic, "value > %0 AND value < %1", cft_parameters); } if (cft == null) { System.err.println("create_contentfilteredtopic error\n"); return; }
FooDataReader reader = (FooDataReader) subscriber.create_datareader( cft, datareader_qos, // or Subscriber.DATAREADER_QOS_DEFAULT // listener, // or null // StatusKind.STATUS_MASK_ALL); if (reader == null) { System.err.println("create_datareader error\n"); return; }
cft_parameters.set(0, "5"); cft_parameters.set(1, "9"); cft.set_expression_parameters(cft_parameters);
FooDataReader reader = ...;
QueryCondition queryCondition = null; String qc_param_list[] = {"1", "100"}; StringSeq qc_parameters = new StringSeq(java.util.Arrays.asList(cft_param_list)); queryCondition = reader.create_querycondition(SampleStateKind.NOT_READ_SAMPLE_STATE, ViewStateKind.ANY_VIEW_STATE, InstanceStateKind.ANY_INSTANCE_STATE, "value > %0 AND value < %1", qc_parameters); if (queryCondition == null) { System.err.println("create_querycondition error\n"); return; }
FooSeq _dataSeq = new FooSeq(); SampleInfoSeq _infoSeq = new SampleInfoSeq(); try { reader.read_w_condition(_dataSeq, _infoSeq, ResourceLimitsQosPolicy.LENGTH_UNLIMITED, queryCondition); for(int i = 0; i < _dataSeq.size(); ++i) { SampleInfo info = (SampleInfo)_infoSeq.get(i); if (info.valid_data) { // --- Process data here --- // } } } catch (RETCODE_NO_DATA noData) { // No data to process } finally { reader.return_loan(_dataSeq, _infoSeq); }
retcode = reader.delete_readcondition(queryCondition);
This optimization applies to all filtering using the built-in SQL filter, performed by the DDS::DataReader, for either DDS::ContentFilteredTopic or DDS::QueryCondition. This does not apply to filtering perfomed for DDS::ContentFilteredTopic by the DDS::DataWriter.