clean up valuesubkeyrangeseT
This commit is contained in:
parent
291e3ef2fe
commit
73c37aa4ca
@ -4,7 +4,7 @@ use crate::storage_manager::SignedValueData;
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RPCOperationValueChanged {
|
pub struct RPCOperationValueChanged {
|
||||||
key: TypedKey,
|
key: TypedKey,
|
||||||
subkeys: Vec<ValueSubkeyRange>,
|
subkeys: ValueSubkeyRangeSet,
|
||||||
count: u32,
|
count: u32,
|
||||||
value: SignedValueData,
|
value: SignedValueData,
|
||||||
}
|
}
|
||||||
@ -12,7 +12,7 @@ pub struct RPCOperationValueChanged {
|
|||||||
impl RPCOperationValueChanged {
|
impl RPCOperationValueChanged {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
key: TypedKey,
|
key: TypedKey,
|
||||||
subkeys: Vec<ValueSubkeyRange>,
|
subkeys: ValueSubkeyRangeSet,
|
||||||
count: u32,
|
count: u32,
|
||||||
value: SignedValueData,
|
value: SignedValueData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -32,7 +32,7 @@ impl RPCOperationValueChanged {
|
|||||||
pub fn key(&self) -> &TypedKey {
|
pub fn key(&self) -> &TypedKey {
|
||||||
&self.key
|
&self.key
|
||||||
}
|
}
|
||||||
pub fn subkeys(&self) -> &[ValueSubkeyRange] {
|
pub fn subkeys(&self) -> &ValueSubkeyRangeSet {
|
||||||
&self.subkeys
|
&self.subkeys
|
||||||
}
|
}
|
||||||
pub fn count(&self) -> u32 {
|
pub fn count(&self) -> u32 {
|
||||||
@ -41,7 +41,7 @@ impl RPCOperationValueChanged {
|
|||||||
pub fn value(&self) -> &SignedValueData {
|
pub fn value(&self) -> &SignedValueData {
|
||||||
&self.value
|
&self.value
|
||||||
}
|
}
|
||||||
pub fn destructure(self) -> (TypedKey, Vec<ValueSubkeyRange>, u32, SignedValueData) {
|
pub fn destructure(self) -> (TypedKey, ValueSubkeyRangeSet, u32, SignedValueData) {
|
||||||
(self.key, self.subkeys, self.count, self.value)
|
(self.key, self.subkeys, self.count, self.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,25 +52,20 @@ impl RPCOperationValueChanged {
|
|||||||
let key = decode_typed_key(&k_reader)?;
|
let key = decode_typed_key(&k_reader)?;
|
||||||
|
|
||||||
let sk_reader = reader.get_subkeys().map_err(RPCError::protocol)?;
|
let sk_reader = reader.get_subkeys().map_err(RPCError::protocol)?;
|
||||||
let mut subkeys = Vec::<ValueSubkeyRange>::with_capacity(
|
let mut subkeys = ValueSubkeyRangeSet::new();
|
||||||
sk_reader
|
|
||||||
.len()
|
|
||||||
.try_into()
|
|
||||||
.map_err(RPCError::map_protocol("too many subkey ranges"))?,
|
|
||||||
);
|
|
||||||
for skr in sk_reader.iter() {
|
for skr in sk_reader.iter() {
|
||||||
let vskr = (skr.get_start(), skr.get_end());
|
let vskr = (skr.get_start(), skr.get_end());
|
||||||
if vskr.0 > vskr.1 {
|
if vskr.0 > vskr.1 {
|
||||||
return Err(RPCError::protocol("invalid subkey range"));
|
return Err(RPCError::protocol("invalid subkey range"));
|
||||||
}
|
}
|
||||||
if let Some(lvskr) = subkeys.last() {
|
if let Some(lvskr) = subkeys.last() {
|
||||||
if lvskr.1 >= vskr.0 {
|
if lvskr >= vskr.0 {
|
||||||
return Err(RPCError::protocol(
|
return Err(RPCError::protocol(
|
||||||
"subkey range out of order or not merged",
|
"subkey range out of order or not merged",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subkeys.push(vskr);
|
subkeys.ranges_insert(vskr.0..=vskr.1);
|
||||||
}
|
}
|
||||||
let count = reader.get_count();
|
let count = reader.get_count();
|
||||||
let v_reader = reader.get_value().map_err(RPCError::protocol)?;
|
let v_reader = reader.get_value().map_err(RPCError::protocol)?;
|
||||||
@ -91,14 +86,14 @@ impl RPCOperationValueChanged {
|
|||||||
|
|
||||||
let mut sk_builder = builder.reborrow().init_subkeys(
|
let mut sk_builder = builder.reborrow().init_subkeys(
|
||||||
self.subkeys
|
self.subkeys
|
||||||
.len()
|
.ranges_len()
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(RPCError::map_internal("invalid subkey range list length"))?,
|
.map_err(RPCError::map_internal("invalid subkey range list length"))?,
|
||||||
);
|
);
|
||||||
for (i, skr) in self.subkeys.iter().enumerate() {
|
for (i, skr) in self.subkeys.ranges().enumerate() {
|
||||||
let mut skr_builder = sk_builder.reborrow().get(i as u32);
|
let mut skr_builder = sk_builder.reborrow().get(i as u32);
|
||||||
skr_builder.set_start(skr.0);
|
skr_builder.set_start(*skr.start());
|
||||||
skr_builder.set_end(skr.1);
|
skr_builder.set_end(*skr.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.set_count(self.count);
|
builder.set_count(self.count);
|
||||||
|
@ -6,7 +6,7 @@ const MAX_WATCH_VALUE_A_PEERS_LEN: usize = 20;
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RPCOperationWatchValueQ {
|
pub struct RPCOperationWatchValueQ {
|
||||||
key: TypedKey,
|
key: TypedKey,
|
||||||
subkeys: Vec<ValueSubkeyRange>,
|
subkeys: ValueSubkeyRangeSet,
|
||||||
expiration: u64,
|
expiration: u64,
|
||||||
count: u32,
|
count: u32,
|
||||||
watcher: PublicKey,
|
watcher: PublicKey,
|
||||||
@ -16,7 +16,7 @@ pub struct RPCOperationWatchValueQ {
|
|||||||
impl RPCOperationWatchValueQ {
|
impl RPCOperationWatchValueQ {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
key: TypedKey,
|
key: TypedKey,
|
||||||
subkeys: Vec<ValueSubkeyRange>,
|
subkeys: ValueSubkeyRangeSet,
|
||||||
expiration: u64,
|
expiration: u64,
|
||||||
count: u32,
|
count: u32,
|
||||||
watcher: PublicKey,
|
watcher: PublicKey,
|
||||||
@ -41,9 +41,9 @@ impl RPCOperationWatchValueQ {
|
|||||||
Vec::with_capacity(PUBLIC_KEY_LENGTH + 4 + (self.subkeys.len() * 8) + 8 + 4);
|
Vec::with_capacity(PUBLIC_KEY_LENGTH + 4 + (self.subkeys.len() * 8) + 8 + 4);
|
||||||
sig_data.extend_from_slice(&self.key.kind.0);
|
sig_data.extend_from_slice(&self.key.kind.0);
|
||||||
sig_data.extend_from_slice(&self.key.value.bytes);
|
sig_data.extend_from_slice(&self.key.value.bytes);
|
||||||
for sk in &self.subkeys {
|
for sk in self.subkeys.ranges() {
|
||||||
sig_data.extend_from_slice(&sk.0.to_le_bytes());
|
sig_data.extend_from_slice(&sk.start().to_le_bytes());
|
||||||
sig_data.extend_from_slice(&sk.1.to_le_bytes());
|
sig_data.extend_from_slice(&sk.end().to_le_bytes());
|
||||||
}
|
}
|
||||||
sig_data.extend_from_slice(&self.expiration.to_le_bytes());
|
sig_data.extend_from_slice(&self.expiration.to_le_bytes());
|
||||||
sig_data.extend_from_slice(&self.count.to_le_bytes());
|
sig_data.extend_from_slice(&self.count.to_le_bytes());
|
||||||
@ -66,7 +66,7 @@ impl RPCOperationWatchValueQ {
|
|||||||
pub fn key(&self) -> &TypedKey {
|
pub fn key(&self) -> &TypedKey {
|
||||||
&self.key
|
&self.key
|
||||||
}
|
}
|
||||||
pub fn subkeys(&self) -> &[ValueSubkeyRange] {
|
pub fn subkeys(&self) -> &ValueSubkeyRangeSet {
|
||||||
&self.subkeys
|
&self.subkeys
|
||||||
}
|
}
|
||||||
pub fn expiration(&self) -> u64 {
|
pub fn expiration(&self) -> u64 {
|
||||||
@ -86,7 +86,7 @@ impl RPCOperationWatchValueQ {
|
|||||||
self,
|
self,
|
||||||
) -> (
|
) -> (
|
||||||
TypedKey,
|
TypedKey,
|
||||||
Vec<ValueSubkeyRange>,
|
ValueSubkeyRangeSet,
|
||||||
u64,
|
u64,
|
||||||
u32,
|
u32,
|
||||||
PublicKey,
|
PublicKey,
|
||||||
@ -112,25 +112,20 @@ impl RPCOperationWatchValueQ {
|
|||||||
if sk_reader.len() as usize > MAX_WATCH_VALUE_Q_SUBKEYS_LEN {
|
if sk_reader.len() as usize > MAX_WATCH_VALUE_Q_SUBKEYS_LEN {
|
||||||
return Err(RPCError::protocol("WatchValueQ subkeys length too long"));
|
return Err(RPCError::protocol("WatchValueQ subkeys length too long"));
|
||||||
}
|
}
|
||||||
let mut subkeys = Vec::<ValueSubkeyRange>::with_capacity(
|
let mut subkeys = ValueSubkeyRangeSet::new();
|
||||||
sk_reader
|
|
||||||
.len()
|
|
||||||
.try_into()
|
|
||||||
.map_err(RPCError::map_protocol("too many subkey ranges"))?,
|
|
||||||
);
|
|
||||||
for skr in sk_reader.iter() {
|
for skr in sk_reader.iter() {
|
||||||
let vskr = (skr.get_start(), skr.get_end());
|
let vskr = (skr.get_start(), skr.get_end());
|
||||||
if vskr.0 > vskr.1 {
|
if vskr.0 > vskr.1 {
|
||||||
return Err(RPCError::protocol("invalid subkey range"));
|
return Err(RPCError::protocol("invalid subkey range"));
|
||||||
}
|
}
|
||||||
if let Some(lvskr) = subkeys.last() {
|
if let Some(lvskr) = subkeys.last() {
|
||||||
if lvskr.1 >= vskr.0 {
|
if lvskr >= vskr.0 {
|
||||||
return Err(RPCError::protocol(
|
return Err(RPCError::protocol(
|
||||||
"subkey range out of order or not merged",
|
"subkey range out of order or not merged",
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
subkeys.push(vskr);
|
subkeys.ranges_insert(vskr.0..=vskr.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let expiration = reader.get_expiration();
|
let expiration = reader.get_expiration();
|
||||||
@ -165,10 +160,10 @@ impl RPCOperationWatchValueQ {
|
|||||||
.try_into()
|
.try_into()
|
||||||
.map_err(RPCError::map_internal("invalid subkey range list length"))?,
|
.map_err(RPCError::map_internal("invalid subkey range list length"))?,
|
||||||
);
|
);
|
||||||
for (i, skr) in self.subkeys.iter().enumerate() {
|
for (i, skr) in self.subkeys.ranges().enumerate() {
|
||||||
let mut skr_builder = sk_builder.reborrow().get(i as u32);
|
let mut skr_builder = sk_builder.reborrow().get(i as u32);
|
||||||
skr_builder.set_start(skr.0);
|
skr_builder.set_start(*skr.start());
|
||||||
skr_builder.set_end(skr.1);
|
skr_builder.set_end(*skr.end());
|
||||||
}
|
}
|
||||||
builder.set_expiration(self.expiration);
|
builder.set_expiration(self.expiration);
|
||||||
builder.set_count(self.count);
|
builder.set_count(self.count);
|
||||||
|
@ -31,6 +31,14 @@ fn get_string(text: &str) -> Option<String> {
|
|||||||
Some(text.to_owned())
|
Some(text.to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_subkeys(text: &str) -> Option<ValueSubkeyRangeSet> {
|
||||||
|
if let Some(n) = get_number(text) {
|
||||||
|
Some(ValueSubkeyRangeSet::single(n.try_into().ok()?))
|
||||||
|
} else {
|
||||||
|
ValueSubkeyRangeSet::from_str(text).ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_route_id(
|
fn get_route_id(
|
||||||
rss: RouteSpecStore,
|
rss: RouteSpecStore,
|
||||||
allow_allocated: bool,
|
allow_allocated: bool,
|
||||||
@ -902,7 +910,7 @@ impl VeilidAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn debug_record_purge(&self, args: Vec<String>) -> VeilidAPIResult<String> {
|
async fn debug_record_purge(&self, args: Vec<String>) -> VeilidAPIResult<String> {
|
||||||
// <local|remote>
|
// <local|remote> [bytes]
|
||||||
let storage_manager = self.storage_manager()?;
|
let storage_manager = self.storage_manager()?;
|
||||||
|
|
||||||
let scope = get_debug_argument_at(&args, 1, "debug_record_purge", "scope", get_string)?;
|
let scope = get_debug_argument_at(&args, 1, "debug_record_purge", "scope", get_string)?;
|
||||||
@ -914,6 +922,17 @@ impl VeilidAPI {
|
|||||||
};
|
};
|
||||||
return Ok(out);
|
return Ok(out);
|
||||||
}
|
}
|
||||||
|
async fn debug_record_get(&self, args: Vec<String>) -> VeilidAPIResult<String> {
|
||||||
|
let storage_manager = self.storage_manager()?;
|
||||||
|
|
||||||
|
let key = get_debug_argument_at(&args, 1, "debug_record_get", "key", get_typed_key)?;
|
||||||
|
let subkeys =
|
||||||
|
get_debug_argument_at(&args, 2, "debug_record_subkeys", "subkeys", get_string)?;
|
||||||
|
|
||||||
|
// let rc = self.routing_context();
|
||||||
|
|
||||||
|
return Ok("TODO");
|
||||||
|
}
|
||||||
|
|
||||||
async fn debug_record(&self, args: String) -> VeilidAPIResult<String> {
|
async fn debug_record(&self, args: String) -> VeilidAPIResult<String> {
|
||||||
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
|
let args: Vec<String> = args.split_whitespace().map(|s| s.to_owned()).collect();
|
||||||
@ -924,6 +943,8 @@ impl VeilidAPI {
|
|||||||
self.debug_record_list(args).await
|
self.debug_record_list(args).await
|
||||||
} else if command == "purge" {
|
} else if command == "purge" {
|
||||||
self.debug_record_purge(args).await
|
self.debug_record_purge(args).await
|
||||||
|
} else if command == "get" {
|
||||||
|
self.debug_record_get(args).await
|
||||||
} else {
|
} else {
|
||||||
Ok(">>> Unknown command\n".to_owned())
|
Ok(">>> Unknown command\n".to_owned())
|
||||||
}
|
}
|
||||||
@ -954,6 +975,7 @@ impl VeilidAPI {
|
|||||||
test <route>
|
test <route>
|
||||||
record list <local|remote>
|
record list <local|remote>
|
||||||
purge <local|remote> [bytes]
|
purge <local|remote> [bytes]
|
||||||
|
get <key> <subkeys>
|
||||||
|
|
||||||
<destination> is:
|
<destination> is:
|
||||||
* direct: <node>[+<safety>][<modifiers>]
|
* direct: <node>[+<safety>][<modifiers>]
|
||||||
@ -966,6 +988,9 @@ impl VeilidAPI {
|
|||||||
<protocoltype> is: udp|tcp|ws|wss
|
<protocoltype> is: udp|tcp|ws|wss
|
||||||
<addresstype> is: ipv4|ipv6
|
<addresstype> is: ipv4|ipv6
|
||||||
<routingdomain> is: public|local
|
<routingdomain> is: public|local
|
||||||
|
<subkeys> is:
|
||||||
|
* a number: 2
|
||||||
|
* a comma-separated inclusive range list: 1..=3,5..=8
|
||||||
"#
|
"#
|
||||||
.to_owned())
|
.to_owned())
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,5 @@ pub use value_subkey_range_set::*;
|
|||||||
|
|
||||||
/// Value subkey
|
/// Value subkey
|
||||||
pub type ValueSubkey = u32;
|
pub type ValueSubkey = u32;
|
||||||
/// Value subkey range
|
|
||||||
pub type ValueSubkeyRange = (u32, u32);
|
|
||||||
/// Value sequence number
|
/// Value sequence number
|
||||||
pub type ValueSeqNum = u32;
|
pub type ValueSeqNum = u32;
|
||||||
|
@ -41,6 +41,28 @@ impl ValueSubkeyRangeSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for ValueSubkeyRangeSet {
|
||||||
|
type Err = VeilidAPIError;
|
||||||
|
|
||||||
|
fn from_str(value: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut data = RangeSetBlaze::<ValueSubkey>::new();
|
||||||
|
|
||||||
|
for r in value.split(",") {
|
||||||
|
let r = r.trim();
|
||||||
|
let Some((ss, es)) = r.split_once("..=") else {
|
||||||
|
return Err(VeilidAPIError::parse_error("can not parse ValueSubkeyRangeSet", r));
|
||||||
|
};
|
||||||
|
let sn = ValueSubkey::from_str(ss)
|
||||||
|
.map_err(|e| VeilidAPIError::parse_error("could not parse ValueSubkey", e))?;
|
||||||
|
let en = ValueSubkey::from_str(es)
|
||||||
|
.map_err(|e| VeilidAPIError::parse_error("could not parse ValueSubkey", e))?;
|
||||||
|
data.ranges_insert(sn..=en);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(ValueSubkeyRangeSet { data })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for ValueSubkeyRangeSet {
|
impl Deref for ValueSubkeyRangeSet {
|
||||||
type Target = RangeSetBlaze<ValueSubkey>;
|
type Target = RangeSetBlaze<ValueSubkey>;
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ abstract class VeilidRoutingContext {
|
|||||||
Future<void> deleteDHTRecord(TypedKey key);
|
Future<void> deleteDHTRecord(TypedKey key);
|
||||||
Future<ValueData?> getDHTValue(TypedKey key, int subkey, bool forceRefresh);
|
Future<ValueData?> getDHTValue(TypedKey key, int subkey, bool forceRefresh);
|
||||||
Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data);
|
Future<ValueData?> setDHTValue(TypedKey key, int subkey, Uint8List data);
|
||||||
Future<Timestamp> watchDHTValues(
|
Future<Timestamp> watchDHTValues(TypedKey key, List<ValueSubkeyRange> subkeys,
|
||||||
TypedKey key, ValueSubkeyRange subkeys, Timestamp expiration, int count);
|
Timestamp expiration, int count);
|
||||||
Future<bool> cancelDHTWatch(TypedKey key, ValueSubkeyRange subkeys);
|
Future<bool> cancelDHTWatch(TypedKey key, List<ValueSubkeyRange> subkeys);
|
||||||
}
|
}
|
||||||
|
@ -710,7 +710,7 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Timestamp> watchDHTValues(TypedKey key, ValueSubkeyRange subkeys,
|
Future<Timestamp> watchDHTValues(TypedKey key, List<ValueSubkeyRange> subkeys,
|
||||||
Timestamp expiration, int count) async {
|
Timestamp expiration, int count) async {
|
||||||
final nativeKey = jsonEncode(key).toNativeUtf8();
|
final nativeKey = jsonEncode(key).toNativeUtf8();
|
||||||
final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8();
|
final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8();
|
||||||
@ -726,7 +726,8 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> cancelDHTWatch(TypedKey key, ValueSubkeyRange subkeys) async {
|
Future<bool> cancelDHTWatch(
|
||||||
|
TypedKey key, List<ValueSubkeyRange> subkeys) async {
|
||||||
final nativeKey = jsonEncode(key).toNativeUtf8();
|
final nativeKey = jsonEncode(key).toNativeUtf8();
|
||||||
final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8();
|
final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8();
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ class VeilidRoutingContextJS implements VeilidRoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<Timestamp> watchDHTValues(TypedKey key, ValueSubkeyRange subkeys,
|
Future<Timestamp> watchDHTValues(TypedKey key, List<ValueSubkeyRange> subkeys,
|
||||||
Timestamp expiration, int count) async {
|
Timestamp expiration, int count) async {
|
||||||
final ts = await _wrapApiPromise(js_util.callMethod(
|
final ts = await _wrapApiPromise(js_util.callMethod(
|
||||||
wasm, "routing_context_watch_dht_values", [
|
wasm, "routing_context_watch_dht_values", [
|
||||||
@ -143,7 +143,7 @@ class VeilidRoutingContextJS implements VeilidRoutingContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> cancelDHTWatch(TypedKey key, ValueSubkeyRange subkeys) {
|
Future<bool> cancelDHTWatch(TypedKey key, List<ValueSubkeyRange> subkeys) {
|
||||||
return _wrapApiPromise(js_util.callMethod(
|
return _wrapApiPromise(js_util.callMethod(
|
||||||
wasm,
|
wasm,
|
||||||
"routing_context_cancel_dht_watch",
|
"routing_context_cancel_dht_watch",
|
||||||
|
Loading…
Reference in New Issue
Block a user