This commit is contained in:
Christian Schwarz
2024-08-22 12:45:13 +00:00
parent 78d1ba4f5d
commit 20d97f8430
4 changed files with 56 additions and 56 deletions

View File

@@ -149,7 +149,7 @@ impl EphemeralFile {
let buffer = self.buffered_writer.inspect_buffer();
let buffered = &buffer[0..buffer.pending()];
let dst_cap = dst.bytes_total().as_u64();
let dst_cap = dst.bytes_total().into_u64();
let end = {
// saturating_add is correct here because the max file size is u64::MAX, so,
// if start + dst.len() > u64::MAX, then we know it will be a short read
@@ -179,11 +179,7 @@ impl EphemeralFile {
let file: &VirtualFile = file_size_tracking_writer.as_inner();
let bounds = dst.bounds();
let slice = file
.read_exact_at(
dst.slice(0..written_range.len().as_usize()),
start as u64,
ctx,
)
.read_exact_at(dst.slice(0..written_range.len().into_usize()), start, ctx)
.await?;
Slice::from_buf_bounds(Slice::into_inner(slice), bounds)
} else {
@@ -195,17 +191,17 @@ impl EphemeralFile {
.0
.checked_sub(flushed_offset)
.unwrap()
.as_usize();
.into_usize();
let to_copy =
&buffered[offset_in_buffer..(offset_in_buffer + buffered_range.len().as_usize())];
&buffered[offset_in_buffer..(offset_in_buffer + buffered_range.len().into_usize())];
let bounds = dst.bounds();
let mut view = dst.slice(
written_range.len().as_usize()
written_range.len().into_usize()
..written_range
.len()
.checked_add(buffered_range.len())
.unwrap()
.as_usize(),
.into_usize(),
);
view.as_mut_rust_slice_full_zeroed()
.copy_from_slice(to_copy);
@@ -216,7 +212,7 @@ impl EphemeralFile {
// TODO: in debug mode, randomize the remaining bytes in `dst` to catch bugs
Ok((dst, (end - start).as_usize()))
Ok((dst, (end - start).into_usize()))
}
/// Returns the offset at which the first byte of the input was written, for use
@@ -231,7 +227,7 @@ impl EphemeralFile {
) -> std::io::Result<u64> {
let pos = self.bytes_written;
let new_bytes_written = pos.checked_add(srcbuf.len().as_u64()).ok_or_else(|| {
let new_bytes_written = pos.checked_add(srcbuf.len().into_u64()).ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::Other,
format!(
@@ -366,10 +362,10 @@ mod tests {
assert!(file.len() as usize == write_nbytes);
for i in 0..write_nbytes {
assert_eq!(value_offsets[i], i.as_u64());
assert_eq!(value_offsets[i], i.into_u64());
let buf = Vec::with_capacity(1);
let (buf_slice, nread) = file
.read_at_to_end(i.as_u64(), buf.slice_full(), &ctx)
.read_at_to_end(i.into_u64(), buf.slice_full(), &ctx)
.await
.unwrap();
let buf = buf_slice.into_inner();

View File

@@ -173,7 +173,7 @@ impl InMemoryLayerIndexValue {
.checked_add(batch_offset)
.ok_or_else(|| anyhow::anyhow!("base_offset + batch_offset overflows u64: base_offset={base_offset} batch_offset={batch_offset}"))?;
if pos.as_usize() > Self::MAX_SUPPORTED_POS {
if pos.into_usize() > Self::MAX_SUPPORTED_POS {
anyhow::bail!(
"base_offset+batch_offset exceeds the maximum supported value: base_offset={base_offset} batch_offset={batch_offset} (+)={pos} max={max}",
max = Self::MAX_SUPPORTED_POS
@@ -189,7 +189,7 @@ impl InMemoryLayerIndexValue {
let mut data: u64 = 0;
use bit_field::BitField;
data.set_bits(Self::WILL_INIT_RANGE, if will_init { 1 } else { 0 });
data.set_bits(Self::LEN_RANGE, len.as_u64());
data.set_bits(Self::LEN_RANGE, len.into_u64());
data.set_bits(Self::POS_RANGE, pos);
Ok(Self(data))
@@ -658,7 +658,7 @@ impl InMemoryLayer {
value: InMemoryLayerIndexValue::new(InMemoryLayerIndexValueNewArgs {
base_offset,
batch_offset: pos,
len: len.as_usize(),
len: len.into_usize(),
will_init,
})?,
})
@@ -669,7 +669,7 @@ impl InMemoryLayer {
inner.file.write_raw(&serialized_batch.raw, ctx).await?;
let new_size = inner.file.len();
let expected_new_len = base_offset
.checked_add(serialized_batch.raw.len().as_u64())
.checked_add(serialized_batch.raw.len().into_u64())
// write_raw would error if we were to overflow u64.
// also InMemoryLayerIndexValue and higher levels in
//the code don't allow the file to grow that large
@@ -870,13 +870,13 @@ mod tests {
for will_init in [true, false] {
let expect = Unpacked {
will_init,
len: len.as_u64(),
pos: pos.as_u64(),
len: len.into_u64(),
pos: pos.into_u64(),
};
roundtrip(
Args {
will_init,
base_offset: pos.as_u64(),
base_offset: pos.into_u64(),
batch_offset: 0,
len,
},
@@ -886,7 +886,7 @@ mod tests {
Args {
will_init,
base_offset: 0,
batch_offset: pos.as_u64(),
batch_offset: pos.into_u64(),
len,
},
expect,
@@ -909,7 +909,7 @@ mod tests {
let too_large = Args {
will_init: false,
len: 0,
base_offset: MAX_SUPPORTED_POS.as_u64() + 1,
base_offset: MAX_SUPPORTED_POS.into_u64() + 1,
batch_offset: 0,
};
assert!(InMemoryLayerIndexValue::new(too_large).is_err());
@@ -917,7 +917,7 @@ mod tests {
will_init: false,
len: 0,
base_offset: 0,
batch_offset: MAX_SUPPORTED_POS.as_u64() + 1,
batch_offset: MAX_SUPPORTED_POS.into_u64() + 1,
};
assert!(InMemoryLayerIndexValue::new(too_large).is_err());
}
@@ -927,15 +927,15 @@ mod tests {
let too_large = Args {
will_init: false,
len: 0,
base_offset: MAX_SUPPORTED_POS.as_u64(),
base_offset: MAX_SUPPORTED_POS.into_u64(),
batch_offset: 1,
};
assert!(InMemoryLayerIndexValue::new(too_large).is_err());
let too_large = Args {
will_init: false,
len: 0,
base_offset: MAX_SUPPORTED_POS.as_u64() - 1,
batch_offset: MAX_SUPPORTED_POS.as_u64() - 1,
base_offset: MAX_SUPPORTED_POS.into_u64() - 1,
batch_offset: MAX_SUPPORTED_POS.into_u64() - 1,
};
assert!(InMemoryLayerIndexValue::new(too_large).is_err());
}
@@ -947,13 +947,13 @@ mod tests {
Args {
will_init: false,
len,
base_offset: MAX_SUPPORTED_POS.as_u64(),
base_offset: MAX_SUPPORTED_POS.into_u64(),
batch_offset: 0,
},
Unpacked {
will_init: false,
len: len as u64,
pos: MAX_SUPPORTED_POS.as_u64(),
pos: MAX_SUPPORTED_POS.into_u64(),
},
);
roundtrip(
@@ -961,12 +961,12 @@ mod tests {
will_init: false,
len,
base_offset: 0,
batch_offset: MAX_SUPPORTED_POS.as_u64(),
batch_offset: MAX_SUPPORTED_POS.into_u64(),
},
Unpacked {
will_init: false,
len: len as u64,
pos: MAX_SUPPORTED_POS.as_u64(),
pos: MAX_SUPPORTED_POS.into_u64(),
},
);
}

View File

@@ -5,24 +5,26 @@ pub(crate) const _ASSERT_U64_EQ_USIZE: () = {
};
pub(crate) trait U64IsUsize {
fn as_usize(self) -> usize;
fn into_usize(self) -> usize;
}
impl U64IsUsize for u64 {
#[inline(always)]
fn as_usize(self) -> usize {
fn into_usize(self) -> usize {
#[allow(clippy::let_unit_value)]
let _ = _ASSERT_U64_EQ_USIZE;
self as usize
}
}
pub(crate) trait UsizeIsU64 {
fn as_u64(self) -> u64;
fn into_u64(self) -> u64;
}
impl UsizeIsU64 for usize {
#[inline(always)]
fn as_u64(self) -> u64 {
fn into_u64(self) -> u64 {
#[allow(clippy::let_unit_value)]
let _ = _ASSERT_U64_EQ_USIZE;
self as u64
}

View File

@@ -132,14 +132,14 @@ where
// plan which chunks we need to read from
let mut remaining = req_len;
let mut chunk_no = *pos / (DIO_CHUNK_SIZE.as_u64());
let mut offset_in_chunk = pos.as_usize() % DIO_CHUNK_SIZE;
let mut chunk_no = *pos / (DIO_CHUNK_SIZE.into_u64());
let mut offset_in_chunk = pos.into_usize() % DIO_CHUNK_SIZE;
while remaining > 0 {
let remaining_in_chunk = std::cmp::min(remaining, DIO_CHUNK_SIZE - offset_in_chunk);
by_chunk.entry(chunk_no).or_default().push(Interest {
logical_read,
offset_in_chunk: offset_in_chunk.as_u64(),
len: remaining_in_chunk.as_u64(),
offset_in_chunk: offset_in_chunk.into_u64(),
len: remaining_in_chunk.into_u64(),
});
offset_in_chunk = 0;
chunk_no += 1;
@@ -196,7 +196,7 @@ where
offset_in_physical_read: i
.checked_mul(DIO_CHUNK_SIZE)
.unwrap()
.as_u64()
.into_u64()
+ offset_in_chunk,
len,
}
@@ -228,7 +228,7 @@ where
continue;
}
let read_offset = start_chunk_no
.checked_mul(DIO_CHUNK_SIZE.as_u64())
.checked_mul(DIO_CHUNK_SIZE.into_u64())
.expect("we produce chunk_nos by dividing by DIO_CHUNK_SIZE earlier");
let io_buf = get_io_buffer(nchunks).slice_full();
let req_len = io_buf.len();
@@ -540,7 +540,7 @@ mod tests {
async fn test_blackbox() {
let ctx = RequestContext::new(TaskKind::UnitTest, DownloadBehavior::Error);
let cs = DIO_CHUNK_SIZE;
let cs_u64 = cs.as_u64();
let cs_u64 = cs.into_u64();
let file = InMemoryFile::new_random(10 * cs);
@@ -623,8 +623,8 @@ mod tests {
let file = InMemoryFile::new_random(2 * DIO_CHUNK_SIZE);
let a = file.test_logical_read(DIO_CHUNK_SIZE.as_u64(), 10);
let b = file.test_logical_read(DIO_CHUNK_SIZE.as_u64() + 30, 20);
let a = file.test_logical_read(DIO_CHUNK_SIZE.into_u64(), 10);
let b = file.test_logical_read(DIO_CHUNK_SIZE.into_u64() + 30, 20);
let recorder = RecorderFile::new(&file);
@@ -633,7 +633,7 @@ mod tests {
let recorded = recorder.recorded.borrow();
assert_eq!(recorded.len(), 1);
let RecordedRead { pos, req_len, .. } = &recorded[0];
assert_eq!(*pos, DIO_CHUNK_SIZE.as_u64());
assert_eq!(*pos, DIO_CHUNK_SIZE.into_u64());
assert_eq!(*req_len, DIO_CHUNK_SIZE);
}
@@ -649,7 +649,7 @@ mod tests {
let mut test_logical_reads = Vec::new();
for i in 3..3 + MAX_CHUNK_BATCH_SIZE + MAX_CHUNK_BATCH_SIZE / 2 {
test_logical_reads
.push(file.test_logical_read(i.as_u64() * DIO_CHUNK_SIZE.as_u64() + 10, 1));
.push(file.test_logical_read(i.into_u64() * DIO_CHUNK_SIZE.into_u64() + 10, 1));
}
let recorder = RecorderFile::new(&file);
@@ -678,7 +678,7 @@ mod tests {
let file = InMemoryFile::new_random(3 * DIO_CHUNK_SIZE);
let a = file.test_logical_read(0, 1); // chunk 0
let b = file.test_logical_read(2 * DIO_CHUNK_SIZE.as_u64(), 1); // chunk 2
let b = file.test_logical_read(2 * DIO_CHUNK_SIZE.into_u64(), 1); // chunk 2
let recorder = RecorderFile::new(&file);
@@ -694,7 +694,7 @@ mod tests {
}
{
let RecordedRead { pos, req_len, .. } = &recorded[1];
assert_eq!(*pos, 2 * DIO_CHUNK_SIZE.as_u64());
assert_eq!(*pos, 2 * DIO_CHUNK_SIZE.into_u64());
assert_eq!(*req_len, DIO_CHUNK_SIZE);
}
}
@@ -814,19 +814,21 @@ mod tests {
let test_logical_reads = vec![
// read spanning two batches
TestLogicalRead::new(
DIO_CHUNK_SIZE.as_u64() / 2,
DIO_CHUNK_SIZE.into_u64() / 2,
MAX_CHUNK_BATCH_SIZE * DIO_CHUNK_SIZE,
Err("foo".to_owned()),
),
// second read in failing chunk
TestLogicalRead::new(
(MAX_CHUNK_BATCH_SIZE * DIO_CHUNK_SIZE).as_u64() + DIO_CHUNK_SIZE.as_u64() - 10,
(MAX_CHUNK_BATCH_SIZE * DIO_CHUNK_SIZE).into_u64() + DIO_CHUNK_SIZE.into_u64() - 10,
5,
Err("foo".to_owned()),
),
// read unaffected
TestLogicalRead::new(
(MAX_CHUNK_BATCH_SIZE * DIO_CHUNK_SIZE).as_u64() + 2 * DIO_CHUNK_SIZE.as_u64() + 10,
(MAX_CHUNK_BATCH_SIZE * DIO_CHUNK_SIZE).into_u64()
+ 2 * DIO_CHUNK_SIZE.into_u64()
+ 10,
5,
Ok(vec![1; 5]),
),
@@ -837,8 +839,8 @@ mod tests {
for test_logical_reads in test_logical_read_perms {
let file = mock_file!(
0, MAX_CHUNK_BATCH_SIZE*DIO_CHUNK_SIZE => Ok(vec![0; MAX_CHUNK_BATCH_SIZE*DIO_CHUNK_SIZE]),
(MAX_CHUNK_BATCH_SIZE*DIO_CHUNK_SIZE).as_u64(), DIO_CHUNK_SIZE => Err("foo".to_owned()),
(MAX_CHUNK_BATCH_SIZE*DIO_CHUNK_SIZE + 2*DIO_CHUNK_SIZE).as_u64(), DIO_CHUNK_SIZE => Ok(vec![1; DIO_CHUNK_SIZE]),
(MAX_CHUNK_BATCH_SIZE*DIO_CHUNK_SIZE).into_u64(), DIO_CHUNK_SIZE => Err("foo".to_owned()),
(MAX_CHUNK_BATCH_SIZE*DIO_CHUNK_SIZE + 2*DIO_CHUNK_SIZE).into_u64(), DIO_CHUNK_SIZE => Ok(vec![1; DIO_CHUNK_SIZE]),
);
execute_and_validate_test_logical_reads(&file, test_logical_reads, &ctx).await;
}
@@ -852,7 +854,7 @@ mod tests {
fn setup_short_chunk_read_tests() -> TestShortReadsSetup {
let ctx = RequestContext::new(TaskKind::UnitTest, DownloadBehavior::Error);
assert!(DIO_CHUNK_SIZE > 20, "test assumption");
let written = (2 * DIO_CHUNK_SIZE - 10).as_u64();
let written = (2 * DIO_CHUNK_SIZE - 10).into_u64();
let file = InMemoryFile::new_random(written as usize);
TestShortReadsSetup { ctx, file, written }
}
@@ -874,7 +876,7 @@ mod tests {
let recorded = recorder.recorded.borrow();
assert_eq!(recorded.len(), 1);
let RecordedRead { pos, req_len, res } = &recorded[0];
assert_eq!(*pos, DIO_CHUNK_SIZE.as_u64());
assert_eq!(*pos, DIO_CHUNK_SIZE.into_u64());
assert_eq!(*req_len, DIO_CHUNK_SIZE);
assert_eq!(res, &file.content[DIO_CHUNK_SIZE..(written as usize)]);
}
@@ -911,7 +913,7 @@ mod tests {
let recorded = recorder.recorded.borrow();
assert_eq!(recorded.len(), 1);
let RecordedRead { pos, req_len, res } = &recorded[0];
assert_eq!(*pos, DIO_CHUNK_SIZE.as_u64());
assert_eq!(*pos, DIO_CHUNK_SIZE.into_u64());
assert_eq!(*req_len, DIO_CHUNK_SIZE);
assert_eq!(res, &file.content[DIO_CHUNK_SIZE..(written as usize)]);
}