The table map consider the table name as case insensitive.
The table map in Schema is tables: HashMap<Vec<u8>, Table> which requires the table name to be cloned and clone the search key on finding as well.
The search part can be mitigated by using new UpperToLowerBytes. However it requires unsafe to convert &[u8] to &UpperToLowerBytes. also it still clones the key on insersion.
#[derive(Eq)]
pub struct UpperToLowerBytesVec(Vec<u8>);
impl UpperToLowerBytesVec {
pub fn new(bytes: Vec<u8>) -> Self {
Self(bytes)
}
}
impl Borrow<UpperToLowerBytes> for UpperToLowerBytesVec {
fn borrow(&self) -> &UpperToLowerBytes {
(&self.0[..]).into()
}
}
impl PartialEq for UpperToLowerBytesVec {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
#[derive(Eq)]
pub struct UpperToLowerBytes([u8]);
impl From<&[u8]> for &UpperToLowerBytes {
fn from(bytes: &[u8]) -> Self {
unsafe { &*(bytes as *const [u8] as *const UpperToLowerBytes) }
}
}
impl PartialEq for UpperToLowerBytes {
fn eq(&self, other: &Self) -> bool {
if self.0.len() != other.0.len() {
return false;
}
for (i, b) in self.0.iter().enumerate() {
if UPPER_TO_LOWER[*b as usize] != UPPER_TO_LOWER[other.0[i] as usize] {
return false;
}
}
true
}
}
impl Hash for UpperToLowerBytes {
fn hash<H: Hasher>(&self, state: &mut H) {
for b in self.0.iter() {
state.write_u8(UPPER_TO_LOWER[*b as usize]);
}
}
}
Let's implement a new hash map using a key from the value.
The table map consider the table name as case insensitive.
The table map in Schema is
tables: HashMap<Vec<u8>, Table>
which requires the table name to be cloned and clone the search key on finding as well.The search part can be mitigated by using new
UpperToLowerBytes
. However it requiresunsafe
to convert&[u8]
to&UpperToLowerBytes
. also it still clones the key on insersion.Let's implement a new hash map using a key from the value.