Repository: qdrant/qdrant
File: lib/common/common/src/disk.rs (Rust)

Code before:
use std::path::{Path, PathBuf};

use walkdir::WalkDir;

/// How many bytes a directory takes.
pub fn dir_size(path: impl Into<PathBuf>) -> std::io::Result<u64> {
    fn dir_size(mut dir: std::fs::ReadDir) -> std::io::Result<u64> {
        dir.try_fold(0, |acc, file| {
            let file = file?;
            let size = match file.metadata()? {
                data if data.is_dir() => dir_size(std::fs::read_dir(file.path())?)?,
                data => data.len(),
            };
            Ok(acc + size)
        })
    }

    dir_size(std::fs::read_dir(path.into())?)
}

const BLOCK_SIZE: u64 = 512; // 512 bytes per block, aka DEV_BSIZE

/// How many bytes a directory takes on disk.
/// Notes:
/// - on non-unix systems, this is the same as `dir_size`
pub fn dir_disk_size(path: impl Into<PathBuf>) -> std::io::Result<u64> {
    fn dir_disk_size(mut dir: std::fs::ReadDir) -> std::io::Result<u64> {
        dir.try_fold(0, |acc, file| {
            let file = file?;
            let metadata = file.metadata()?;
            let size = if metadata.is_dir() {
                dir_disk_size(std::fs::read_dir(file.path())?)?
            } else {
                #[cfg(unix)]
                {
                    use std::os::unix::fs::MetadataExt;
                    metadata.blocks() * BLOCK_SIZE
                }
                #[cfg(not(unix))]
                {
                    metadata.len()
                }
            };
            Ok(acc + size)
        })
    }

Review comment (suggestion):
Should be under `#[cfg(unix)]` (or moved into the same code block as call to `metadata.blocks()`), otherwise it produces a warning on Windows. (and our CI doesn't catch it)

https://github.com/qdrant/qdrant/actions/runs/17166548660/job/48708117198?pr=7120#step:9:42

```
warning: constant `BLOCK_SIZE` is never used
  --> lib\common\common\src\disk.rs:21:7
   |
21 | const BLOCK_SIZE: u64 = 512; // 512 bytes per block, aka DEV_BSIZE
   |       ^^^^^^^^^^
   |
   = note: `#[warn(dead_code)]` on by default
```



Code after:
use std::path::{Path, PathBuf};

use walkdir::WalkDir;

/// How many bytes a directory takes on disk.
///
/// Note: on non-unix systems, this function returns the apparent/logical
/// directory size rather than actual disk usage.
pub fn dir_disk_size(path: impl Into<PathBuf>) -> std::io::Result<u64> {
    fn dir_disk_size(mut dir: std::fs::ReadDir) -> std::io::Result<u64> {
        dir.try_fold(0, |acc, file| {
            let file = file?;
            let metadata = file.metadata()?;
            let size = if metadata.is_dir() {
                dir_disk_size(std::fs::read_dir(file.path())?)?
            } else {
                #[cfg(unix)]
                {
                    const BLOCK_SIZE: u64 = 512; // aka DEV_BSIZE
                    use std::os::unix::fs::MetadataExt;
                    metadata.blocks() * BLOCK_SIZE
                }
                #[cfg(not(unix))]
                {
                    metadata.len()
                }
            };
            Ok(acc + size)
        })
    }

    dir_disk_size(std::fs::read_dir(path.into())?)
}

/// List all files in the given directory recursively.
///
/// Notes:
/// - a directory must be given
/// - symlinks are considered to be files
pub fn list_files(dir: impl AsRef<Path>) -> std::io::Result<Vec<PathBuf>> {
    let dir = dir.as_ref();
    if !dir.is_dir() {
        return Ok(vec![]);
    }

    let mut files = Vec::new();