Use FieldIdx in FieldsShape

Finally got to the main motivating example from the MCP :)
This commit is contained in:
Scott McMurray
2023-04-02 23:21:09 -07:00
parent bf41e753ec
commit 21bb8ef24e
7 changed files with 133 additions and 101 deletions

View File

@@ -1108,7 +1108,7 @@ pub enum FieldsShape {
/// ordered to match the source definition order.
/// This vector does not go in increasing order.
// FIXME(eddyb) use small vector optimization for the common case.
offsets: Vec<Size>,
offsets: IndexVec<FieldIdx, Size>,
/// Maps source order field indices to memory order indices,
/// depending on how the fields were reordered (if at all).
@@ -1122,7 +1122,7 @@ pub enum FieldsShape {
///
// FIXME(eddyb) build a better abstraction for permutations, if possible.
// FIXME(camlorn) also consider small vector optimization here.
memory_index: Vec<u32>,
memory_index: IndexVec<FieldIdx, u32>,
},
}
@@ -1157,7 +1157,7 @@ impl FieldsShape {
assert!(i < count);
stride * i
}
FieldsShape::Arbitrary { ref offsets, .. } => offsets[i],
FieldsShape::Arbitrary { ref offsets, .. } => offsets[FieldIdx::from_usize(i)],
}
}
@@ -1168,7 +1168,9 @@ impl FieldsShape {
unreachable!("FieldsShape::memory_index: `Primitive`s have no fields")
}
FieldsShape::Union(_) | FieldsShape::Array { .. } => i,
FieldsShape::Arbitrary { ref memory_index, .. } => memory_index[i].try_into().unwrap(),
FieldsShape::Arbitrary { ref memory_index, .. } => {
memory_index[FieldIdx::from_usize(i)].try_into().unwrap()
}
}
}
@@ -1176,20 +1178,17 @@ impl FieldsShape {
#[inline]
pub fn index_by_increasing_offset<'a>(&'a self) -> impl Iterator<Item = usize> + 'a {
let mut inverse_small = [0u8; 64];
let mut inverse_big = vec![];
let mut inverse_big = IndexVec::new();
let use_small = self.count() <= inverse_small.len();
// We have to write this logic twice in order to keep the array small.
if let FieldsShape::Arbitrary { ref memory_index, .. } = *self {
if use_small {
for i in 0..self.count() {
inverse_small[memory_index[i] as usize] = i as u8;
for (field_idx, &mem_idx) in memory_index.iter_enumerated() {
inverse_small[mem_idx as usize] = field_idx.as_u32() as u8;
}
} else {
inverse_big = vec![0; self.count()];
for i in 0..self.count() {
inverse_big[memory_index[i] as usize] = i as u32;
}
inverse_big = memory_index.invert_bijective_mapping();
}
}
@@ -1199,7 +1198,7 @@ impl FieldsShape {
if use_small {
inverse_small[i] as usize
} else {
inverse_big[i] as usize
inverse_big[i as u32].as_usize()
}
}
})