Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Item ordering #71

Open
m-mueller678 opened this issue Sep 24, 2023 · 4 comments
Open

Item ordering #71

m-mueller678 opened this issue Sep 24, 2023 · 4 comments

Comments

@m-mueller678
Copy link

Currently, the linkme macro accepts an usize sort key. Although it is not documented, I assume this controls the ordering of the elements in the final slice. I was planing to use this to guarantee a deterministic ordering of entries between builds by supplying a hash of the item as the sort key. Otherwise, I end up with different orderings between release and debug builds. Unfortunately, the sort key is limited to a maximum of 9999, which is too small to avoid hash collisions.

It would be neat to have more control over the ordering of items.

@BD103
Copy link

BD103 commented Dec 21, 2023

To add on to this, this feature should at least be documented if it is intended to be used by others.

@MarkusTieger
Copy link

Currently, the linkme macro accepts an usize sort key. Although it is not documented, I assume this controls the ordering of the elements in the final slice. I was planing to use this to guarantee a deterministic ordering of entries between builds by supplying a hash of the item as the sort key. Otherwise, I end up with different orderings between release and debug builds. Unfortunately, the sort key is limited to a maximum of 9999, which is too small to avoid hash collisions.

It would be neat to have more control over the ordering of items.

Actually I tried that, if I specify a sort key, it just isn't present in the array.

@oberrich
Copy link

oberrich commented Sep 2, 2024

I've tried the following on Windows:

#[distributed_slice]
pub static ITEM: [u32];

#[distributed_slice(ITEM, 2)]
static ITEM2: u32 = 2;
#[distributed_slice(ITEM, 1)]
static ITEM1: u32 = 1;

which expands to

#[link_section = ".linkme_ITEM$b0002"]
static ITEM2: u32 = {...};
#[link_section = ".linkme_ITEM$b0001"]
static ITEM1: u32 = {...};

According to Raymond Chen's Old New Thing the linker sorts items into the section according to the fragment on the right of the $ sign. As expected, the items are put into the section in correct order:

image

As for the limit of 9999, not sure if this is a linker restriction or an artificial limitation.
Which platform did you try it on? Maybe your platform has a different linker behavior.

@oberrich
Copy link

oberrich commented Sep 2, 2024

Actually there's two unexpected gotchas when using this facility:

  • When mixing ordered slice elements with non-ordered ones, the non-ordered ones will always be sorted into the front of the slice.
#[distributed_slice]
pub static ITEM: [u32];

#[distributed_slice(ITEM, 2)] // .linkme_ITEM$b0002
static ITEM2: u32 = 2;
#[distributed_slice(ITEM, 1)] // .linkme_ITEM$b0001
static ITEM1: u32 = 1;
#[distributed_slice(ITEM)] // .linkme_ITEM$b
static ITEM3: u32 = 3;

fn main() {
    println!("{:?}", ITEM.iter());
}

yields Iter([3, 1, 2]) as opposed to Iter([1, 2, 3]) since .linkme_ITEM$b is lexicographically smaller than .linkme_ITEM$b0001.

  • Reusing the same order for a slice element, will introduce an unordered sub-slice within said order.
#[distributed_slice(ITEM, 1)]
static ITEM1: u32 = 1;
#[distributed_slice(ITEM, 2)]
static ITEM2: u32 = 2;
#[distributed_slice(ITEM, 2)]
static ITEM3: u32 = 3;
#[distributed_slice(ITEM, 4)]
static ITEM4: u32 = 4;

yields Iter([1, 3, 2, 4]) while

#[distributed_slice(ITEM, 1)]
static ITEM1: u32 = 1;
#[distributed_slice(ITEM, 2)]
static ITEM3: u32 = 3;
#[distributed_slice(ITEM, 2)]
static ITEM2: u32 = 2;
#[distributed_slice(ITEM, 4)]
static ITEM4: u32 = 4;

yields Iter([1, 2, 3, 4]).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants