Created
July 1, 2024 18:12
-
-
Save allada/27f23fb613956db0cc00752cb3b43532 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[repr(u8)] | |
#[derive(Copy, Clone, Debug, PartialEq)] | |
enum PriorityActionStage { | |
// Note: These are ordered by priority with the items that need to be | |
// processed first at the top (highest number). | |
Unknown = 0, | |
CompletedFromCache = 1, | |
Completed = 2, | |
Executing = 3, | |
Queued = 4, | |
CacheCheck = 5, | |
} | |
impl From<&ActionStage> for PriorityActionStage { | |
fn from(stage: &ActionStage) -> Self { | |
match stage { | |
ActionStage::CacheCheck => Self::CacheCheck, | |
ActionStage::Queued => Self::Queued, | |
ActionStage::Executing => Self::Executing, | |
ActionStage::Completed(_) => Self::Completed, | |
ActionStage::CompletedFromCache(_) => Self::CompletedFromCache, | |
ActionStage::Unknown => Self::Unknown, | |
} | |
} | |
} | |
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] | |
#[repr(transparent)] | |
struct AwaitedActionSortKey(u64); | |
impl AwaitedActionSortKey { | |
const fn new(state_priority: PriorityActionStage, priority: i32, hash: [u8; 3]) -> Self { | |
let state_priority = state_priority as u8 as u64; | |
// Shift `new_priority` so [`i32::MIN`] is represented by zero. | |
// This makes it so any nagative values are positive, but | |
// maintains ordering. | |
const MIN_I32: i64 = (i32::MIN as i64).abs(); | |
let priority = (priority as i64 + MIN_I32) as u64; | |
// The left 4 bits are the state priority, the next 32 bits are the | |
// priority, and the right 28 bits are the hash. | |
let hash = u64::from_be_bytes([0, 0, 0, 0, 0, hash[0], hash[1], hash[2]]); | |
let final_priority = (state_priority << 56) | (priority << 24) | hash; | |
AwaitedActionSortKey(final_priority) | |
} | |
fn new_with_action_hash(state_priority: PriorityActionStage, priority: i32, action_hash: &ActionInfoHashKey) -> Self { | |
let hash = { | |
let mut hasher = DefaultHasher::new(); | |
ActionInfoHashKey::hash(action_hash, &mut hasher); | |
hasher.finish().to_le_bytes()[0..3].try_into().unwrap() | |
}; | |
Self::new(state_priority, priority, hash) | |
} | |
} | |
// Ensure the size of the sort key is the same as a `u64`. | |
assert_eq_size!(AwaitedActionSortKey, u64); | |
// Note: Result has 0x3456789a + 0x80000000 = 0xb456789a because we need | |
// to shift the `i32::MIN` value to be represented by zero. | |
const_assert_eq!(AwaitedActionSortKey::new(PriorityActionStage::Queued, 0x3456789a, [0xbc, 0xde, 0xf0]).0, AwaitedActionSortKey(0x04b456789abcdef0).0); | |
// Ensure PriorityActionStage is used as the sort key first. | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::CacheCheck, i32::MIN, [0; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, i32::MAX, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, i32::MIN, [0; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Executing, i32::MAX, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Executing, i32::MIN, [0; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Completed, i32::MAX, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Completed, i32::MIN, [0; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::CompletedFromCache, i32::MAX, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::CompletedFromCache, i32::MIN, [0; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Unknown, i32::MAX, [0; 3]).0); | |
// Ensure the priority is used as the sort key second. | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, i32::MAX, [0xff; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, i32::MAX - 1, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, i32::MAX - 1, [0xff; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, 1, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, 1, [0xff; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, 0, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, 0, [0xff; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, -1, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, -1, [0xff; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, i32::MIN + 1, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, i32::MIN + 1, [0xff; 3]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, i32::MIN, [0; 3]).0); | |
// Ensure the hash is used as the sort key third. | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::CacheCheck, 0, [0xff, 0xff, 0xff]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, 0, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, 1, [0xff, 0xff, 0xff]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, 0, [0; 3]).0); | |
const_assert!(AwaitedActionSortKey::new(PriorityActionStage::Queued, 0, [0xff, 0xff, 0xff]).0 > AwaitedActionSortKey::new(PriorityActionStage::Queued, 0, [0; 3]).0); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment