mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-01-03 17:29:23 +00:00
separate firo caches and add versioning
This commit is contained in:
parent
23db925e86
commit
2c07f2c13b
5 changed files with 142 additions and 43 deletions
|
@ -15,8 +15,8 @@ import '../../utilities/stack_file_system.dart';
|
|||
|
||||
part 'firo_cache_coordinator.dart';
|
||||
part 'firo_cache_reader.dart';
|
||||
part 'firo_cache_writer.dart';
|
||||
part 'firo_cache_worker.dart';
|
||||
part 'firo_cache_writer.dart';
|
||||
|
||||
/// Temporary debugging log function for this file
|
||||
void _debugLog(Object? object) {
|
||||
|
@ -29,44 +29,73 @@ void _debugLog(Object? object) {
|
|||
}
|
||||
|
||||
abstract class _FiroCache {
|
||||
static const String sqliteDbFileName = "firo_ex_cache.sqlite3";
|
||||
static const int _setCacheVersion = 1;
|
||||
static const int _tagsCacheVersion = 1;
|
||||
static const String sparkSetCacheFileName =
|
||||
"spark_set_v$_setCacheVersion.sqlite3";
|
||||
static const String sparkUsedTagsCacheFileName =
|
||||
"spark_tags_v$_tagsCacheVersion.sqlite3";
|
||||
|
||||
static Database? _db;
|
||||
static Database get db {
|
||||
if (_db == null) {
|
||||
static Database? _setCacheDB;
|
||||
static Database? _usedTagsCacheDB;
|
||||
static Database get setCacheDB {
|
||||
if (_setCacheDB == null) {
|
||||
throw Exception(
|
||||
"FiroCache.init() must be called before accessing FiroCache.db!",
|
||||
);
|
||||
}
|
||||
return _db!;
|
||||
return _setCacheDB!;
|
||||
}
|
||||
|
||||
static Database get usedTagsCacheDB {
|
||||
if (_usedTagsCacheDB == null) {
|
||||
throw Exception(
|
||||
"FiroCache.init() must be called before accessing FiroCache.db!",
|
||||
);
|
||||
}
|
||||
return _usedTagsCacheDB!;
|
||||
}
|
||||
|
||||
static Future<void>? _initFuture;
|
||||
static Future<void> init() => _initFuture ??= _init();
|
||||
|
||||
static Future<void> _init() async {
|
||||
final sqliteDir = await StackFileSystem.applicationSQLiteDirectory();
|
||||
final sqliteDir =
|
||||
await StackFileSystem.applicationFiroCacheSQLiteDirectory();
|
||||
|
||||
final file = File("${sqliteDir.path}/$sqliteDbFileName");
|
||||
final sparkSetCacheFile = File("${sqliteDir.path}/$sparkSetCacheFileName");
|
||||
final sparkUsedTagsCacheFile =
|
||||
File("${sqliteDir.path}/$sparkUsedTagsCacheFileName");
|
||||
|
||||
final exists = await file.exists();
|
||||
if (!exists) {
|
||||
await _createDb(file.path);
|
||||
if (!(await sparkSetCacheFile.exists())) {
|
||||
await _createSparkSetCacheDb(sparkSetCacheFile.path);
|
||||
}
|
||||
if (!(await sparkUsedTagsCacheFile.exists())) {
|
||||
await _createSparkUsedTagsCacheDb(sparkUsedTagsCacheFile.path);
|
||||
}
|
||||
|
||||
_db = sqlite3.open(
|
||||
file.path,
|
||||
_setCacheDB = sqlite3.open(
|
||||
sparkSetCacheFile.path,
|
||||
mode: OpenMode.readWrite,
|
||||
);
|
||||
_usedTagsCacheDB = sqlite3.open(
|
||||
sparkUsedTagsCacheFile.path,
|
||||
mode: OpenMode.readWrite,
|
||||
);
|
||||
}
|
||||
|
||||
static Future<void> _deleteAllCache() async {
|
||||
final start = DateTime.now();
|
||||
db.execute(
|
||||
setCacheDB.execute(
|
||||
"""
|
||||
DELETE FROM SparkSet;
|
||||
DELETE FROM SparkCoin;
|
||||
DELETE FROM SparkSetCoins;
|
||||
VACUUM;
|
||||
""",
|
||||
);
|
||||
usedTagsCacheDB.execute(
|
||||
"""
|
||||
DELETE FROM SparkUsedCoinTags;
|
||||
VACUUM;
|
||||
""",
|
||||
|
@ -77,7 +106,7 @@ abstract class _FiroCache {
|
|||
);
|
||||
}
|
||||
|
||||
static Future<void> _createDb(String file) async {
|
||||
static Future<void> _createSparkSetCacheDb(String file) async {
|
||||
final db = sqlite3.open(
|
||||
file,
|
||||
mode: OpenMode.readWriteCreate,
|
||||
|
@ -109,7 +138,20 @@ abstract class _FiroCache {
|
|||
FOREIGN KEY (setId) REFERENCES SparkSet(id),
|
||||
FOREIGN KEY (coinId) REFERENCES SparkCoin(id)
|
||||
);
|
||||
""",
|
||||
);
|
||||
|
||||
db.dispose();
|
||||
}
|
||||
|
||||
static Future<void> _createSparkUsedTagsCacheDb(String file) async {
|
||||
final db = sqlite3.open(
|
||||
file,
|
||||
mode: OpenMode.readWriteCreate,
|
||||
);
|
||||
|
||||
db.execute(
|
||||
"""
|
||||
CREATE TABLE SparkUsedCoinTags (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
tag TEXT NOT NULL UNIQUE
|
||||
|
|
|
@ -20,14 +20,18 @@ abstract class FiroCacheCoordinator {
|
|||
}
|
||||
|
||||
static Future<String> getSparkCacheSize() async {
|
||||
final dir = await StackFileSystem.applicationSQLiteDirectory();
|
||||
final cacheFile = File("${dir.path}/${_FiroCache.sqliteDbFileName}");
|
||||
final int bytes;
|
||||
if (await cacheFile.exists()) {
|
||||
bytes = await cacheFile.length();
|
||||
} else {
|
||||
bytes = 0;
|
||||
}
|
||||
final dir = await StackFileSystem.applicationFiroCacheSQLiteDirectory();
|
||||
final setCacheFile = File(
|
||||
"${dir.path}/${_FiroCache.sparkSetCacheFileName}",
|
||||
);
|
||||
final usedTagsCacheFile = File(
|
||||
"${dir.path}/${_FiroCache.sparkUsedTagsCacheFileName}",
|
||||
);
|
||||
final int bytes =
|
||||
((await setCacheFile.exists()) ? await setCacheFile.length() : 0) +
|
||||
((await usedTagsCacheFile.exists())
|
||||
? await usedTagsCacheFile.length()
|
||||
: 0);
|
||||
|
||||
if (bytes < 1024) {
|
||||
return '$bytes B';
|
||||
|
@ -88,7 +92,7 @@ abstract class FiroCacheCoordinator {
|
|||
static Future<Set<String>> getUsedCoinTags(int startNumber) async {
|
||||
final result = await _Reader._getSparkUsedCoinTags(
|
||||
startNumber,
|
||||
db: _FiroCache.db,
|
||||
db: _FiroCache.usedTagsCacheDB,
|
||||
);
|
||||
return result.map((e) => e["tag"] as String).toSet();
|
||||
}
|
||||
|
@ -99,7 +103,7 @@ abstract class FiroCacheCoordinator {
|
|||
/// this table in practice.
|
||||
static Future<int> getUsedCoinTagsLastAddedRowId() async {
|
||||
final result = await _Reader._getUsedCoinTagsLastAddedRowId(
|
||||
db: _FiroCache.db,
|
||||
db: _FiroCache.usedTagsCacheDB,
|
||||
);
|
||||
if (result.isEmpty) {
|
||||
return 0;
|
||||
|
@ -112,7 +116,7 @@ abstract class FiroCacheCoordinator {
|
|||
) async {
|
||||
return await _Reader._checkTagIsUsed(
|
||||
tag,
|
||||
db: _FiroCache.db,
|
||||
db: _FiroCache.usedTagsCacheDB,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -122,7 +126,7 @@ abstract class FiroCacheCoordinator {
|
|||
}) async {
|
||||
return await _Reader._getSetCoinsForGroupId(
|
||||
groupId,
|
||||
db: _FiroCache.db,
|
||||
db: _FiroCache.setCacheDB,
|
||||
newerThanTimeStamp: newerThanTimeStamp,
|
||||
);
|
||||
}
|
||||
|
@ -137,7 +141,7 @@ abstract class FiroCacheCoordinator {
|
|||
) async {
|
||||
final result = await _Reader._getLatestSetInfoForGroupId(
|
||||
groupId,
|
||||
db: _FiroCache.db,
|
||||
db: _FiroCache.setCacheDB,
|
||||
);
|
||||
|
||||
if (result.isEmpty) {
|
||||
|
@ -156,7 +160,7 @@ abstract class FiroCacheCoordinator {
|
|||
) async {
|
||||
return await _Reader._checkSetInfoForGroupIdExists(
|
||||
groupId,
|
||||
db: _FiroCache.db,
|
||||
db: _FiroCache.setCacheDB,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,10 @@ class _FiroCacheWorker {
|
|||
}
|
||||
|
||||
static Future<_FiroCacheWorker> spawn() async {
|
||||
final sqliteDir = await StackFileSystem.applicationSQLiteDirectory();
|
||||
final dbFilePath = "${sqliteDir.path}/${_FiroCache.sqliteDbFileName}";
|
||||
final dir = await StackFileSystem.applicationFiroCacheSQLiteDirectory();
|
||||
final setCacheFilePath = "${dir.path}/${_FiroCache.sparkSetCacheFileName}";
|
||||
final usedTagsCacheFilePath =
|
||||
"${dir.path}/${_FiroCache.sparkUsedTagsCacheFileName}";
|
||||
|
||||
final initPort = RawReceivePort();
|
||||
final connection = Completer<(ReceivePort, SendPort)>.sync();
|
||||
|
@ -45,7 +47,7 @@ class _FiroCacheWorker {
|
|||
try {
|
||||
await Isolate.spawn(
|
||||
_startWorkerIsolate,
|
||||
(initPort.sendPort, dbFilePath),
|
||||
(initPort.sendPort, setCacheFilePath, usedTagsCacheFilePath),
|
||||
);
|
||||
} catch (_) {
|
||||
initPort.close();
|
||||
|
@ -75,7 +77,8 @@ class _FiroCacheWorker {
|
|||
static void _handleCommandsToIsolate(
|
||||
ReceivePort receivePort,
|
||||
SendPort sendPort,
|
||||
Database db,
|
||||
Database setCacheDb,
|
||||
Database usedTagsCacheDb,
|
||||
Mutex mutex,
|
||||
) {
|
||||
receivePort.listen((message) {
|
||||
|
@ -87,11 +90,18 @@ class _FiroCacheWorker {
|
|||
switch (task.func) {
|
||||
case FCFuncName._updateSparkAnonSetCoinsWith:
|
||||
final data = task.data as (int, Map<String, dynamic>);
|
||||
result = _updateSparkAnonSetCoinsWith(db, data.$2, data.$1);
|
||||
result = _updateSparkAnonSetCoinsWith(
|
||||
setCacheDb,
|
||||
data.$2,
|
||||
data.$1,
|
||||
);
|
||||
break;
|
||||
|
||||
case FCFuncName._updateSparkUsedTagsWith:
|
||||
result = _updateSparkUsedTagsWith(db, task.data as List<String>);
|
||||
result = _updateSparkUsedTagsWith(
|
||||
usedTagsCacheDb,
|
||||
task.data as List<String>,
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -107,14 +117,24 @@ class _FiroCacheWorker {
|
|||
});
|
||||
}
|
||||
|
||||
static void _startWorkerIsolate((SendPort, String) args) {
|
||||
static void _startWorkerIsolate((SendPort, String, String) args) {
|
||||
final receivePort = ReceivePort();
|
||||
args.$1.send(receivePort.sendPort);
|
||||
final mutex = Mutex();
|
||||
final db = sqlite3.open(
|
||||
final setCacheDb = sqlite3.open(
|
||||
args.$2,
|
||||
mode: OpenMode.readWrite,
|
||||
);
|
||||
_handleCommandsToIsolate(receivePort, args.$1, db, mutex);
|
||||
final usedTagsCacheDb = sqlite3.open(
|
||||
args.$3,
|
||||
mode: OpenMode.readWrite,
|
||||
);
|
||||
_handleCommandsToIsolate(
|
||||
receivePort,
|
||||
args.$1,
|
||||
setCacheDb,
|
||||
usedTagsCacheDb,
|
||||
mutex,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
|
||||
import '../../../db/sqlite/firo_cache.dart';
|
||||
import '../../../models/isar/models/blockchain_data/v2/transaction_v2.dart';
|
||||
import '../../../models/isar/models/isar_models.dart';
|
||||
import '../../../pages/add_wallet_views/add_token_view/edit_wallet_tokens_view.dart';
|
||||
|
@ -282,6 +283,24 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
|
|||
),
|
||||
],
|
||||
),
|
||||
if (wallet.isarTransactionVersion == 2 &&
|
||||
wallet is FiroWallet)
|
||||
Row(
|
||||
children: [
|
||||
const Text(
|
||||
"sparkCache: ",
|
||||
),
|
||||
const SizedBox(
|
||||
width: 2,
|
||||
),
|
||||
FutureBuilder(
|
||||
future: FiroCacheCoordinator.getSparkCacheSize(),
|
||||
builder: (_, snapshot) => Text(
|
||||
snapshot.data ?? "",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
const Spacer(),
|
||||
|
|
|
@ -91,10 +91,24 @@ abstract class StackFileSystem {
|
|||
}
|
||||
}
|
||||
|
||||
static Future<Directory> applicationSQLiteDirectory() async {
|
||||
// Not used in general now. See applicationFiroCacheSQLiteDirectory()
|
||||
// static Future<Directory> applicationSQLiteDirectory() async {
|
||||
// final root = await applicationRootDirectory();
|
||||
// if (Util.isDesktop) {
|
||||
// final dir = Directory("${root.path}/sqlite");
|
||||
// if (!dir.existsSync()) {
|
||||
// await dir.create();
|
||||
// }
|
||||
// return dir;
|
||||
// } else {
|
||||
// return root;
|
||||
// }
|
||||
// }
|
||||
|
||||
static Future<Directory> applicationTorDirectory() async {
|
||||
final root = await applicationRootDirectory();
|
||||
if (Util.isDesktop) {
|
||||
final dir = Directory("${root.path}/sqlite");
|
||||
final dir = Directory("${root.path}/tor");
|
||||
if (!dir.existsSync()) {
|
||||
await dir.create();
|
||||
}
|
||||
|
@ -104,10 +118,10 @@ abstract class StackFileSystem {
|
|||
}
|
||||
}
|
||||
|
||||
static Future<Directory> applicationTorDirectory() async {
|
||||
static Future<Directory> applicationFiroCacheSQLiteDirectory() async {
|
||||
final root = await applicationRootDirectory();
|
||||
if (Util.isDesktop) {
|
||||
final dir = Directory("${root.path}/tor");
|
||||
final dir = Directory("${root.path}/sqlite/firo_cache");
|
||||
if (!dir.existsSync()) {
|
||||
await dir.create();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue