mirror of
https://github.com/localsend/localsend.git
synced 2026-08-07 07:14:52 +00:00
perf: increase buffer size
This commit is contained in:
@@ -3,7 +3,7 @@ use sha2::{Digest, Sha256};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
/// Buffer size used when hashing a file chunk by chunk.
|
||||
const HASH_BUFFER_SIZE: usize = 64 * 1024;
|
||||
const HASH_BUFFER_SIZE: usize = 512 * 1024;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum HashError {
|
||||
|
||||
@@ -10,6 +10,10 @@ use tokio::sync::{mpsc, oneshot};
|
||||
/// Channel capacity for file upload chunks (provides backpressure).
|
||||
const UPLOAD_CHANNEL_CAPACITY: usize = 16;
|
||||
|
||||
/// Size of the write buffer that coalesces incoming body chunks (typically one
|
||||
/// TLS record, ~16 KiB) into larger file writes.
|
||||
const WRITE_BUFFER_SIZE: usize = 512 * 1024;
|
||||
|
||||
/// Where the content of an uploaded file should go, decided by the application.
|
||||
#[derive(Debug)]
|
||||
pub enum FileUploadTarget {
|
||||
@@ -286,7 +290,7 @@ async fn write_file_from_receiver(
|
||||
) -> Result<(), String> {
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
let mut file = open.await?;
|
||||
let mut file = tokio::io::BufWriter::with_capacity(WRITE_BUFFER_SIZE, open.await?);
|
||||
let mut written: u64 = 0;
|
||||
while let Some(chunk) = rx.recv().await {
|
||||
written += chunk.len() as u64;
|
||||
@@ -306,6 +310,7 @@ async fn write_file_from_receiver(
|
||||
file.flush()
|
||||
.await
|
||||
.map_err(|e| format!("Failed to flush file: {e}"))?;
|
||||
let file = file.into_inner();
|
||||
|
||||
if written != expected_size {
|
||||
return Err(format!(
|
||||
|
||||
@@ -6,6 +6,9 @@ use tokio::sync::mpsc;
|
||||
/// Channel capacity used when normalizing a file-backed [`FileContent`] into a stream.
|
||||
const FILE_CHANNEL_CAPACITY: usize = 16;
|
||||
|
||||
/// Buffer size used when reading a file into chunks.
|
||||
const READ_BUFFER_SIZE: usize = 512 * 1024;
|
||||
|
||||
/// The binary content of a file provided by the application for a transfer.
|
||||
///
|
||||
/// Shared by the HTTP client (upload) and server (download API) so both can
|
||||
@@ -73,9 +76,12 @@ impl FileContent {
|
||||
async fn read_file_into_sender(mut file: tokio::fs::File, tx: mpsc::Sender<Bytes>) {
|
||||
use tokio::io::AsyncReadExt;
|
||||
|
||||
let mut buffer = bytes::BytesMut::with_capacity(64 * 1024);
|
||||
let mut buffer = bytes::BytesMut::new();
|
||||
let mut total: u64 = 0;
|
||||
loop {
|
||||
// Re-reserve every iteration: `split()` hands the filled part off, which
|
||||
// can leave little spare capacity for the next read.
|
||||
buffer.reserve(READ_BUFFER_SIZE);
|
||||
match file.read_buf(&mut buffer).await {
|
||||
Ok(0) => break,
|
||||
Ok(n) => {
|
||||
|
||||
@@ -28,7 +28,7 @@ async fn hash_file_from_path() {
|
||||
/// reporting the cumulative progress after each of them.
|
||||
#[tokio::test]
|
||||
async fn hash_large_file_from_path() {
|
||||
let content: Vec<u8> = (0..500_000).map(|i| (i % 251) as u8).collect();
|
||||
let content: Vec<u8> = (0..2_000_000).map(|i| (i % 251) as u8).collect();
|
||||
let path = std::env::temp_dir().join(format!("localsend-hash-{}", uuid::Uuid::new_v4()));
|
||||
tokio::fs::write(&path, &content).await.unwrap();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user