Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion flutter_cache_manager/lib/src/cache_store.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class CacheStore {

Duration get _maxAge => _config.stalePeriod;

Duration get _maxCapacityAgeFilterDuration => _config.maxCapacityAgeFilterDuration ?? const Duration(days: 1);

DateTime lastCleanupRun = DateTime.now();
Timer? _scheduledCleanup;

Expand Down Expand Up @@ -136,7 +138,7 @@ class CacheStore {
final toRemove = <int>[];
final provider = await _cacheInfoRepository;

final overCapacity = await provider.getObjectsOverCapacity(_capacity);
final overCapacity = await provider.getObjectsOverCapacity(_capacity, maxAge: _maxCapacityAgeFilterDuration);
for (final cacheObject in overCapacity) {
_removeCachedFile(cacheObject, toRemove);
}
Expand Down
5 changes: 5 additions & 0 deletions flutter_cache_manager/lib/src/config/_config_unsupported.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ class Config implements def.Config {
FileSystem? fileSystem,
//ignore: avoid_unused_constructor_parameters
FileService? fileService,
//ignore: avoid_unused_constructor_parameters
Duration? maxCapacityAgeFilterDuration,
}) {
throw UnsupportedError('Platform is not supported');
}
Expand All @@ -39,4 +41,7 @@ class Config implements def.Config {

@override
FileService get fileService => throw UnimplementedError();

@override
Duration? get maxCapacityAgeFilterDuration => throw UnimplementedError();
}
3 changes: 3 additions & 0 deletions flutter_cache_manager/lib/src/config/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ abstract class Config {
CacheInfoRepository repo,
FileSystem fileSystem,
FileService fileService,
Duration? maxCapacityAgeFilterDuration,
}) = impl.Config;

String get cacheKey;
Expand All @@ -40,4 +41,6 @@ abstract class Config {
FileSystem get fileSystem;

FileService get fileService;

Duration? get maxCapacityAgeFilterDuration;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ abstract class CacheInfoRepository {
/// Gets the list of [CacheObject] that can be removed if the repository is over capacity.
///
/// The exact implementation is up to the repository, but implementations should
/// return a preferred list of items. For example, the least recently accessed
Future<List<CacheObject>> getObjectsOverCapacity(int capacity);
/// return a preferred list of items. For example, the least recently accessed.
/// [maxAge] filters objects older than the given duration (defaults to 1 day).
Future<List<CacheObject>> getObjectsOverCapacity(int capacity, {Duration? maxAge});

/// Returns a list of [CacheObject] that are older than [maxAge]
Future<List<CacheObject>> getOldObjects(Duration maxAge);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,14 @@ class CacheObjectProvider extends CacheInfoRepository
}

@override
Future<List<CacheObject>> getObjectsOverCapacity(int capacity) async {
Future<List<CacheObject>> getObjectsOverCapacity(int capacity, {Duration? maxAge}) 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
DateTime.now().subtract(maxAge ?? const Duration(days: 1)).millisecondsSinceEpoch
],
limit: 100,
offset: capacity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,14 @@ class JsonCacheInfoRepository extends CacheInfoRepository
}

@override
Future<List<CacheObject>> getObjectsOverCapacity(int capacity) async {
final allSorted = _cacheObjects.values.toList()
Future<List<CacheObject>> getObjectsOverCapacity(int capacity, {Duration? maxAge}) async {
final threshold = DateTime.now().subtract(maxAge ?? const Duration(days: 1));
final filtered = _cacheObjects.values
.where((c) => c.touched!.isBefore(threshold))
.toList()
..sort((c1, c2) => c1.touched!.compareTo(c2.touched!));
if (allSorted.length <= capacity) return [];
return allSorted.getRange(0, allSorted.length - capacity).toList();
if (filtered.length <= capacity) return [];
return filtered.getRange(0, filtered.length - capacity).toList();
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class NonStoringObjectProvider implements CacheInfoRepository {
}

@override
Future<List<CacheObject>> getObjectsOverCapacity(int capacity) {
Future<List<CacheObject>> getObjectsOverCapacity(int capacity, {Duration? maxAge}) {
return Future.value([]);
}

Expand Down
67 changes: 36 additions & 31 deletions flutter_cache_manager/test/mock.mocks.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Mocks generated by Mockito 5.4.4 from annotations
// Mocks generated by Mockito 5.4.6 from annotations
// in flutter_cache_manager/test/mock.dart.
// Do not manually edit this file.

Expand All @@ -20,10 +20,12 @@ import 'package:mockito/src/dummies.dart' as _i6;
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: must_be_immutable
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
// ignore_for_file: invalid_use_of_internal_member

class _FakeCacheObject_0 extends _i1.SmartFake implements _i2.CacheObject {
_FakeCacheObject_0(
Expand Down Expand Up @@ -196,11 +198,15 @@ class MockCacheInfoRepositoryBase extends _i1.Mock
) as _i4.Future<List<_i2.CacheObject>>);

@override
_i4.Future<List<_i2.CacheObject>> getObjectsOverCapacity(int? capacity) =>
_i4.Future<List<_i2.CacheObject>> getObjectsOverCapacity(
int? capacity, {
Duration? maxAge,
}) =>
(super.noSuchMethod(
Invocation.method(
#getObjectsOverCapacity,
[capacity],
{#maxAge: maxAge},
),
returnValue:
_i4.Future<List<_i2.CacheObject>>.value(<_i2.CacheObject>[]),
Expand Down Expand Up @@ -254,16 +260,6 @@ class MockCacheStoreBase extends _i1.Mock implements _i5.CacheStore {
),
) as Duration);

@override
set cleanupRunMinInterval(Duration? _cleanupRunMinInterval) =>
super.noSuchMethod(
Invocation.setter(
#cleanupRunMinInterval,
_cleanupRunMinInterval,
),
returnValueForMissingStub: null,
);

@override
_i3.FileSystem get fileSystem => (super.noSuchMethod(
Invocation.getter(#fileSystem),
Expand All @@ -274,13 +270,13 @@ class MockCacheStoreBase extends _i1.Mock implements _i5.CacheStore {
) as _i3.FileSystem);

@override
set fileSystem(_i3.FileSystem? _fileSystem) => super.noSuchMethod(
Invocation.setter(
#fileSystem,
_fileSystem,
String get storeKey => (super.noSuchMethod(
Invocation.getter(#storeKey),
returnValue: _i6.dummyValue<String>(
this,
Invocation.getter(#storeKey),
),
returnValueForMissingStub: null,
);
) as String);

@override
DateTime get lastCleanupRun => (super.noSuchMethod(
Expand All @@ -292,22 +288,31 @@ class MockCacheStoreBase extends _i1.Mock implements _i5.CacheStore {
) as DateTime);

@override
set lastCleanupRun(DateTime? _lastCleanupRun) => super.noSuchMethod(
set cleanupRunMinInterval(Duration? value) => super.noSuchMethod(
Invocation.setter(
#lastCleanupRun,
_lastCleanupRun,
#cleanupRunMinInterval,
value,
),
returnValueForMissingStub: null,
);

@override
String get storeKey => (super.noSuchMethod(
Invocation.getter(#storeKey),
returnValue: _i6.dummyValue<String>(
this,
Invocation.getter(#storeKey),
set fileSystem(_i3.FileSystem? value) => super.noSuchMethod(
Invocation.setter(
#fileSystem,
value,
),
) as String);
returnValueForMissingStub: null,
);

@override
set lastCleanupRun(DateTime? value) => super.noSuchMethod(
Invocation.setter(
#lastCleanupRun,
value,
),
returnValueForMissingStub: null,
);

@override
_i4.Future<_i3.FileInfo?> getFile(
Expand Down Expand Up @@ -431,10 +436,10 @@ class MockFileServiceBase extends _i1.Mock implements _i3.FileService {
) as int);

@override
set concurrentFetches(int? _concurrentFetches) => super.noSuchMethod(
set concurrentFetches(int? value) => super.noSuchMethod(
Invocation.setter(
#concurrentFetches,
_concurrentFetches,
value,
),
returnValueForMissingStub: null,
);
Expand Down Expand Up @@ -486,10 +491,10 @@ class MockWebHelper extends _i1.Mock implements _i7.WebHelper {
) as int);

@override
set concurrentCalls(int? _concurrentCalls) => super.noSuchMethod(
set concurrentCalls(int? value) => super.noSuchMethod(
Invocation.setter(
#concurrentCalls,
_concurrentCalls,
value,
),
returnValueForMissingStub: null,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ void main() {

test('getObjectsOverCapacity should return oldest objects', () async {
var repo = await JsonRepoHelpers.createRepository();
var result = await repo.getObjectsOverCapacity(1);
var result = await repo.getObjectsOverCapacity(1, maxAge: Duration.zero);
expect(result.length, 2);
expectIdInList(result, 1);
expectIdInList(result, 3);
Expand Down