DataCacheX
A versatile and extensible caching library for Dart and Flutter applications
π Overview
DataCacheX is a powerful caching solution designed to simplify data management in your Dart and Flutter applications. It provides a flexible and efficient way to store and retrieve data with support for multiple storage backends, advanced caching policies, and comprehensive analytics.
Why Choose DataCacheX?
- Multiple Storage Options: Choose from memory, Hive, SQLite, or SharedPreferences adapters
- Flexible Caching Policies: Configure expiry, compression, encryption, and priority
- Memory Management: Automatic cleanup and multiple eviction strategies
- Performance Analytics: Track cache performance with built-in metrics
- Type Safety: Full support for generic types and complex data structures
- Extensibility: Easy to extend with custom adapters and serializers
π Installation
Add data_cache_x
to your pubspec.yaml
file:
dependencies:
data_cache_x: ^latest_version
Then run:
flutter pub get
π§ Quick Start
Initialize the Package
import 'package:data_cache_x/data_cache_x.dart';
import 'package:data_cache_x/service_locator.dart';
Future<void> main() async {
// Initialize with default settings (Hive adapter)
await setupDataCacheX();
// Get the DataCacheX instance
final dataCache = getIt<DataCacheX>();
// Start using the cache
await dataCache.put('greeting', 'Hello, World!');
final value = await dataCache.get<String>('greeting');
print(value); // Output: Hello, World!
}
Choose a Different Adapter
// Use memory adapter (volatile, but fast)
await setupDataCacheX(adapterType: CacheAdapterType.memory);
// Use SQLite adapter (persistent, good for larger datasets)
await setupDataCacheX(adapterType: CacheAdapterType.sqlite);
// Use SharedPreferences adapter (persistent, simple key-value storage)
await setupDataCacheX(adapterType: CacheAdapterType.sharedPreferences);
π Core Features
Basic Cache Operations
// Store values with optional expiry
await dataCache.put('user_profile', userProfile,
expiry: Duration(hours: 24));
// Retrieve values with type safety
final profile = await dataCache.get<UserProfile>('user_profile');
// Check if a key exists
final exists = await dataCache.containsKey('user_profile');
// Delete a value
await dataCache.delete('user_profile');
// Clear the entire cache
await dataCache.clear();
Batch Operations
// Store multiple values at once
await dataCache.putAll({
'user': currentUser,
'settings': appSettings,
'theme': currentTheme,
}, expiry: Duration(days: 7));
// Retrieve multiple values
final values = await dataCache.getAll<dynamic>([
'user', 'settings', 'theme'
]);
// Delete multiple values
await dataCache.deleteAll(['user', 'settings', 'theme']);
Advanced Caching Policies
// Create a custom policy
final myPolicy = CachePolicy(
expiry: Duration(hours: 24), // Fixed expiry time
slidingExpiry: Duration(hours: 2), // Extends on each access
staleTime: Duration(minutes: 30), // Time before refresh
priority: CachePriority.high, // Higher priority in eviction
refreshStrategy: RefreshStrategy.backgroundRefresh,
maxSize: 1024 * 10, // 10 KB max size
encrypt: true, // Enable encryption
compression: CompressionMode.auto, // Auto-compress if beneficial
);
// Apply the policy
await dataCache.put('important_data', data, policy: myPolicy);
// Use predefined policies
await dataCache.put('sensitive_data', userData,
policy: CachePolicy.encrypted(expiry: Duration(days: 7)));
await dataCache.put('temp_data', tempData,
policy: CachePolicy.temporary);
await dataCache.put('large_data', largeData,
policy: CachePolicy.compressed());
Auto-Refresh with Callbacks
// Get data with auto-refresh when stale
final userData = await dataCache.get<UserData>('user_data',
refreshCallback: () => fetchUserFromApi(), // Called when data is stale/expired
policy: CachePolicy(
staleTime: Duration(minutes: 5),
refreshStrategy: RefreshStrategy.backgroundRefresh,
),
);
// Multiple items with different refresh callbacks
final data = await dataCache.getAll<dynamic>(['users', 'posts', 'comments'],
refreshCallbacks: {
'users': () => fetchUsersFromApi(),
'posts': () => fetchPostsFromApi(),
'comments': () => fetchCommentsFromApi(),
},
policy: CachePolicy(staleTime: Duration(minutes: 10)),
);
π Advanced Features
Memory Management with Eviction Strategies
// Create a cache with LRU (Least Recently Used) eviction
final lruCache = DataCacheX(
cacheAdapter,
maxSize: 10 * 1024 * 1024, // 10 MB max size
maxItems: 1000, // 1000 items max
evictionStrategy: EvictionStrategy.lru,
);
// Other available strategies
// LFU (Least Frequently Used)
final lfuCache = DataCacheX(
cacheAdapter,
evictionStrategy: EvictionStrategy.lfu,
);
// FIFO (First In, First Out)
final fifoCache = DataCacheX(
cacheAdapter,
evictionStrategy: EvictionStrategy.fifo,
);
// TTL (Time To Live - prioritizes items closest to expiration)
final ttlCache = DataCacheX(
cacheAdapter,
evictionStrategy: EvictionStrategy.ttl,
);
Data Compression
// Create a cache with compression support
final compressedCache = DataCacheX(
cacheAdapter,
compressionLevel: 6, // 1 (fastest) to 9 (most compression)
);
// Auto compression (only compresses if beneficial)
await dataCache.put('large_text', largeString,
policy: CachePolicy(compression: CompressionMode.auto));
// Always compress
await dataCache.put('always_compressed', value,
policy: CachePolicy(compression: CompressionMode.always));
// Never compress
await dataCache.put('never_compressed', value,
policy: CachePolicy(compression: CompressionMode.never));
Cache Analytics
// Get basic metrics
print('Hit rate: ${dataCache.hitRate}%');
print('Total size: ${dataCache.totalSize} bytes');
print('Average item size: ${dataCache.averageItemSize} bytes');
// Get most frequently accessed keys
final topKeys = dataCache.mostFrequentlyAccessedKeys;
for (final entry in topKeys) {
print('${entry.key}: ${entry.value} accesses');
}
// Get largest items
final largestItems = dataCache.largestItems;
for (final entry in largestItems) {
print('${entry.key}: ${entry.value} bytes');
}
// Get complete analytics summary
final summary = dataCache.getAnalyticsSummary();
print(summary);
// Reset metrics
dataCache.resetMetrics();
Background Cleanup
import 'package:data_cache_x/utils/background_cleanup.dart';
// Initialize background cleanup (automatically done by setupDataCacheX)
// But you can manually control it if needed:
BackgroundCleanup.initializeBackgroundCleanup(
adapter: cacheAdapter,
frequency: Duration(hours: 1),
);
// Stop background cleanup
BackgroundCleanup.stopBackgroundCleanup();
// Manually trigger cleanup
BackgroundCleanup.performCleanup(cacheAdapter);
Custom Adapters and Serializers
import 'package:data_cache_x/serializers/data_serializer.dart';
import 'dart:convert';
// Define a custom data type
class UserProfile {
final String name;
final int age;
UserProfile({required this.name, required this.age});
}
// Create a serializer for the custom type
class UserProfileSerializer implements DataSerializer<UserProfile> {
@override
UserProfile fromJson(String json) {
final map = jsonDecode(json);
return UserProfile(name: map['name'], age: map['age']);
}
@override
String toJson(UserProfile value) {
return jsonEncode({'name': value.name, 'age': value.age});
}
}
// Register the custom serializer
await setupDataCacheX(
customSerializers: {
UserProfile: UserProfileSerializer(),
},
);
π§ͺ Example App
The package includes a comprehensive example app (CacheHub) that demonstrates all features:
- News Feed: API caching with different policies
- Image Gallery: Binary data caching for images
- Analytics: Cache performance visualization
- Explorer: Browse and manipulate cached data
- Adapter Playground: Benchmark different adapters
- Settings: Configure cache behavior
To run the example app:
cd example
flutter pub get
flutter run
π API Reference
DataCacheX Class
Method | Description |
---|---|
Future<void> put<T>(String key, T value, {CachePolicy? policy}) |
Stores a value in the cache |
Future<T?> get<T>(String key, {Function? refreshCallback, CachePolicy? policy}) |
Retrieves a value from the cache |
Future<void> delete(String key) |
Deletes a value from the cache |
Future<void> clear() |
Clears the entire cache |
Future<bool> containsKey(String key) |
Checks if a key exists and hasn't expired |
Future<void> putAll(Map<String, dynamic> entries, {CachePolicy? policy}) |
Stores multiple values at once |
Future<Map<String, T?>> getAll<T>(List<String> keys, {Map<String, Function>? refreshCallbacks, CachePolicy? policy}) |
Retrieves multiple values at once |
Future<void> deleteAll(List<String> keys) |
Deletes multiple values at once |
Future<void> invalidate(String key) |
Explicitly invalidates a cache entry |
Future<void> invalidateWhere(bool Function(String, dynamic) test) |
Invalidates entries matching a condition |
Cache Adapters
CacheAdapterType.hive
: Hive NoSQL database (persistent)CacheAdapterType.memory
: In-memory storage (volatile)CacheAdapterType.sqlite
: SQLite database (persistent)CacheAdapterType.sharedPreferences
: SharedPreferences (persistent)
Eviction Strategies
EvictionStrategy.lru
: Least Recently UsedEvictionStrategy.lfu
: Least Frequently UsedEvictionStrategy.fifo
: First In, First OutEvictionStrategy.ttl
: Time To Live (expiry-based)
Cache Priorities
CachePriority.low
: Evicted firstCachePriority.normal
: Default priorityCachePriority.high
: Higher retention priorityCachePriority.critical
: Evicted last
Compression Modes
CompressionMode.auto
: Compress only if beneficialCompressionMode.always
: Always compressCompressionMode.never
: Never compress
π License
This project is licensed under the MIT License - see the LICENSE file for details.
Libraries
- adapters/cache_adapter
- adapters/hive/hive_adapter
- adapters/memory_adapter
- adapters/sqlite/sqlite_adapter
- analytics/cache_analytics
- core/data_cache_x
- core/exception
- data_cache_x
data_cache_x
is a versatile caching library for Dart and Flutter applications. It provides a flexible and extensible way to store and retrieve data, with support for different storage adapters.- models/cache_item
- models/cache_policy
- serializers/data_serializer
- serializers/json_data_serializer
- service_locator
- utils/background_cleanup
- utils/cache_eviction
- utils/compression
- utils/time_helper