partition_from_pubkey (#22430)

* Revert "chore: bump dashmap from 4.0.2 to 5.0.0 (#21824)"

This reverts commit 8aa3d690b5.

* partition_from_pubkey
This commit is contained in:
Jeff Washington (jwash) 2022-01-13 17:02:42 -06:00 committed by GitHub
parent 66a97bdde0
commit 7711cd74c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 106 additions and 1 deletions

View File

@ -4459,6 +4459,41 @@ impl Bank {
account_count
}
/// This is the inverse of pubkey_range_from_partition.
/// return the lowest end_index which would contain this pubkey
#[cfg(test)]
pub fn partition_from_pubkey(
pubkey: &Pubkey,
partition_count: PartitionsPerCycle,
) -> PartitionIndex {
type Prefix = u64;
const PREFIX_SIZE: usize = mem::size_of::<Prefix>();
const PREFIX_MAX: Prefix = Prefix::max_value();
if partition_count == 1 {
return 0;
}
// not-overflowing way of `(Prefix::max_value() + 1) / partition_count`
let partition_width = (PREFIX_MAX - partition_count + 1) / partition_count + 1;
let prefix = u64::from_be_bytes(pubkey.as_ref()[0..PREFIX_SIZE].try_into().unwrap());
if prefix == 0 {
return 0;
}
if prefix == PREFIX_MAX {
return partition_count - 1;
}
let mut result = (prefix + 1) / partition_width;
if (prefix + 1) % partition_width == 0 {
// adjust for integer divide
result = result.saturating_sub(1);
}
result
}
// Mostly, the pair (start_index & end_index) is equivalent to this range:
// start_index..=end_index. But it has some exceptional cases, including
// this important and valid one:
@ -4514,6 +4549,19 @@ impl Bank {
start_pubkey[0..PREFIX_SIZE].copy_from_slice(&start_key_prefix.to_be_bytes());
end_pubkey[0..PREFIX_SIZE].copy_from_slice(&end_key_prefix.to_be_bytes());
let start_pubkey_final = Pubkey::new_from_array(start_pubkey);
let end_pubkey_final = Pubkey::new_from_array(end_pubkey);
if start_index != 0 && start_index == end_index {
error!(
"start=end, {}, {}, start, end: {:?}, {:?}, pubkeys: {}, {}",
start_pubkey.iter().map(|x| format!("{:02x}", x)).join(""),
end_pubkey.iter().map(|x| format!("{:02x}", x)).join(""),
start_key_prefix,
end_key_prefix,
start_pubkey_final,
end_pubkey_final
);
}
trace!(
"pubkey_range_from_partition: ({}-{})/{} [{}]: {}-{}",
start_index,
@ -4523,9 +4571,66 @@ impl Bank {
start_pubkey.iter().map(|x| format!("{:02x}", x)).join(""),
end_pubkey.iter().map(|x| format!("{:02x}", x)).join(""),
);
#[cfg(test)]
if start_index != end_index {
assert_eq!(
if start_index == 0 && end_index == 0 {
0
} else {
start_index + 1
},
Self::partition_from_pubkey(&start_pubkey_final, partition_count),
"{}, {}, start_key_prefix: {}, {}, {}",
start_index,
end_index,
start_key_prefix,
start_pubkey_final,
partition_count
);
assert_eq!(
end_index,
Self::partition_from_pubkey(&end_pubkey_final, partition_count),
"{}, {}, {}, {}",
start_index,
end_index,
end_pubkey_final,
partition_count
);
if start_index != 0 {
start_pubkey[0..PREFIX_SIZE]
.copy_from_slice(&start_key_prefix.saturating_sub(1).to_be_bytes());
let pubkey_test = Pubkey::new_from_array(start_pubkey);
assert_eq!(
start_index,
Self::partition_from_pubkey(&pubkey_test, partition_count),
"{}, {}, start_key_prefix-1: {}, {}, {}",
start_index,
end_index,
start_key_prefix.saturating_sub(1),
pubkey_test,
partition_count
);
}
if end_index != partition_count - 1 && end_index != 0 {
end_pubkey[0..PREFIX_SIZE]
.copy_from_slice(&end_key_prefix.saturating_add(1).to_be_bytes());
let pubkey_test = Pubkey::new_from_array(end_pubkey);
assert_eq!(
end_index.saturating_add(1),
Self::partition_from_pubkey(&pubkey_test, partition_count),
"start: {}, end: {}, pubkey: {}, partition_count: {}, prefix_before_addition: {}, prefix after: {}",
start_index,
end_index,
pubkey_test,
partition_count,
end_key_prefix,
end_key_prefix.saturating_add(1),
);
}
}
// should be an inclusive range (a closed interval) like this:
// [0xgg00-0xhhff], [0xii00-0xjjff], ... (where 0xii00 == 0xhhff + 1)
Pubkey::new_from_array(start_pubkey)..=Pubkey::new_from_array(end_pubkey)
start_pubkey_final..=end_pubkey_final
}
pub fn get_partitions(