Skip to main content

KeyHolderOrder

Enum KeyHolderOrder 

Source
pub enum KeyHolderOrder {
    AscendingMemberId,
    Declaration,
}
Expand description

In what order the members of a key holder are serialized.

XTypes 1.3 §7.6.8 orders the holder’s members by member id, and DDSI-RTPS 2.5 §9.6.3.8 hashes whatever that produces. Two peers that disagree about the order compute two different KeyHashes for one sample, which is the same instance arriving under two handles — a wrong value with nothing on the wire to say so.

§What the implementations do

Measured 2026-08-10 through n3-keyholder/ on the Linux test host — Cyclone DDS 11.0.1 via dds_stream_extract_keyBE_from_key(…, DDS_CDR_KEY_SERIALIZATION_KEYHASH, …), RTI Connext 7.7.0 via PRESTypePlugin_interpretedSerializeKeyForKeyhash under all five encapsulations, Fast DDS via the generated KeyOrderPubSubType::compute_key. Two types, each declared in the reverse of its id order, so the KeyHash says which order won:

@final struct KeyOrder { @id(5) @key long  b; @id(2) @key long a; };  // b = 2, a = 1
@final struct KeyMixed { @id(5) @key octet b; @id(2) @key long a; };  // b = 2, a = 1
KeyOrder KeyHashKeyMixed KeyHash
Cyclone, XCDR1 and XCDR200000001 0000000200000001 02
RTI, XCDR2 (CDR2_BE, D_CDR2_BE, PL_CDR2_BE)00000001 0000000200000001 02
Fast DDS, both00000001 0000000200000001 02
RTI, XCDR1 (CDR_BE, PL_CDR_BE)00000002 0000000102000000 00000001

— all sixteen bytes wide, zero-extended. So the clause’s order is what three of the four combinations write, and RTI under encoding version 1 is the one that keeps declaration order: the same version split KeyHolderExtensibility and KeyHolderNesting already carry for RTI, on a third axis.

KeyMixed is the case that shows it is an ordering and not a coincidence of equal-width members: RTI’s XCDR1 holder is eight octets, with the octet first and three of padding behind it, and everyone else’s is five with no padding at all.

Cyclone’s serdata key buffer — dds_stream_extract_key_from_data, which is not the KeyHash — is in declaration order in both versions. It is an intermediate: dds_stream_extract_keyBE_from_key reorders it on the way to the hash, and reading the intermediate as the answer gives Cyclone a divergence it does not have.

Variants§

§

AscendingMemberId

Ascending effective member id. The clause, and what three of the four measured combinations write.

§

Declaration

The order the members are declared in, which is the order the sample carries them in.

RTI Connext 7.7 under XCDR1. Under XCDR2 RTI orders by member id like everyone else, which is why Dialect::key_holder_order takes the encoding.

Implementations§

Source§

impl KeyHolderOrder

Source

pub const ALL: [Self; 2]

Both.

Source

pub const fn is_default(self) -> bool

Whether this is the default.

Source

pub const fn as_str(self) -> &'static str

Short name, for configuration and diagnostics.

Source

pub fn parse(value: &str) -> Option<Self>

Parse a configuration value.

An unknown value returns None rather than falling back to the default: a typo here changes every instance handle.

Trait Implementations§

Source§

impl Clone for KeyHolderOrder

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for KeyHolderOrder

Source§

impl Debug for KeyHolderOrder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for KeyHolderOrder

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for KeyHolderOrder

Source§

impl Hash for KeyHolderOrder

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for KeyHolderOrder

Source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 (const: unstable) · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 (const: unstable) · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 (const: unstable) · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

fn clamp_to<R>(self, range: R) -> Self
where Self: Sized, R: ClampBounds<Self>,

🔬This is a nightly-only experimental API. (clamp_to)
Restrict a value to a certain range. Read more
Source§

impl PartialEq for KeyHolderOrder

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl PartialOrd for KeyHolderOrder

Source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 (const: unstable) · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 (const: unstable) · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 (const: unstable) · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 (const: unstable) · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl StructuralPartialEq for KeyHolderOrder

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.