trimCacheByLRU static method

Future<int> trimCacheByLRU({
  1. required String currentClassId,
  2. int maxNonCurrent = 1,
})

LRU 淘汰:保留当前课堂 + 最多 maxNonCurrent 个最近访问的课堂;跳过带 success.json 的离线包。 仅清理 .last_access 命中的自动缓存课堂;用户主动下载的离线包不受影响。

Implementation

static Future<int> trimCacheByLRU({
  required String currentClassId,
  int maxNonCurrent = 1,
}) async {
  final ctl = PlayBackController();
  final cacheDir = await ctl._ensureCacheDir();
  if (!await cacheDir.exists()) return 0;
  final currentSafe = ctl._safeId(currentClassId.trim());
  final entries = <({String safeId, DateTime ts})>[];
  await for (final e in cacheDir.list(followLinks: false)) {
    if (e is! Directory) continue;
    final safeId = p.basename(e.path);
    if (safeId == currentSafe) continue;
    // 跳过用户主动下载的离线包
    if (await File(p.join(e.path, '$safeId-success.json')).exists()) continue;
    final la = File(p.join(e.path, '.last_access'));
    if (!await la.exists()) continue;
    try {
      final s = (await la.readAsString()).trim();
      final ts = DateTime.parse(s);
      entries.add((safeId: safeId, ts: ts));
    } catch (_) {}
  }
  // 最早的在前面
  entries.sort((a, b) => a.ts.compareTo(b.ts));
  final toDelete = entries.length - maxNonCurrent;
  if (toDelete <= 0) return 0;
  var deleted = 0;
  for (var i = 0; i < toDelete; i++) {
    try {
      await Directory(p.join(cacheDir.path, entries[i].safeId)).delete(
        recursive: true,
      );
      deleted++;
    } catch (_) {}
  }
  return deleted;
}