namespace Dpz.Core.Service.ObjectStorage;

/// <summary>
/// COS 空目录 marker 清理计划计算器
/// </summary>
internal static class S3DirectoryCleanupPlanner
{
    public static S3DirectoryCleanupPlan BuildPlan(IEnumerable<S3ListedObject> objects)
    {
        var directoryMarkers = new List<string>();
        var occupiedDirectories = new HashSet<string>(StringComparer.Ordinal);
        var scannedObjectCount = 0;

        foreach (var item in objects)
        {
            if (string.IsNullOrWhiteSpace(item.Key))
            {
                continue;
            }

            scannedObjectCount++;
            if (item.Size == 0 && item.Key.EndsWith('/'))
            {
                directoryMarkers.Add(item.Key);
                continue;
            }

            var slashIndex = item.Key.IndexOf('/');
            while (slashIndex >= 0)
            {
                occupiedDirectories.Add(item.Key[..(slashIndex + 1)]);
                slashIndex = item.Key.IndexOf('/', slashIndex + 1);
            }
        }

        var emptyDirectoryMarkers = directoryMarkers
            .Where(key => !occupiedDirectories.Contains(key))
            .ToList();
        return new S3DirectoryCleanupPlan(
            emptyDirectoryMarkers,
            scannedObjectCount,
            directoryMarkers.Count
        );
    }
}

internal readonly record struct S3ListedObject(string Key, long Size);

internal sealed record S3DirectoryCleanupPlan(
    IReadOnlyList<string> EmptyDirectoryMarkers,
    int ScannedObjectCount,
    int CandidateMarkerCount
);
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个用于在 S3(或兼容 COS)对象存储中识别和清理空目录标记的工具类。

核心组件

1. S3DirectoryCleanupPlanner(静态类)

主要的计划生成器,包含一个静态方法 BuildPlan

2. BuildPlan 方法逻辑

该方法接收 S3 对象列表,分析并生成清理计划:

public static S3DirectoryCleanupPlan BuildPlan(IEnumerable<S3ListedObject> objects)

执行步骤:

  1. 初始化数据结构

    • directoryMarkers: 存储所有目录标记(以 / 结尾且大小为 0 的对象)
    • occupiedDirectories: 存储所有被实际文件占用的目录路径
    • scannedObjectCount: 扫描的对象总数
  2. 遍历所有对象

    • 跳过空键值的对象
    • 统计扫描数量
    • 识别目录标记:大小为 0 且以 / 结尾的对象
    • 提取占用的目录:对于实际文件,提取其所有父目录路径
  3. 路径提取示例

    对于文件 "folder1/folder2/file.txt"
    会提取: "folder1/" 和 "folder1/folder2/"
    
  4. 计算空目录标记

    • 从所有目录标记中排除被占用的目录
    • 剩余的即为空目录标记(可以安全删除)
  5. 返回清理计划

数据模型

S3ListedObject(记录结构体)

internal readonly record struct S3ListedObject(string Key, long Size);
  • 表示 S3 对象的基本信息
  • Key: 对象键(路径)
  • Size: 对象大小(字节)

S3DirectoryCleanupPlan(记录类)

internal sealed record S3DirectoryCleanupPlan(
    IReadOnlyList<string> EmptyDirectoryMarkers,  // 可删除的空目录标记列表
    int ScannedObjectCount,                        // 扫描的对象总数
    int CandidateMarkerCount                       // 发现的目录标记总数
);

应用场景

在 S3/COS 中,目录实际上不存在,但有些工具会创建 0 字节的 "目录标记" 对象。当目录下的文件被删除后,这些标记可能成为 "空目录",此工具可识别并清理它们,优化存储空间和列表性能。

关键特性

  • ✅ 使用 HashSet 提高查找效率
  • ✅ 大小写敏感的路径比较(StringComparer.Ordinal
  • ✅ 使用现代 C# 特性(record、范围运算符 [..]
  • ✅ 只读返回类型保证数据安全
评论加载中...