better dht record class

This commit is contained in:
Christien Rioux 2023-07-17 22:39:33 -04:00
parent 90fc2e5f85
commit bf813d7d0f
7 changed files with 300 additions and 132 deletions

109
lib/tools/dht_record.dart Normal file
View file

@ -0,0 +1,109 @@
import 'package:veilid/veilid.dart';
import 'dart:typed_data';
import 'tools.dart';
class DHTRecord {
final VeilidRoutingContext _dhtctx;
final DHTRecordDescriptor _recordDescriptor;
final int _defaultSubkey;
static Future<DHTRecord> create(VeilidRoutingContext dhtctx,
{DHTSchema schema = const DHTSchema.dflt(oCnt: 1),
int defaultSubkey = 0}) async {
DHTRecordDescriptor recordDescriptor = await dhtctx.createDHTRecord(schema);
return DHTRecord(
dhtctx: dhtctx,
recordDescriptor: recordDescriptor,
defaultSubkey: defaultSubkey);
}
static Future<DHTRecord> open(
VeilidRoutingContext dhtctx, TypedKey recordKey, KeyPair? writer,
{int defaultSubkey = 0}) async {
DHTRecordDescriptor recordDescriptor =
await dhtctx.openDHTRecord(recordKey, writer);
return DHTRecord(
dhtctx: dhtctx,
recordDescriptor: recordDescriptor,
defaultSubkey: defaultSubkey);
}
DHTRecord(
{required VeilidRoutingContext dhtctx,
required DHTRecordDescriptor recordDescriptor,
int defaultSubkey = 0})
: _dhtctx = dhtctx,
_recordDescriptor = recordDescriptor,
_defaultSubkey = defaultSubkey;
int _subkey(int subkey) => (subkey == -1) ? _defaultSubkey : subkey;
Future<Uint8List?> get({int subkey = -1, bool forceRefresh = false}) async {
ValueData? valueData = await _dhtctx.getDHTValue(
_recordDescriptor.key, _subkey(subkey), false);
if (valueData == null) {
return null;
}
return valueData.data;
}
Future<T?> getJson<T>(T Function(Map<String, dynamic>) fromJson,
{int subkey = -1, bool forceRefresh = false}) async {
ValueData? valueData = await _dhtctx.getDHTValue(
_recordDescriptor.key, _subkey(subkey), false);
if (valueData == null) {
return null;
}
return valueData.readJsonData(fromJson);
}
Future<void> eventualWriteBytes(Uint8List newValue, {int subkey = -1}) async {
// Get existing identity key
ValueData? valueData;
do {
// Ensure it exists already
if (valueData == null) {
throw const FormatException("value does not exist");
}
// Set the new data
valueData = await _dhtctx.setDHTValue(
_recordDescriptor.key, _subkey(subkey), newValue);
// Repeat if newer data on the network was found
} while (valueData != null);
}
Future<void> eventualUpdateBytes(
Future<Uint8List> Function(Uint8List oldValue) update,
{int subkey = -1}) async {
// Get existing identity key
ValueData? valueData = await _dhtctx.getDHTValue(
_recordDescriptor.key, _subkey(subkey), false);
do {
// Ensure it exists already
if (valueData == null) {
throw const FormatException("value does not exist");
}
// Update the data
final newData = await update(valueData.data);
// Set it back
valueData = await _dhtctx.setDHTValue(
_recordDescriptor.key, _subkey(subkey), newData);
// Repeat if newer data on the network was found
} while (valueData != null);
}
Future<void> eventualWriteJson<T>(T newValue, {int subkey = -1}) {
return eventualWriteBytes(jsonEncodeBytes(newValue), subkey: subkey);
}
Future<void> eventualUpdateJson<T>(
T Function(Map<String, dynamic>) fromJson, Future<T> Function(T) update,
{int subkey = -1}) {
return eventualUpdateBytes(jsonUpdate(fromJson, update), subkey: subkey);
}
}

30
lib/tools/json_tools.dart Normal file
View file

@ -0,0 +1,30 @@
// import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:veilid/veilid.dart';
import 'dart:typed_data';
import 'dart:convert';
extension FromValueDataJsonExt on ValueData {
T readJsonData<T>(T Function(Map<String, dynamic>) fromJson) {
return fromJson(jsonDecode(utf8.decode(data)));
}
}
Uint8List jsonEncodeBytes(Object? object,
{Object? Function(Object?)? toEncodable}) {
return Uint8List.fromList(
utf8.encode(jsonEncode(object, toEncodable: toEncodable)));
}
Future<Uint8List> jsonUpdateBytes<T>(T Function(Map<String, dynamic>) fromJson,
Uint8List oldBytes, Future<T> Function(T) update) async {
T oldObj = fromJson(jsonDecode(utf8.decode(oldBytes)));
T newObj = await update(oldObj);
return jsonEncodeBytes(newObj);
}
Future<Uint8List> Function(Uint8List) jsonUpdate<T>(
T Function(Map<String, dynamic>) fromJson, Future<T> Function(T) update) {
return (Uint8List oldBytes) {
return jsonUpdateBytes(fromJson, oldBytes, update);
};
}

View file

@ -1,9 +1,4 @@
export 'external_stream_state.dart';
import 'package:veilid/veilid.dart';
import 'dart:convert';
extension FromValueDataJsonExt on ValueData {
T readJsonData<T>(T Function(Map<String, dynamic>) fromJson) {
return fromJson(jsonDecode(utf8.decode(data)));
}
}
export 'dht_record.dart';
export 'json_tools.dart';
export 'phono_byte.dart';