💾

flutter_cache_managerにおけるキャッシュ件数の仕組み

2023/03/03に公開

はじめに

flutter_cache_manager では以下ののように maxNrOfCacheObjects でキャッシュする件数をカスタマイズすることができるのですが、この値を小さくしても Cache ディレクトリに保存されたファイルが残り続けてしまうため、どんな仕組みでキャッシュを削除しているのか調査しました。

class CustomCacheManager {
  static const key = 'customCacheKey';
  static CacheManager instance = CacheManager(
    Config(
      key,
      stalePeriod: const Duration(days: 7),
      maxNrOfCacheObjects: 20,
      repo: JsonCacheInfoRepository(databaseName: key),
      fileSystem: IOFileSystem(key),
      fileService: HttpFileService(),
    ),
  );
}

なお公式のドキュメントには以下のように記載されており(Google 翻訳で翻訳済み)、キャッシュされたファイルがmaxNrOfCacheObjects で設定した数を超えると削除されるように読み取れます。ちなみに stalePeriodconst Duration(seconds: 3) と設定するとファイルが削除されたため、こちらは想定通りに機能しているようでした。

キャッシュ マネージャーは、maxNrOfCacheObjects と stalePeriod の 2 つの変数を使用してファイルを削除するタイミングを決定します。キャッシュは、ファイルが最後に使用された時期を認識しています。キャッシュを消去するとき (これは継続的に行われます)、ファイルが多すぎる場合、最後に使用された順に並べ替えられた場合、およびファイルが古い期間より長く使用されていない場合、キャッシュはファイルを削除します。

バージョン

flutter_cache_manager: 3.3.0

使用してから 1 日経たないと削除対象にならない

flutter_cache_manager の削除対象を取得している部分のソースコードは以下のようになっていました。 capacity には maxNrOfCacheObjects で指定した値が入ります。

Future<List<CacheObject>> getObjectsOverCapacity(int capacity) async {
  return CacheObject.fromMapList(await db!.query(
    _tableCacheObject,
    columns: null,
    orderBy: '${CacheObject.columnTouched} DESC',
    where: '${CacheObject.columnTouched} < ?',
    whereArgs: [
      DateTime.now().subtract(const Duration(days: 1)).millisecondsSinceEpoch
    ],
    limit: 100,
    offset: capacity,
  ));
}

取得条件が

where: '${CacheObject.columnTouched} < ?',
whereArgs: [
  DateTime.now().subtract(const Duration(days: 1)).millisecondsSinceEpoch
],

となっており、どうやら 1 日以上使用していないキャッシュが削除対象になるようです。maxNrOfCacheObjects に小さな値を設定しても消えなかったのはこの条件に当てはまらなかったからのようです。

Discussion