Last active
August 27, 2020 09:38
-
-
Save Gorniv/ae1692a628cb29db9e6de95f2b923779 to your computer and use it in GitHub Desktop.
HiveCacheManager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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