Skip to content

Commit

Permalink
Update write array
Browse files Browse the repository at this point in the history
  • Loading branch information
sonndinh committed Feb 11, 2024
1 parent 630bccf commit bd157c1
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 75 deletions.
90 changes: 22 additions & 68 deletions dds/DCPS/XTypes/DynamicVwrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace DCPS {

bool check_rc(DDS::ReturnCode_t rc, DDS::MemberId id, DDS::TypeKind tk, const char* fn_name)
{
return XTypes::check_rc_from_get(rc, id, tk, fn_name, LogLevel::Warning);
return XTypes::check_rc_from_get(rc, id, tk, fn_name, LogLevel::Notice);
}

bool begin_member_helper(ValueWriter& vw, MemberParam* params,
Expand Down Expand Up @@ -1368,87 +1368,40 @@ bool vwrite_element(ValueWriter& vw, DDS::DynamicData_ptr value,
return vwrite_item(vw, value, id, elem_dt);
}

DDS::ReturnCode_t vwrite_primitive_array(ValueWriter& vw, DDS::DynamicData_ptr value,
XTypes::TypeKind prim_kind, XTypes::TypeKind orig_kind, CORBA::ULong arr_flat_idx)
{
// TODO: To support this optimization for dynamic data, we need to have the semantics
// of the MemberId argument dependent on whether get_*_value or get_*_values is called
// on the dynamic data object. In particular, in get_*_value, id is the Id of the final
// element type; in get_*_values, id is the Id of the innermost single-dimension array
// in relative to the whole original array.
const DDS::MemberId id = value->get_member_id_at_index(arr_flat_idx);
if (id == XTypes::MEMBER_ID_INVALID) {
if (log_level >= LogLevel::Notice) {
ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: vwrite_primitive_array: get_member_id_at_index %u failed\n", arr_flat_idx));
}
return DDS::RETCODE_BAD_PARAMETER;
}

// return vwrite_primitive_collection(vw, value, id, prim_kind, orig_kind, XTypes::TK_ARRAY);
return true;
}

// TODO(sonndinh): Don't need to optimize here anymore since we already attempt to do it
// one level up when writing this array as a member of a struct or union.
// When it reach this function, it means the attempt failed and we fall back to write
// elements one by one even if the element type is primitive.
bool vwrite_array_helper(ValueWriter& vw, CORBA::ULong dim_idx, const DDS::BoundSeq& dims,
std::vector<CORBA::ULong> idx_vec, const DDS::DynamicType_var& elem_type,
DDS::BoundSeq& idx_vec, const DDS::DynamicType_var& elem_type,
DDS::DynamicData_ptr value)
{
const XTypes::TypeKind elem_kind = elem_type->get_kind();
const CORBA::ULong dims_len = dims.length();
XTypes::TypeKind treat_elem_as;
if (get_equivalent_kind(elem_type, treat_elem_as) != DDS::RETCODE_OK) {
return false;
}

const bool try_optimize = XTypes::is_primitive(treat_elem_as) && dim_idx == dims_len - 1;
bool optimize_failed = false;

if (!vw.begin_array(elem_kind)) {
return false;
}
if (try_optimize) {
// Try writing the innermost arrays using write_*_array.
// Fall back to write elements one by one if fails.
CORBA::ULong arr_flat_idx = 0;
const DDS::ReturnCode_t rc = XTypes::flat_index(arr_flat_idx, idx_vec, dims, dim_idx);
if (rc != DDS::RETCODE_OK) {
if (log_level >= LogLevel::Notice) {
ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: vwrite_array_helper: flat_index failed (%C)\n",
retcode_to_string(rc)));
}
return false;
}
optimize_failed = vwrite_primitive_array(vw, value, treat_elem_as, elem_kind, arr_flat_idx) != DDS::RETCODE_OK;
}

if (!try_optimize || optimize_failed) {
for (CORBA::ULong i = 0; i < dims[dim_idx]; ++i) {
if (!vw.begin_element(i)) {
return false;
}
idx_vec[dim_idx] = i;
if (dim_idx == dims_len - 1) {
CORBA::ULong flat_idx = 0;
const DDS::ReturnCode_t rc = XTypes::flat_index(flat_idx, idx_vec, dims, dims_len);
if (rc != DDS::RETCODE_OK) {
if (log_level >= LogLevel::Notice) {
ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: vwrite_array_helper: flat_index failed (%C)\n",
retcode_to_string(rc)));
}
return false;
}
if (!vwrite_element(vw, value, elem_type, flat_idx)) {
return false;
for (CORBA::ULong i = 0; i < dims[dim_idx]; ++i) {
if (!vw.begin_element(i)) {
return false;
}
idx_vec[dim_idx] = i;
if (dim_idx == dims_len - 1) {
CORBA::ULong flat_idx = 0;
const DDS::ReturnCode_t rc = XTypes::flat_index(flat_idx, idx_vec, dims, dims_len);
if (rc != DDS::RETCODE_OK) {
if (log_level >= LogLevel::Notice) {
ACE_ERROR((LM_NOTICE, "(%P|%t) NOTICE: vwrite_array_helper: flat_index failed (%C)\n",
retcode_to_string(rc)));
}
} else if (!vwrite_array_helper(vw, dim_idx+1, dims, idx_vec, elem_type, value)) {
return false;
}
if (!vw.end_element()) {
if (!vwrite_element(vw, value, elem_type, flat_idx)) {
return false;
}
} else if (!vwrite_array_helper(vw, dim_idx+1, dims, idx_vec, elem_type, value)) {
return false;
}
if (!vw.end_element()) {
return false;
}
}

Expand All @@ -1469,7 +1422,8 @@ bool vwrite_array(ValueWriter& vw, DDS::DynamicData_ptr value, const DDS::Dynami

DDS::DynamicType_var elem_type = XTypes::get_base_type(td->element_type());
const DDS::BoundSeq& dims = td->bound();
std::vector<CORBA::ULong> idx_vec(dims.length());
DDS::BoundSeq idx_vec;
idx_vec.length(dims.length());

return vwrite_array_helper(vw, 0, dims, idx_vec, elem_type, value);
}
Expand Down
9 changes: 4 additions & 5 deletions dds/DCPS/XTypes/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1681,14 +1681,14 @@ bool has_explicit_keys(DDS::DynamicType* dt)
}

// Convert to a flat index using a given number of dimensions starting from the outermost dimension.
DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const std::vector<CORBA::ULong>& idx_vec,
DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const DDS::BoundSeq& idx_vec,
const DDS::BoundSeq& dims, CORBA::ULong up_to_ndims)
{
const CORBA::ULong dims_len = dims.length();
if (idx_vec.size() != dims_len) {
if (idx_vec.length() != dims_len) {
if (DCPS::log_level >= DCPS::LogLevel::Notice) {
ACE_ERROR((LM_WARNING, "(%P|%t) WARNING: flat_index: Number of dimensions (%u) != "
" size of the index vector (%u)\n", dims_len, idx_vec.size()));
" size of the index vector (%u)\n", dims_len, idx_vec.length()));
}
return DDS::RETCODE_BAD_PARAMETER;
}
Expand Down Expand Up @@ -1720,8 +1720,7 @@ DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const std::vector<CORBA::UL
return DDS::RETCODE_OK;
}

DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const std::vector<CORBA::ULong>& idx_vec,
const DDS::BoundSeq& dims)
DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const DDS::BoundSeq& idx_vec, const DDS::BoundSeq& dims)
{
return flat_index(flat_idx, idx_vec, dims, dims.length());
}
Expand Down
4 changes: 2 additions & 2 deletions dds/DCPS/XTypes/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,9 +242,9 @@ inline DCPS::Sample::Extent nested(DCPS::Sample::Extent ext)

// Convert the index vector to an element in a multi-dimensional array into a flat index.
// See description for ARRAY_TYPE in XTypes 1.3, page 139.
DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const std::vector<CORBA::ULong>& idx_vec,
DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const DDS::BoundSeq& idx_vec,
const DDS::BoundSeq& dims, CORBA::ULong up_to_ndims);
OpenDDS_Dcps_Export DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const std::vector<CORBA::ULong>& idx_vec,
OpenDDS_Dcps_Export DDS::ReturnCode_t flat_index(CORBA::ULong& flat_idx, const DDS::BoundSeq& idx_vec,
const DDS::BoundSeq& dims);

inline bool check_rc_from_get(DDS::ReturnCode_t rc, DDS::MemberId id, DDS::TypeKind tk,
Expand Down

0 comments on commit bd157c1

Please sign in to comment.