Skip to content

Commit 7b25daa

Browse files
committed
Introduce the "find_keys_in_interval" / "find_key_values_in_interval".
1 parent b407efa commit 7b25daa

30 files changed

Lines changed: 1987 additions & 397 deletions

linera-execution/src/execution_state_actor.rs

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use linera_base::{
2424
ownership::ChainOwnership,
2525
time::Instant,
2626
};
27-
use linera_views::{batch::Batch, context::Context, views::View};
27+
use linera_views::{batch::Batch, context::Context, store::KeyInterval, views::View};
2828
use oneshot::Sender;
2929
use reqwest::{header::HeaderMap, Client, Url};
3030
use tracing::{info_span, instrument, Instrument as _};
@@ -35,9 +35,10 @@ use crate::{
3535
system::{CreateApplicationResult, OpenChainConfig},
3636
util::{OracleResponseExt as _, RespondExt as _},
3737
ApplicationDescription, ApplicationId, ExecutionError, ExecutionRuntimeContext,
38-
ExecutionStateView, JsVec, Message, MessageContext, MessageKind, ModuleId, Operation,
39-
OperationContext, OutgoingMessage, ProcessStreamsContext, QueryContext, QueryOutcome,
40-
ResourceController, SystemMessage, TransactionTracker, UserContractCode, UserServiceCode,
38+
ExecutionStateView, IntervalKeyValues, IntervalKeys, JsVec, Message, MessageContext,
39+
MessageKind, ModuleId, Operation, OperationContext, OutgoingMessage, ProcessStreamsContext,
40+
QueryContext, QueryOutcome, ResourceController, SystemMessage, TransactionTracker,
41+
UserContractCode, UserServiceCode,
4142
};
4243

4344
/// Actor for handling requests to the execution state.
@@ -405,6 +406,32 @@ where
405406
callback.respond(result);
406407
}
407408

409+
FindKeysInInterval {
410+
id,
411+
key_interval,
412+
callback,
413+
} => {
414+
let view = self.state.users.try_load_entry(&id).await?;
415+
let result = match view {
416+
Some(view) => view.find_keys_in_interval(key_interval).await?,
417+
None => (Vec::new(), true),
418+
};
419+
callback.respond(result);
420+
}
421+
422+
FindKeyValuesInInterval {
423+
id,
424+
key_interval,
425+
callback,
426+
} => {
427+
let view = self.state.users.try_load_entry(&id).await?;
428+
let result = match view {
429+
Some(view) => view.find_key_values_in_interval(key_interval).await?,
430+
None => (Vec::new(), true),
431+
};
432+
callback.respond(result);
433+
}
434+
408435
WriteBatch {
409436
id,
410437
batch,
@@ -1400,6 +1427,20 @@ pub enum ExecutionRequest {
14001427
callback: Sender<Vec<(Vec<u8>, Vec<u8>)>>,
14011428
},
14021429

1430+
FindKeysInInterval {
1431+
id: ApplicationId,
1432+
key_interval: KeyInterval,
1433+
#[debug(skip)]
1434+
callback: Sender<IntervalKeys>,
1435+
},
1436+
1437+
FindKeyValuesInInterval {
1438+
id: ApplicationId,
1439+
key_interval: KeyInterval,
1440+
#[debug(skip)]
1441+
callback: Sender<IntervalKeyValues>,
1442+
},
1443+
14031444
WriteBatch {
14041445
id: ApplicationId,
14051446
batch: Batch,

linera-execution/src/lib.rs

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ use linera_base::{
4545
ownership::ChainOwnership,
4646
vm::VmRuntime,
4747
};
48-
use linera_views::{batch::Batch, ViewError};
48+
use linera_views::{batch::Batch, store::KeyInterval, ViewError};
4949
use serde::{Deserialize, Serialize};
5050
use system::AdminOperation;
51+
52+
pub type IntervalKeys = (Vec<Vec<u8>>, bool);
53+
pub type IntervalKeyValues = (Vec<(Vec<u8>, Vec<u8>)>, bool);
5154
use thiserror::Error;
5255
pub use web_thread_pool::Pool as ThreadPool;
5356
use web_thread_select as web_thread;
@@ -724,6 +727,8 @@ pub trait BaseRuntime {
724727
type ReadValueBytes: fmt::Debug + Send + Sync;
725728
type FindKeysByPrefix: fmt::Debug + Send + Sync;
726729
type FindKeyValuesByPrefix: fmt::Debug + Send + Sync;
730+
type FindKeysInInterval: fmt::Debug + Send + Sync;
731+
type FindKeyValuesInInterval: fmt::Debug + Send + Sync;
727732

728733
/// The current chain ID.
729734
fn chain_id(&mut self) -> Result<ChainId, ExecutionError>;
@@ -864,6 +869,18 @@ pub trait BaseRuntime {
864869
promise: &Self::FindKeysByPrefix,
865870
) -> Result<Vec<Vec<u8>>, ExecutionError>;
866871

872+
/// Creates the promise to access keys in a specific interval.
873+
fn find_keys_in_interval_new(
874+
&mut self,
875+
key_interval: KeyInterval,
876+
) -> Result<Self::FindKeysInInterval, ExecutionError>;
877+
878+
/// Resolves the promise to access keys in a specific interval.
879+
fn find_keys_in_interval_wait(
880+
&mut self,
881+
promise: &Self::FindKeysInInterval,
882+
) -> Result<IntervalKeys, ExecutionError>;
883+
867884
/// Reads the data from the key/values having a specific prefix.
868885
#[cfg(feature = "test")]
869886
#[expect(clippy::type_complexity)]
@@ -888,6 +905,18 @@ pub trait BaseRuntime {
888905
promise: &Self::FindKeyValuesByPrefix,
889906
) -> Result<Vec<(Vec<u8>, Vec<u8>)>, ExecutionError>;
890907

908+
/// Creates the promise to access key/values in a specific interval.
909+
fn find_key_values_in_interval_new(
910+
&mut self,
911+
key_interval: KeyInterval,
912+
) -> Result<Self::FindKeyValuesInInterval, ExecutionError>;
913+
914+
/// Resolves the promise to access key/values in a specific interval.
915+
fn find_key_values_in_interval_wait(
916+
&mut self,
917+
promise: &Self::FindKeyValuesInInterval,
918+
) -> Result<IntervalKeyValues, ExecutionError>;
919+
891920
/// Makes an HTTP request to the given URL and returns the answer, if any.
892921
fn perform_http_request(
893922
&mut self,

linera-execution/src/runtime.rs

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use linera_base::{
2222
time::Instant,
2323
vm::VmRuntime,
2424
};
25-
use linera_views::batch::Batch;
25+
use linera_views::{batch::Batch, store::KeyInterval};
2626
use oneshot::Receiver;
2727
use tracing::instrument;
2828

@@ -251,6 +251,8 @@ impl<T> QueryManager<T> {
251251
type Keys = Vec<Vec<u8>>;
252252
type Value = Vec<u8>;
253253
type KeyValues = Vec<(Vec<u8>, Vec<u8>)>;
254+
type IntervalKeys = (Vec<Vec<u8>>, bool);
255+
type IntervalKeyValues = (Vec<(Vec<u8>, Vec<u8>)>, bool);
254256

255257
#[derive(Debug, Default)]
256258
struct ViewUserState {
@@ -266,6 +268,10 @@ struct ViewUserState {
266268
find_keys_queries: QueryManager<Keys>,
267269
/// The find-key-values queries in progress.
268270
find_key_values_queries: QueryManager<KeyValues>,
271+
/// The find-keys-in-interval queries in progress.
272+
find_keys_in_interval_queries: QueryManager<IntervalKeys>,
273+
/// The find-key-values-in-interval queries in progress.
274+
find_key_values_in_interval_queries: QueryManager<IntervalKeyValues>,
269275
}
270276

271277
impl ViewUserState {
@@ -276,6 +282,8 @@ impl ViewUserState {
276282
self.read_multi_values_queries.force_all()?;
277283
self.find_keys_queries.force_all()?;
278284
self.find_key_values_queries.force_all()?;
285+
self.find_keys_in_interval_queries.force_all()?;
286+
self.find_key_values_in_interval_queries.force_all()?;
279287
Ok(())
280288
}
281289
}
@@ -599,6 +607,8 @@ where
599607
type ReadMultiValuesBytes = u32;
600608
type FindKeysByPrefix = u32;
601609
type FindKeyValuesByPrefix = u32;
610+
type FindKeysInInterval = u32;
611+
type FindKeyValuesInInterval = u32;
602612

603613
fn chain_id(&mut self) -> Result<ChainId, ExecutionError> {
604614
let mut this = self.inner();
@@ -930,6 +940,77 @@ where
930940
Ok(key_values)
931941
}
932942

943+
fn find_keys_in_interval_new(
944+
&mut self,
945+
key_interval: KeyInterval,
946+
) -> Result<Self::FindKeysInInterval, ExecutionError> {
947+
let mut this = self.inner();
948+
let id = this.current_application().id;
949+
this.resource_controller.track_read_operation()?;
950+
let receiver = this.execution_state_sender.send_request(move |callback| {
951+
ExecutionRequest::FindKeysInInterval {
952+
id,
953+
key_interval,
954+
callback,
955+
}
956+
})?;
957+
let state = this.view_user_states.entry(id).or_default();
958+
state.find_keys_in_interval_queries.register(receiver)
959+
}
960+
961+
fn find_keys_in_interval_wait(
962+
&mut self,
963+
promise: &Self::FindKeysInInterval,
964+
) -> Result<(Vec<Vec<u8>>, bool), ExecutionError> {
965+
let mut this = self.inner();
966+
let id = this.current_application().id;
967+
let (keys, is_finished) = {
968+
let state = this.view_user_states.entry(id).or_default();
969+
state.find_keys_in_interval_queries.wait(*promise)?
970+
};
971+
let read_size = keys.iter().map(Vec::len).sum::<usize>();
972+
this.resource_controller
973+
.track_bytes_read(read_size as u64)?;
974+
Ok((keys, is_finished))
975+
}
976+
977+
fn find_key_values_in_interval_new(
978+
&mut self,
979+
key_interval: KeyInterval,
980+
) -> Result<Self::FindKeyValuesInInterval, ExecutionError> {
981+
let mut this = self.inner();
982+
let id = this.current_application().id;
983+
this.resource_controller.track_read_operation()?;
984+
let receiver = this.execution_state_sender.send_request(move |callback| {
985+
ExecutionRequest::FindKeyValuesInInterval {
986+
id,
987+
key_interval,
988+
callback,
989+
}
990+
})?;
991+
let state = this.view_user_states.entry(id).or_default();
992+
state.find_key_values_in_interval_queries.register(receiver)
993+
}
994+
995+
fn find_key_values_in_interval_wait(
996+
&mut self,
997+
promise: &Self::FindKeyValuesInInterval,
998+
) -> Result<(Vec<(Vec<u8>, Vec<u8>)>, bool), ExecutionError> {
999+
let mut this = self.inner();
1000+
let id = this.current_application().id;
1001+
let (key_values, is_finished) = {
1002+
let state = this.view_user_states.entry(id).or_default();
1003+
state.find_key_values_in_interval_queries.wait(*promise)?
1004+
};
1005+
let read_size = key_values
1006+
.iter()
1007+
.map(|(key, value)| key.len() + value.len())
1008+
.sum::<usize>();
1009+
this.resource_controller
1010+
.track_bytes_read(read_size as u64)?;
1011+
Ok((key_values, is_finished))
1012+
}
1013+
9331014
fn perform_http_request(
9341015
&mut self,
9351016
request: http::Request,

0 commit comments

Comments
 (0)