Skip to content

Instantly share code, notes, and snippets.

@Gorniv
Last active August 27, 2020 09:38
Show Gist options
  • Save Gorniv/ae1692a628cb29db9e6de95f2b923779 to your computer and use it in GitHub Desktop.
Save Gorniv/ae1692a628cb29db9e6de95f2b923779 to your computer and use it in GitHub Desktop.
HiveCacheManager
import 'package:flutter/foundation.dart';
import 'package:get_it/get_it.dart';
import 'package:hive/hive.dart';
import 'package:mobile/core/index.dart';
import 'package:path/path.dart' as p;
import 'package:semaphore/semaphore.dart';
import 'package:pedantic/pedantic.dart';
abstract class HiveLazyCacheManager {
final _sm = LocalSemaphore(1);
String _key = 'cache_v1';
String _nameLogger = 'HiveCacheManager';
String _keyTime = 'cache_time_v1';
Duration _duration = const Duration(hours: 8);
final appSettings = GetIt.I.get<AppSetting>();
Stream<dynamic> _compactStream;
LazyBox<dynamic> _box;
Box<dynamic> _boxTime;
void init(String name, Duration duration) {
_key = '${name.toLowerCase()}$_key';
_nameLogger = '$name$_nameLogger';
_keyTime = '${name.toLowerCase()}$_keyTime';
_duration = duration;
}
Future<void> openAsync() async {
final path = kIsWeb ? _key : p.join(appSettings.directoryApp.path, _key);
final pathTime = kIsWeb ? _keyTime : p.join(appSettings.directoryApp.path, _keyTime);
_box = await Hive.openLazyBox(_key, path: path);
_boxTime = await Hive.openBox(_keyTime, path: pathTime);
_compactStream = Stream<void>.periodic(const Duration(seconds: 311));
unawaited(_compactStream.forEach((_) async {
await _box.compact();
await _boxTime.compact();
}));
}
bool containsKey(String itemId, {bool useExpire = true}) {
try {
_sm.acquire();
return _containsKey(itemId, useExpire: useExpire);
} catch (error, stackTrace) {
l.log('$error', name: _nameLogger, error: error, stackTrace: stackTrace);
return false;
} finally {
_sm.release();
}
}
bool _containsKey(
String itemId, {
bool useExpire,
}) {
if (itemId == null) return false;
if (useExpire == true && _duration != null) {
if (!_boxTime.containsKey(itemId)) {
return false;
}
final time = _boxTime.get(itemId) as DateTime;
final difference = time.difference(DateTime.now());
if (difference > _duration) {
_boxTime.delete(itemId);
return false;
}
}
if (!_box.containsKey(itemId)) {
return false;
}
return true;
}
/// offsetExpire - less time save (if add time)
Future<void> putItemAsync(String key, dynamic value, {Duration offsetExpire, bool useExpire = true}) async {
try {
await _sm.acquire();
if (useExpire == true && _duration != null) {
var time = DateTime.now();
if (offsetExpire != null) {
time.add(offsetExpire);
}
await _boxTime.put(key, time);
}
await _box.put(key, value);
} finally {
_sm.release();
}
}
Future<dynamic> getItemAsync(String keyId, {bool useExpire = true}) async {
try {
await _sm.acquire();
return await (_getItemAsync(keyId, useExpire: useExpire));
} finally {
_sm.release();
}
}
dynamic getItem(String keyId) {
return _box.get(keyId);
}
Future<List<dynamic>> getAllAsync({bool useExpire = true}) async {
try {
await _sm.acquire();
final keys = _box.keys.toList();
final result = [];
for (var item in keys) {
final map = await _getItemAsync(item.toString(), useExpire: useExpire);
result.add(map);
}
return result;
} finally {
_sm.release();
}
}
Future<void> deleteAsync(String keyCurrent) async {
try {
await _sm.acquire();
await _box.delete(keyCurrent);
await _boxTime.delete(keyCurrent);
} finally {
_sm.release();
}
}
Future<void> compactAsync() async {
try {
await _sm.acquire();
await _box.compact();
await _boxTime.compact();
} finally {
_sm.release();
}
}
Future<dynamic> _getItemAsync(String keyId, {bool useExpire = true}) async {
try {
if (useExpire == true) {
if (_containsKey(keyId, useExpire: useExpire) == false) return null;
}
return await _box.get(keyId);
} finally {}
}
}
abstract class HiveCacheManager {
String _key = 'cache_v1';
String _nameLogger = 'HiveCacheManager';
String _keyTime = 'cache_time_v1';
final appSettings = GetIt.I.get<AppSetting>();
Stream<dynamic> _compactStream$;
Box<dynamic> _box;
void init(String name, Duration duration) {
_key = '${name.toLowerCase()}$_key';
_nameLogger = '$name$_nameLogger';
_keyTime = '${name.toLowerCase()}$_keyTime';
}
Future<void> openAsync() async {
final path = kIsWeb ? _key : p.join(appSettings.directoryApp.path, _key);
_box = await Hive.openBox(_key, path: path);
_compactStream$ = Stream<void>.periodic(const Duration(seconds: 311));
unawaited(_compactStream$.forEach((_) async {
await _box.compact();
}));
}
bool containsKey(String itemId, {bool useExpire = true}) {
try {
return _containsKey(itemId);
} catch (error, stackTrace) {
l.log('$error', name: _nameLogger, error: error, stackTrace: stackTrace);
return false;
}
}
/// offsetExpire - less time save (if add time)
Future<void> putItemAsync(String key, dynamic value) async {
await _box.put(key, value);
}
dynamic getItem(String keyId) {
return _box.get(keyId);
}
Future<void> compactAsync() async {
await _box.compact();
}
bool _containsKey(String itemId) {
if (!_box.containsKey(itemId)) {
return false;
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment