quantum_cache 1.0.0 copy "quantum_cache: ^1.0.0" to clipboard
quantum_cache: ^1.0.0 copied to clipboard

A high-performance pure Dart cache with L1 memory + L2 disk layers, offering fast access, adaptive ARC eviction, TTL support, AES-256-GCM encryption, isolate safety, and zero native dependencies.

example/lib/main.dart

// ignore_for_file: avoid_print
import 'package:flutter/material.dart';
import 'package:quantum_cache/quantum_cache.dart';

// ─────────────────────────────────────────────────────────────────────────────
// Custom Model + Adapter
// ─────────────────────────────────────────────────────────────────────────────

/// Example domain model.
class UserProfile {
  const UserProfile({
    required this.id,
    required this.name,
    required this.email,
    required this.age,
    required this.createdAt,
    required this.tags,
  });

  final String id;
  final String name;
  final String email;
  final int age;
  final DateTime createdAt;
  final List<String> tags;

  @override
  String toString() =>
      'UserProfile(id: $id, name: $name, age: $age, tags: $tags)';
}

/// Hand-written adapter (normally generated by quantum_cache_builder).
class UserProfileAdapter extends SuperCacheAdapter<UserProfile> {
  @override
  int get typeId => 1;

  @override
  UserProfile read(BinaryReader reader) {
    return UserProfile(
      id: reader.readString(),
      name: reader.readString(),
      email: reader.readString(),
      age: reader.readInt32(),
      createdAt:
          DateTime.fromMicrosecondsSinceEpoch(reader.readInt64(), isUtc: true),
      tags: List.generate(reader.readUint32(), (_) => reader.readString()),
    );
  }

  @override
  void write(BinaryWriter writer, UserProfile obj) {
    writer
      ..writeString(obj.id)
      ..writeString(obj.name)
      ..writeString(obj.email)
      ..writeInt32(obj.age)
      ..writeInt64(obj.createdAt.microsecondsSinceEpoch)
      ..writeUint32(obj.tags.length);
    for (final tag in obj.tags) {
      writer.writeString(tag);
    }
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// App Entry Point
// ─────────────────────────────────────────────────────────────────────────────

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // ── 1. Register custom adapters BEFORE init ──────────────────────────────
  SuperCache.registerAdapter(UserProfileAdapter());

  // ── 2. Initialize the cache ───────────────────────────────────────────────
  await SuperCache.init(
    config: const CacheConfig(
      maxMemoryEntries: 5000,
      maxMemorySizeBytes: 100 * 1024 * 1024, // 100 MB L1
      maxDiskSizeBytes: 512 * 1024 * 1024,   // 512 MB L2
      defaultTtl: Duration(hours: 24),
      evictionPolicy: EvictionPolicyType.arc,
      writeBufferSize: 200,
      writeBufferFlushInterval: Duration(milliseconds: 300),
      enableStatistics: true,
      enableLogging: true,
      logLevel: CacheLogLevel.info,
    ),
  );

  runApp(const SuperCacheExampleApp());
}

// ─────────────────────────────────────────────────────────────────────────────
// App Widget
// ─────────────────────────────────────────────────────────────────────────────

class SuperCacheExampleApp extends StatelessWidget {
  const SuperCacheExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'quantum_cache Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: const CacheDemoPage(),
    );
  }
}

// ─────────────────────────────────────────────────────────────────────────────
// Demo Page
// ─────────────────────────────────────────────────────────────────────────────

class CacheDemoPage extends StatefulWidget {
  const CacheDemoPage({super.key});

  @override
  State<CacheDemoPage> createState() => _CacheDemoPageState();
}

class _CacheDemoPageState extends State<CacheDemoPage> {
  final _cache = SuperCache.instance;
  final _log = <String>[];

  void _appendLog(String msg) {
    setState(() => _log.insert(0, msg));
  }

  // ── Demo Operations ────────────────────────────────────────────────────────

  Future<void> _demoBasicTypes() async {
    await _cache.put('username', 'Alice');
    await _cache.put('score', 9500);
    await _cache.put('isPremium', true);
    await _cache.put('balance', 3.14159);
    await _cache.put('lastLogin', DateTime.now().toUtc());

    final name = await _cache.get<String>('username');
    final score = await _cache.get<int>('score');
    final premium = await _cache.get<bool>('isPremium');

    _appendLog('📦 Basic types: name=$name, score=$score, premium=$premium');
  }

  Future<void> _demoCustomObject() async {
    final user = UserProfile(
      id: 'u001',
      name: 'Bob Smith',
      email: 'bob@example.com',
      age: 32,
      createdAt: DateTime.now().toUtc(),
      tags: ['admin', 'verified', 'premium'],
    );

    await _cache.put('user:u001', user, ttl: const Duration(hours: 2));
    final loaded = await _cache.get<UserProfile>('user:u001');

    _appendLog('👤 Custom object: ${loaded?.name}, tags: ${loaded?.tags}');
  }

  Future<void> _demoCacheAside() async {
    var loaderCalls = 0;

    final products = await _cache.getOrPut<List<dynamic>>(
      'product_catalog',
      () async {
        loaderCalls++;
        // Simulate network call
        await Future<void>.delayed(const Duration(milliseconds: 100));
        return ['Product A', 'Product B', 'Product C', 'Product D'];
      },
      ttl: const Duration(minutes: 30),
    );

    // Second call — should NOT call loader
    await _cache.getOrPut<List<dynamic>>(
      'product_catalog',
      () async => throw Exception('Loader should not be called!'),
    );

    _appendLog('🗂 Cache-aside: ${products.length} products, '
        'loader called: $loaderCalls time(s)');
  }

  Future<void> _demoBatch() async {
    await _cache.putAll({
      'city:1': 'New York',
      'city:2': 'London',
      'city:3': 'Tokyo',
      'city:4': 'Dubai',
    }, ttl: const Duration(days: 7));

    final cities = await _cache.getAll(['city:1', 'city:2', 'city:3', 'city:4']);
    _appendLog('🌍 Batch get: ${cities.values.join(', ')}');
  }

  Future<void> _demoTtl() async {
    await _cache.put(
      'session_token',
      'tok_abc123xyz',
      ttl: const Duration(seconds: 3),
    );

    final before = await _cache.get<String>('session_token');
    _appendLog('⏳ Token before expiry: $before');

    await Future<void>.delayed(const Duration(seconds: 4));

    final after = await _cache.get<String>('session_token');
    _appendLog('⌛ Token after expiry: $after (null = expired)');
  }

  Future<void> _demoEncryption() async {
    // Generate a key (in production, derive from flutter_secure_storage)
    final key = AesCipher.generateKey();

    await SuperCache.init(
      name: 'secure',
      config: CacheConfig(
        boxName: 'secure_box',
        encryptionKey: key,
        maxMemoryEntries: 100,
      ),
    );

    final secureCache = SuperCache.named('secure');
    await secureCache.put('credit_card', '4111-1111-1111-1111');
    final card = await secureCache.get<String>('credit_card');

    _appendLog('🔐 Encrypted: card ends with ${card?.split('-').last}');
  }

  Future<void> _showStatistics() async {
    final stats = _cache.statistics.snapshot();
    _appendLog(
      '📊 Stats: hitRate=${(stats.hitRate * 100).toStringAsFixed(1)}%, '
      'L1=${stats.l1Hits}, L2=${stats.l2Hits}, '
      'miss=${stats.misses}, writes=${stats.writes}',
    );
  }

  Future<void> _warmUp() async {
    // Pre-seed some data
    for (var i = 0; i < 10; i++) {
      await _cache.put('warmup:$i', 'value_$i', forceSync: true);
    }

    // Simulate L1 being empty (e.g. after app restart — L2 has data)
    _cache.statistics.reset();

    // Warm up L1 from L2
    await _cache.warmUp(List.generate(10, (i) => 'warmup:$i'));
    _appendLog('🔥 Warmed up 10 keys into L1');
  }

  // ─────────────────────────────────────────────────────────────────────────
  // UI
  // ─────────────────────────────────────────────────────────────────────────

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('⚡ quantum_cache Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Column(
        children: [
          // ── Controls ─────────────────────────────────────────────────────
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              _demoButton('📦 Basic Types', _demoBasicTypes),
              _demoButton('👤 Custom Object', _demoCustomObject),
              _demoButton('🗂 Cache-Aside', _demoCacheAside),
              _demoButton('🌍 Batch Ops', _demoBatch),
              _demoButton('⏳ TTL Demo', _demoTtl),
              _demoButton('🔐 Encryption', _demoEncryption),
              _demoButton('📊 Statistics', _showStatistics),
              _demoButton('🔥 Warm-Up', _warmUp),
              _demoButton('🗑 Clear Cache', () async {
                await _cache.clear();
                _appendLog('🗑 Cache cleared');
              }),
            ],
          ),
          const Divider(),
          // ── Log ──────────────────────────────────────────────────────────
          Expanded(
            child: _log.isEmpty
                ? const Center(
                    child: Text(
                      'Tap a button to run a demo',
                      style: TextStyle(color: Colors.grey),
                    ),
                  )
                : ListView.builder(
                    padding: const EdgeInsets.all(12),
                    itemCount: _log.length,
                    itemBuilder: (_, i) => Padding(
                      padding: const EdgeInsets.symmetric(vertical: 4),
                      child: Text(
                        _log[i],
                        style: const TextStyle(
                          fontFamily: 'monospace',
                          fontSize: 13,
                        ),
                      ),
                    ),
                  ),
          ),
        ],
      ),
    );
  }

  Widget _demoButton(String label, Future<void> Function() action) {
    return ElevatedButton(
      onPressed: () async {
        try {
          await action();
        } catch (e) {
          _appendLog('❌ Error: $e');
        }
      },
      child: Text(label),
    );
  }

  @override
  void dispose() {
    _cache.dispose();
    super.dispose();
  }
}
0
likes
130
points
7
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A high-performance pure Dart cache with L1 memory + L2 disk layers, offering fast access, adaptive ARC eviction, TTL support, AES-256-GCM encryption, isolate safety, and zero native dependencies.

Topics

#cache #caching #performance #memory-cache #disk-cache

License

MIT (license)

Dependencies

crypto, meta, path, pointycastle

More

Packages that depend on quantum_cache