Rename subtree to subgraph (#265)

Intially, a fold instruction was designed based on idea that its iterable can't expand,
so AIR was considered as a subtree. But after introducing recursive streams in #225, it's
no more a subtree, but a subgraph.
This commit is contained in:
Mike Voronov 2022-05-17 15:53:33 +03:00 committed by GitHub
parent dbd42cdf3d
commit 24f0d66bed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 146 additions and 146 deletions

View File

@ -182,4 +182,4 @@ and it's possible to address its fields separately: `%last_error%.$.instruction`
- Added join behaviour ([PR 11](https://github.com/fluencelabs/aquavm/pull/11)): - Added join behaviour ([PR 11](https://github.com/fluencelabs/aquavm/pull/11)):
- if `call` uses non existing variable, it is just being passed and isn't executed without any error - if `call` uses non existing variable, it is just being passed and isn't executed without any error
- `par` becomes completed when at least one of its subtree is completed - `par` becomes completed when at least one of its subgraph is completed

View File

@ -83,7 +83,7 @@ pub(crate) fn set_remote_call_result<'i>(
trace_ctx: &mut TraceHandler, trace_ctx: &mut TraceHandler,
) { ) {
exec_ctx.next_peer_pks.push(peer_pk); exec_ctx.next_peer_pks.push(peer_pk);
exec_ctx.subtree_complete = false; exec_ctx.subgraph_complete = false;
let new_call_result = CallResult::sent_peer_id(exec_ctx.run_parameters.current_peer_id.clone()); let new_call_result = CallResult::sent_peer_id(exec_ctx.run_parameters.current_peer_id.clone());
trace_ctx.meet_call_end(new_call_result); trace_ctx.meet_call_end(new_call_result);

View File

@ -50,7 +50,7 @@ pub(super) fn handle_prev_state<'i>(
// this call was failed on one of the previous executions, // this call was failed on one of the previous executions,
// here it's needed to bubble this special error up // here it's needed to bubble this special error up
CallServiceFailed(ret_code, err_msg) => { CallServiceFailed(ret_code, err_msg) => {
exec_ctx.subtree_complete = false; exec_ctx.subgraph_complete = false;
let ret_code = *ret_code; let ret_code = *ret_code;
let err_msg = err_msg.clone(); let err_msg = err_msg.clone();
trace_ctx.meet_call_end(prev_result); trace_ctx.meet_call_end(prev_result);
@ -67,7 +67,7 @@ pub(super) fn handle_prev_state<'i>(
} }
// result hasn't been prepared yet // result hasn't been prepared yet
None => { None => {
exec_ctx.subtree_complete = false; exec_ctx.subgraph_complete = false;
Ok(StateDescriptor::not_ready(prev_result)) Ok(StateDescriptor::not_ready(prev_result))
} }
} }
@ -79,7 +79,7 @@ pub(super) fn handle_prev_state<'i>(
return Ok(StateDescriptor::can_execute_now(prev_result)); return Ok(StateDescriptor::can_execute_now(prev_result));
} }
exec_ctx.subtree_complete = false; exec_ctx.subgraph_complete = false;
Ok(StateDescriptor::cant_execute_now(prev_result)) Ok(StateDescriptor::cant_execute_now(prev_result))
} }
// this instruction's been already executed // this instruction's been already executed

View File

@ -106,7 +106,7 @@ impl<'i> ResolvedCall<'i> {
let call_id = exec_ctx.next_call_request_id(); let call_id = exec_ctx.next_call_request_id();
exec_ctx.call_requests.insert(call_id, request_params); exec_ctx.call_requests.insert(call_id, request_params);
exec_ctx.subtree_complete = false; exec_ctx.subgraph_complete = false;
trace_ctx.meet_call_end(CallResult::sent_peer_id_with_call_id( trace_ctx.meet_call_end(CallResult::sent_peer_id_with_call_id(
exec_ctx.run_parameters.current_peer_id.clone(), exec_ctx.run_parameters.current_peer_id.clone(),
call_id, call_id,

View File

@ -94,7 +94,7 @@ fn fail_with_error_object(
exec_ctx exec_ctx
.last_error_descriptor .last_error_descriptor
.set_from_error_object(error.clone(), tetraplet); .set_from_error_object(error.clone(), tetraplet);
exec_ctx.subtree_complete = false; exec_ctx.subgraph_complete = false;
Err(ExecutionError::Catchable(Rc::new(CatchableError::UserError { error }))) Err(ExecutionError::Catchable(Rc::new(CatchableError::UserError { error })))
} }

View File

@ -98,12 +98,12 @@ fn execute_iterations<'i>(
trace_to_exec_err!(trace_ctx.meet_generation_end(fold_id), fold_stream)?; trace_to_exec_err!(trace_ctx.meet_generation_end(fold_id), fold_stream)?;
result?; result?;
if !exec_ctx.subtree_complete { if !exec_ctx.subgraph_complete {
break; break;
} }
} }
Ok(exec_ctx.subtree_complete) Ok(exec_ctx.subgraph_complete)
} }
fn should_stop_iteration(iteration_result: &ExecutionResult<bool>) -> bool { fn should_stop_iteration(iteration_result: &ExecutionResult<bool>) -> bool {

View File

@ -109,15 +109,15 @@ macro_rules! log_instruction {
$exec_ctx.next_peer_pks $exec_ctx.next_peer_pks
); );
log::trace!( log::trace!(
target: air_log_targets::SUBTREE_COMPLETE, target: air_log_targets::SUBGRAPH_COMPLETE,
" subtree complete: {}", " subgraph complete: {}",
$exec_ctx.subtree_complete $exec_ctx.subgraph_complete
); );
log::trace!( log::trace!(
target: air_log_targets::SUBTREE_ELEMENTS, target: air_log_targets::SUBGRAPH_ELEMENTS,
" subtree elements count: {:?}", " subgraph elements count: {:?}",
$trace_ctx.subtree_sizes() $trace_ctx.subgraph_sizes()
); );
log::debug!( log::debug!(
target: air_log_targets::NEW_EXECUTED_TRACE, target: air_log_targets::NEW_EXECUTED_TRACE,
@ -127,13 +127,13 @@ macro_rules! log_instruction {
}; };
} }
/// This macro converts joinable errors to Ok and sets subtree complete to false. /// This macro converts joinable errors to Ok and sets subgraph complete to false.
#[macro_export] #[macro_export]
macro_rules! joinable { macro_rules! joinable {
($cmd:expr, $exec_ctx:expr) => { ($cmd:expr, $exec_ctx:expr) => {
match $cmd { match $cmd {
Err(e) if e.is_joinable() => { Err(e) if e.is_joinable() => {
$exec_ctx.subtree_complete = false; $exec_ctx.subgraph_complete = false;
return Ok(()); return Ok(());
} }
v => v, v => v,

View File

@ -27,7 +27,7 @@ use crate::trace_to_exec_err;
use completeness_updater::ParCompletenessUpdater; use completeness_updater::ParCompletenessUpdater;
use air_parser::ast::Par; use air_parser::ast::Par;
use air_trace_handler::SubtreeType; use air_trace_handler::SubgraphType;
#[rustfmt::skip] #[rustfmt::skip]
impl<'i> ExecutableInstruction<'i> for Par<'i> { impl<'i> ExecutableInstruction<'i> for Par<'i> {
@ -37,72 +37,72 @@ impl<'i> ExecutableInstruction<'i> for Par<'i> {
let mut completeness_updater = ParCompletenessUpdater::new(); let mut completeness_updater = ParCompletenessUpdater::new();
trace_to_exec_err!(trace_ctx.meet_par_start(), self)?; trace_to_exec_err!(trace_ctx.meet_par_start(), self)?;
// execute a left subtree of par // execute a left subgraph of par
let left_result = execute_subtree(self, exec_ctx, trace_ctx, &mut completeness_updater, SubtreeType::Left)?; let left_result = execute_subgraph(self, exec_ctx, trace_ctx, &mut completeness_updater, SubgraphType::Left)?;
// execute a right subtree of par // execute a right subgraph of par
let right_result = execute_subtree(self, exec_ctx, trace_ctx, &mut completeness_updater, SubtreeType::Right)?; let right_result = execute_subgraph(self, exec_ctx, trace_ctx, &mut completeness_updater, SubgraphType::Right)?;
completeness_updater.set_completeness(exec_ctx); completeness_updater.set_completeness(exec_ctx);
prepare_par_result(left_result, right_result, exec_ctx) prepare_par_result(left_result, right_result, exec_ctx)
} }
} }
/// Execute provided subtree and update Par state in trace_ctx.new_trace. /// Execute provided subgraph and update Par state in trace_ctx.new_trace.
fn execute_subtree<'i>( fn execute_subgraph<'i>(
par: &Par<'i>, par: &Par<'i>,
exec_ctx: &mut ExecutionCtx<'i>, exec_ctx: &mut ExecutionCtx<'i>,
trace_ctx: &mut TraceHandler, trace_ctx: &mut TraceHandler,
completeness_updater: &mut ParCompletenessUpdater, completeness_updater: &mut ParCompletenessUpdater,
subtree_type: SubtreeType, subgraph_type: SubgraphType,
) -> ExecutionResult<SubtreeResult> { ) -> ExecutionResult<SubgraphResult> {
let subtree = match subtree_type { let subgraph = match subgraph_type {
SubtreeType::Left => &par.0, SubgraphType::Left => &par.0,
SubtreeType::Right => &par.1, SubgraphType::Right => &par.1,
}; };
exec_ctx.subtree_complete = determine_subtree_complete(subtree); exec_ctx.subgraph_complete = determine_subgraph_complete(subgraph);
// execute a subtree // execute a subgraph
let result = match subtree.execute(exec_ctx, trace_ctx) { let result = match subgraph.execute(exec_ctx, trace_ctx) {
Ok(_) => { Ok(_) => {
trace_to_exec_err!(trace_ctx.meet_par_subtree_end(subtree_type), par)?; trace_to_exec_err!(trace_ctx.meet_par_subgraph_end(subgraph_type), par)?;
SubtreeResult::Succeeded SubgraphResult::Succeeded
} }
Err(e) if e.is_catchable() => { Err(e) if e.is_catchable() => {
exec_ctx.subtree_complete = false; exec_ctx.subgraph_complete = false;
trace_to_exec_err!(trace_ctx.meet_par_subtree_end(subtree_type), par)?; trace_to_exec_err!(trace_ctx.meet_par_subgraph_end(subgraph_type), par)?;
SubtreeResult::Failed(e) SubgraphResult::Failed(e)
} }
Err(e) => { Err(e) => {
exec_ctx.subtree_complete = false; exec_ctx.subgraph_complete = false;
return Err(e); return Err(e);
} }
}; };
completeness_updater.update_completeness(exec_ctx, subtree_type); completeness_updater.update_completeness(exec_ctx, subgraph_type);
Ok(result) Ok(result)
} }
enum SubtreeResult { enum SubgraphResult {
Succeeded, Succeeded,
Failed(ExecutionError), Failed(ExecutionError),
} }
fn prepare_par_result( fn prepare_par_result(
left_result: SubtreeResult, left_result: SubgraphResult,
right_result: SubtreeResult, right_result: SubgraphResult,
exec_ctx: &mut ExecutionCtx<'_>, exec_ctx: &mut ExecutionCtx<'_>,
) -> ExecutionResult<()> { ) -> ExecutionResult<()> {
match (left_result, right_result) { match (left_result, right_result) {
(SubtreeResult::Succeeded, _) | (_, SubtreeResult::Succeeded) => { (SubgraphResult::Succeeded, _) | (_, SubgraphResult::Succeeded) => {
exec_ctx.last_error_descriptor.meet_par_successed_end(); exec_ctx.last_error_descriptor.meet_par_successed_end();
Ok(()) Ok(())
} }
(SubtreeResult::Failed(_), SubtreeResult::Failed(err)) => Err(err), (SubgraphResult::Failed(_), SubgraphResult::Failed(err)) => Err(err),
} }
} }
fn determine_subtree_complete(next_instruction: &Instruction<'_>) -> bool { fn determine_subgraph_complete(next_instruction: &Instruction<'_>) -> bool {
// this is needed to prevent situation when on such pattern // this is needed to prevent situation when on such pattern
// (fold (Iterable i // (fold (Iterable i
// (par // (par
@ -110,6 +110,6 @@ fn determine_subtree_complete(next_instruction: &Instruction<'_>) -> bool {
// (next i) // (next i)
// ) // )
// ) // )
// par will be completed after the last next that wouldn't change subtree_complete // par will be completed after the last next that wouldn't change subgraph_complete
!matches!(next_instruction, Instruction::Next(_)) !matches!(next_instruction, Instruction::Next(_))
} }

View File

@ -15,32 +15,32 @@
*/ */
use super::ExecutionCtx; use super::ExecutionCtx;
use super::SubtreeType; use super::SubgraphType;
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub(super) struct ParCompletenessUpdater { pub(super) struct ParCompletenessUpdater {
left_subtree_complete: bool, left_subgraph_complete: bool,
right_subtree_complete: bool, right_subgraph_complete: bool,
} }
impl ParCompletenessUpdater { impl ParCompletenessUpdater {
pub(super) fn new() -> Self { pub(super) fn new() -> Self {
Self { Self {
left_subtree_complete: false, left_subgraph_complete: false,
right_subtree_complete: false, right_subgraph_complete: false,
} }
} }
pub(super) fn update_completeness(&mut self, exec_ctx: &ExecutionCtx<'_>, subtree_type: SubtreeType) { pub(super) fn update_completeness(&mut self, exec_ctx: &ExecutionCtx<'_>, subgraph_type: SubgraphType) {
match subtree_type { match subgraph_type {
SubtreeType::Left => self.left_subtree_complete = exec_ctx.subtree_complete, SubgraphType::Left => self.left_subgraph_complete = exec_ctx.subgraph_complete,
SubtreeType::Right => self.right_subtree_complete = exec_ctx.subtree_complete, SubgraphType::Right => self.right_subgraph_complete = exec_ctx.subgraph_complete,
} }
} }
pub(super) fn set_completeness(self, exec_ctx: &mut ExecutionCtx<'_>) { pub(super) fn set_completeness(self, exec_ctx: &mut ExecutionCtx<'_>) {
// par is completed if at least one of its subtrees is completed // par is completed if at least one of its subgraphs is completed
let subtree_complete = self.left_subtree_complete || self.right_subtree_complete; let subgraph_complete = self.left_subgraph_complete || self.right_subgraph_complete;
exec_ctx.subtree_complete = subtree_complete; exec_ctx.subgraph_complete = subgraph_complete;
} }
} }

View File

@ -25,10 +25,10 @@ impl<'i> super::ExecutableInstruction<'i> for Seq<'i> {
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> { fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
log_instruction!(seq, exec_ctx, trace_ctx); log_instruction!(seq, exec_ctx, trace_ctx);
exec_ctx.subtree_complete = true; exec_ctx.subgraph_complete = true;
self.0.execute(exec_ctx, trace_ctx)?; self.0.execute(exec_ctx, trace_ctx)?;
if exec_ctx.subtree_complete { if exec_ctx.subgraph_complete {
self.1.execute(exec_ctx, trace_ctx)?; self.1.execute(exec_ctx, trace_ctx)?;
} }

View File

@ -26,10 +26,10 @@ impl<'i> super::ExecutableInstruction<'i> for Xor<'i> {
fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> { fn execute(&self, exec_ctx: &mut ExecutionCtx<'i>, trace_ctx: &mut TraceHandler) -> ExecutionResult<()> {
log_instruction!(xor, exec_ctx, trace_ctx); log_instruction!(xor, exec_ctx, trace_ctx);
exec_ctx.subtree_complete = true; exec_ctx.subgraph_complete = true;
match self.0.execute(exec_ctx, trace_ctx) { match self.0.execute(exec_ctx, trace_ctx) {
Err(e) if e.is_catchable() => { Err(e) if e.is_catchable() => {
exec_ctx.subtree_complete = true; exec_ctx.subgraph_complete = true;
exec_ctx.last_error_descriptor.meet_xor_right_branch(); exec_ctx.last_error_descriptor.meet_xor_right_branch();
print_xor_log(&e); print_xor_log(&e);
@ -44,7 +44,7 @@ fn print_xor_log(e: &ExecutionError) {
if e.is_match_or_mismatch() { if e.is_match_or_mismatch() {
// These errors actually aren't real errors, but a way to bubble execution_step up from match // These errors actually aren't real errors, but a way to bubble execution_step up from match
// to a corresponding xor. They'll become errors iff there is no such xor and execution_step is // to a corresponding xor. They'll become errors iff there is no such xor and execution_step is
// bubble up until the very beginning of current subtree. So the error message shouldn't // bubble up until the very beginning of current subgraph. So the error message shouldn't
// be print out in order not to confuse users. // be print out in order not to confuse users.
return; return;
} }

View File

@ -43,13 +43,13 @@ pub(crate) struct ExecutionCtx<'i> {
/// None means that there weren't any error. /// None means that there weren't any error.
pub(crate) last_error_descriptor: LastErrorDescriptor, pub(crate) last_error_descriptor: LastErrorDescriptor,
/// Indicates that previous executed subtree is complete. /// Indicates that previous executed subgraph is complete.
/// A subtree treats as a complete if all subtree elements satisfy the following rules: /// A subgraph treats as a complete if all subgraph elements satisfy the following rules:
/// - at least one of par subtrees is completed /// - at least one of par subgraphs is completed
/// - at least one of xor subtrees is completed without an error /// - at least one of xor subgraphs is completed without an error
/// - all of seq subtrees are completed /// - all of seq subgraphs are completed
/// - call executed successfully (executed state is Executed) /// - call executed successfully (executed state is Executed)
pub(crate) subtree_complete: bool, pub(crate) subgraph_complete: bool,
/// Tracker of all met instructions. /// Tracker of all met instructions.
pub(crate) tracker: InstructionTracker, pub(crate) tracker: InstructionTracker,
@ -70,7 +70,7 @@ impl<'i> ExecutionCtx<'i> {
Self { Self {
run_parameters, run_parameters,
subtree_complete: true, subgraph_complete: true,
last_call_request_id, last_call_request_id,
call_results, call_results,
..<_>::default() ..<_>::default()
@ -123,7 +123,7 @@ impl<'i> Display for ExecutionCtx<'i> {
writeln!(f, "current peer id: {}", self.run_parameters.current_peer_id)?; writeln!(f, "current peer id: {}", self.run_parameters.current_peer_id)?;
writeln!(f, "init peer id: {}", self.run_parameters.init_peer_id)?; writeln!(f, "init peer id: {}", self.run_parameters.init_peer_id)?;
writeln!(f, "timestamp: {}", self.run_parameters.timestamp)?; writeln!(f, "timestamp: {}", self.run_parameters.timestamp)?;
writeln!(f, "subtree complete: {}", self.subtree_complete)?; writeln!(f, "subgraph complete: {}", self.subgraph_complete)?;
writeln!(f, "next peer public keys: {:?}", self.next_peer_pks)?; writeln!(f, "next peer public keys: {:?}", self.next_peer_pks)?;
Ok(()) Ok(())

View File

@ -73,7 +73,7 @@ pub(crate) struct Scalars<'i> {
/// Terminology used here (mainly to resolve concerns re difference between scalars and values): /// Terminology used here (mainly to resolve concerns re difference between scalars and values):
/// - scalar is an AIR scalar, iterable and non iterable. A scalar is addressed by a name. /// - scalar is an AIR scalar, iterable and non iterable. A scalar is addressed by a name.
/// - value is concrete value assigned to scalar on certain depth /// - value is concrete value assigned to scalar on certain depth
/// - scope is a variable scope where variable is visible. If we consider fold as a tree where /// - scope is a variable scope where variable is visible. If we consider fold as a graph where
/// each next produces a new level, then scope is a level in this tree. Please note that it /// each next produces a new level, then scope is a level in this tree. Please note that it
/// includes variable defined after next instruction. /// includes variable defined after next instruction.
/// - depth is a count of seen scopes (or a depth in a tree met in the previous definition) /// - depth is a count of seen scopes (or a depth in a tree met in the previous definition)

View File

@ -280,7 +280,7 @@ fn access_last_error_by_not_exists_field() {
} }
#[test] #[test]
fn last_error_with_par_one_subtree_failed() { fn last_error_with_par_one_subgraph_failed() {
let fallible_peer_id = "fallible_peer_id"; let fallible_peer_id = "fallible_peer_id";
let fallible_call_service_name = "fallible_call_service"; let fallible_call_service_name = "fallible_call_service";
let mut fallible_vm = create_avm(fallible_call_service(fallible_call_service_name), fallible_peer_id); let mut fallible_vm = create_avm(fallible_call_service(fallible_call_service_name), fallible_peer_id);

View File

@ -34,7 +34,7 @@ fn par_ap_behaviour() {
(seq (seq
(par (par
(call "{relay_id}" ("peer" "timeout") [join_it] $result) (call "{relay_id}" ("peer" "timeout") [join_it] $result)
(ap "fast_result" $result) ;; ap doesn't affect the subtree_complete flag (ap "fast_result" $result) ;; ap doesn't affect the subgraph_complete flag
) )
(call "{client_id}" ("op" "return") [$result.$[0]]) (call "{client_id}" ("op" "return") [$result.$[0]])
) )

View File

@ -28,8 +28,8 @@ fn issue_180() {
(call "{peer_2_id}" ("" "") [] join_var) (call "{peer_2_id}" ("" "") [] join_var)
(seq (seq
(par (par
(call "{peer_1_id}" ("" "") [join_var]) ;; sets subtree_complete to false (call "{peer_1_id}" ("" "") [join_var]) ;; sets subgraph_complete to false
(fold join_var iterator ;; (on < 0.17.3) triggers ValueNotFound exception and doesn't touch subtree_complete flag (fold join_var iterator ;; (on < 0.17.3) triggers ValueNotFound exception and doesn't touch subgraph_complete flag
(null) (null)
) )
) )

View File

@ -68,10 +68,10 @@ impl SubTraceDesc {
} }
impl ExecutedState { impl ExecutedState {
pub fn par(left_subtree_size: usize, right_subtree_size: usize) -> Self { pub fn par(left_subgraph_size: usize, right_subgraph_size: usize) -> Self {
let par_result = ParResult { let par_result = ParResult {
left_size: left_subtree_size as _, left_size: left_subgraph_size as _,
right_size: right_subtree_size as _, right_size: right_subgraph_size as _,
}; };
Self::Par(par_result) Self::Par(par_result)
@ -93,9 +93,9 @@ impl std::fmt::Display for ExecutedState {
match self { match self {
Par(ParResult { Par(ParResult {
left_size: left_subtree_size, left_size: left_subgraph_size,
right_size: right_subtree_size, right_size: right_subgraph_size,
}) => write!(f, "par({}, {})", left_subtree_size, right_subtree_size), }) => write!(f, "par({}, {})", left_subgraph_size, right_subgraph_size),
Call(RequestSentBy(sender)) => write!(f, r"{}", sender), Call(RequestSentBy(sender)) => write!(f, r"{}", sender),
Call(Executed(value)) => { Call(Executed(value)) => {
write!(f, "executed({})", value) write!(f, "executed({})", value)

View File

@ -23,11 +23,11 @@ pub const DATA_CACHE: &str = "data_cache";
/// Print out next_peer_pks at the beginning of each instruction execution_step. /// Print out next_peer_pks at the beginning of each instruction execution_step.
pub const NEXT_PEER_PKS: &str = "next_peer_pks"; pub const NEXT_PEER_PKS: &str = "next_peer_pks";
/// Print out subtree_complete value at the beginning of each instruction execution_step. /// Print out subgraph_complete value at the beginning of each instruction execution_step.
pub const SUBTREE_COMPLETE: &str = "subtree_complete"; pub const SUBGRAPH_COMPLETE: &str = "subgraph_complete";
/// Print out count of element in the current subtree at the beginning of each instruction execution_step. /// Print out count of element in the current subgraph at the beginning of each instruction execution_step.
pub const SUBTREE_ELEMENTS: &str = "subtree_elements_count"; pub const SUBGRAPH_ELEMENTS: &str = "subgraph_elements_count";
/// Print out state of data cache at the beginning of each instruction execution_step. /// Print out state of data cache at the beginning of each instruction execution_step.
pub const NEW_EXECUTED_TRACE: &str = "new_executed_trace"; pub const NEW_EXECUTED_TRACE: &str = "new_executed_trace";
@ -49,8 +49,8 @@ pub const TARGET_MAP: [(&str, i32); 10] = [
(INSTRUCTION, 1 << 1), (INSTRUCTION, 1 << 1),
(DATA_CACHE, 1 << 2), (DATA_CACHE, 1 << 2),
(NEXT_PEER_PKS, 1 << 3), (NEXT_PEER_PKS, 1 << 3),
(SUBTREE_COMPLETE, 1 << 4), (SUBGRAPH_COMPLETE, 1 << 4),
(SUBTREE_ELEMENTS, 1 << 5), (SUBGRAPH_ELEMENTS, 1 << 5),
(NEW_EXECUTED_TRACE, 1 << 6), (NEW_EXECUTED_TRACE, 1 << 6),
(EXECUTED_TRACE_MERGE, 1 << 7), (EXECUTED_TRACE_MERGE, 1 << 7),
(RUN_PARAMS, 1 << 8), (RUN_PARAMS, 1 << 8),

View File

@ -23,8 +23,8 @@ meet_call_start
Expected sequence of `TraceHandler` calls for the `par` instruction: Expected sequence of `TraceHandler` calls for the `par` instruction:
``` ```
meet_par_start meet_par_start
-> meet_par_subtree_end(..., SubtreeType::Left) -> meet_par_subgraph_end(..., SubgraphType::Left)
-> meet_par_subtree_end(..., SubtreeType::Right) -> meet_par_subgraph_end(..., SubgraphType::Right)
``` ```
### Fold instruction ### Fold instruction

View File

@ -50,7 +50,7 @@ impl TraceHandler {
&self.data_keeper.result_trace &self.data_keeper.result_trace
} }
pub fn subtree_sizes(&self) -> (usize, usize) { pub fn subgraph_sizes(&self) -> (usize, usize) {
let prev_len = self.data_keeper.prev_slider().subtrace_len(); let prev_len = self.data_keeper.prev_slider().subtrace_len();
let current_len = self.data_keeper.current_slider().subtrace_len(); let current_len = self.data_keeper.current_slider().subtrace_len();
@ -95,13 +95,13 @@ impl TraceHandler {
Ok(()) Ok(())
} }
pub fn meet_par_subtree_end(&mut self, subtree_type: SubtreeType) -> TraceHandlerResult<()> { pub fn meet_par_subgraph_end(&mut self, subgraph_type: SubgraphType) -> TraceHandlerResult<()> {
match subtree_type { match subgraph_type {
SubtreeType::Left => { SubgraphType::Left => {
let par_fsm = self.fsm_keeper.last_par()?; let par_fsm = self.fsm_keeper.last_par()?;
par_fsm.left_completed(&mut self.data_keeper); par_fsm.left_completed(&mut self.data_keeper);
} }
SubtreeType::Right => { SubgraphType::Right => {
let par_fsm = self.fsm_keeper.pop_par()?; let par_fsm = self.fsm_keeper.pop_par()?;
par_fsm.right_completed(&mut self.data_keeper); par_fsm.right_completed(&mut self.data_keeper);
} }

View File

@ -29,7 +29,7 @@ pub use merger::MergeCtxType;
pub use merger::MergeError; pub use merger::MergeError;
pub use merger::MergerApResult; pub use merger::MergerApResult;
pub use merger::MergerCallResult; pub use merger::MergerCallResult;
pub use state_automata::SubtreeType; pub use state_automata::SubgraphType;
pub type TraceHandlerResult<T> = std::result::Result<T, TraceHandlerError>; pub type TraceHandlerResult<T> = std::result::Result<T, TraceHandlerError>;

View File

@ -75,7 +75,7 @@ pub(super) fn resolve_fold_lore(fold: &FoldResult, merge_ctx: &MergeCtx) -> Merg
/// It could be seen that this function does a convolution of lens with respect to generations. /// It could be seen that this function does a convolution of lens with respect to generations.
/// This is needed to handle (fold (par (next ... cases, because of subtrace_len of a Fold state /// This is needed to handle (fold (par (next ... cases, because of subtrace_len of a Fold state
/// describes only states inside this iteration without states that next brings, however a Par /// describes only states inside this iteration without states that next brings, however a Par
/// lens describe the whole subtree, where "next" states are included. /// lens describe the whole subgraph, where "next" states are included.
// TODO: in future it's possible to change a format of a Fold state to one behaves like Par, // TODO: in future it's possible to change a format of a Fold state to one behaves like Par,
// because this function adds some overhead // because this function adds some overhead

View File

@ -41,7 +41,7 @@ pub enum StateFSMError {
#[error("overflow is occurred while calculating the new position of a {2} slider for resolved par {0:?} and current position {1}'")] #[error("overflow is occurred while calculating the new position of a {2} slider for resolved par {0:?} and current position {1}'")]
ParPosOverflow(ParResult, usize, MergeCtxType), ParPosOverflow(ParResult, usize, MergeCtxType),
/// Errors occurred when ParResult.0 + ParResult.1 value is bigger than current subtree size. /// Errors occurred when ParResult.0 + ParResult.1 value is bigger than current subgraph size.
#[error("underflow is occurred while calculating the new position of a {2} slider for resolved par {0:?} and current subtrace len {1}'")] #[error("underflow is occurred while calculating the new position of a {2} slider for resolved par {0:?} and current subtrace len {1}'")]
ParLenUnderflow(ParResult, usize, MergeCtxType), ParLenUnderflow(ParResult, usize, MergeCtxType),

View File

@ -18,7 +18,7 @@ use super::*;
use crate::MergeCtxType; use crate::MergeCtxType;
use crate::ResolvedFold; use crate::ResolvedFold;
/// This state updater manage to do the same thing as SubTreeStateUpdater in ParFSM, /// This state updater manage to do the same thing as CtxStateHandler in ParFSM,
/// for details please see its detailed comment. /// for details please see its detailed comment.
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub(super) struct CtxStateHandler { pub(super) struct CtxStateHandler {

View File

@ -22,7 +22,7 @@ mod state_inserter;
mod utils; mod utils;
pub use errors::StateFSMError; pub use errors::StateFSMError;
pub use par_fsm::SubtreeType; pub use par_fsm::SubgraphType;
pub(crate) type FSMResult<T> = std::result::Result<T, StateFSMError>; pub(crate) type FSMResult<T> = std::result::Result<T, StateFSMError>;

View File

@ -35,14 +35,14 @@ pub(crate) struct ParFSM {
} }
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum SubtreeType { pub enum SubgraphType {
Left, Left,
Right, Right,
} }
impl ParFSM { impl ParFSM {
pub(crate) fn from_left_started(ingredients: MergerParResult, data_keeper: &mut DataKeeper) -> FSMResult<Self> { pub(crate) fn from_left_started(ingredients: MergerParResult, data_keeper: &mut DataKeeper) -> FSMResult<Self> {
// default is a par with empty left and right subtrees // default is a par with empty left and right subgraphs
let prev_par = ingredients.prev_par.unwrap_or_default(); let prev_par = ingredients.prev_par.unwrap_or_default();
let current_par = ingredients.current_par.unwrap_or_default(); let current_par = ingredients.current_par.unwrap_or_default();
@ -58,31 +58,31 @@ impl ParFSM {
par_builder, par_builder,
}; };
par_fsm.prepare_sliders(data_keeper, SubtreeType::Left)?; par_fsm.prepare_sliders(data_keeper, SubgraphType::Left)?;
Ok(par_fsm) Ok(par_fsm)
} }
pub(crate) fn left_completed(&mut self, data_keeper: &mut DataKeeper) { pub(crate) fn left_completed(&mut self, data_keeper: &mut DataKeeper) {
self.par_builder.track(data_keeper, SubtreeType::Left); self.par_builder.track(data_keeper, SubgraphType::Left);
self.state_handler.handle_subtree_end(data_keeper, SubtreeType::Left); self.state_handler.handle_subgraph_end(data_keeper, SubgraphType::Left);
// all invariants were checked in the ctor // all invariants were checked in the ctor
let _ = self.prepare_sliders(data_keeper, SubtreeType::Right); let _ = self.prepare_sliders(data_keeper, SubgraphType::Right);
} }
pub(crate) fn right_completed(mut self, data_keeper: &mut DataKeeper) { pub(crate) fn right_completed(mut self, data_keeper: &mut DataKeeper) {
self.par_builder.track(data_keeper, SubtreeType::Right); self.par_builder.track(data_keeper, SubgraphType::Right);
let state = self.par_builder.build(); let state = self.par_builder.build();
self.state_inserter.insert(data_keeper, state); self.state_inserter.insert(data_keeper, state);
self.state_handler.handle_subtree_end(data_keeper, SubtreeType::Right); self.state_handler.handle_subgraph_end(data_keeper, SubgraphType::Right);
} }
fn prepare_sliders(&self, data_keeper: &mut DataKeeper, subtree_type: SubtreeType) -> FSMResult<()> { fn prepare_sliders(&self, data_keeper: &mut DataKeeper, subgraph_type: SubgraphType) -> FSMResult<()> {
let (prev_len, current_len) = match subtree_type { let (prev_len, current_len) = match subgraph_type {
SubtreeType::Left => (self.prev_par.left_size, self.current_par.left_size), SubgraphType::Left => (self.prev_par.left_size, self.current_par.left_size),
SubtreeType::Right => (self.prev_par.right_size, self.current_par.right_size), SubgraphType::Right => (self.prev_par.right_size, self.current_par.right_size),
}; };
data_keeper.prev_slider_mut().set_subtrace_len(prev_len as _)?; data_keeper.prev_slider_mut().set_subtrace_len(prev_len as _)?;
@ -94,11 +94,11 @@ impl ParFSM {
use std::fmt; use std::fmt;
impl fmt::Display for SubtreeType { impl fmt::Display for SubgraphType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
SubtreeType::Left => write!(f, "left"), SubgraphType::Left => write!(f, "left"),
SubtreeType::Right => write!(f, "right"), SubgraphType::Right => write!(f, "right"),
} }
} }
} }

View File

@ -20,37 +20,37 @@ use super::*;
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub(super) struct ParBuilder { pub(super) struct ParBuilder {
saved_states_count: usize, saved_states_count: usize,
left_subtree_size: usize, left_subgraph_size: usize,
right_subtree_size: usize, right_subgraph_size: usize,
} }
impl ParBuilder { impl ParBuilder {
// StateInserter here needs to guaranteed that ParBuilder creates after it, // StateInserter here needs to guaranteed that ParBuilder creates after it,
// it must be so to right track a left subtree size // it must be so to right track a left subgraph size
pub(super) fn from_keeper(data_keeper: &DataKeeper, _: &StateInserter) -> Self { pub(super) fn from_keeper(data_keeper: &DataKeeper, _: &StateInserter) -> Self {
let saved_states_count = data_keeper.result_states_count(); let saved_states_count = data_keeper.result_states_count();
Self { Self {
saved_states_count, saved_states_count,
left_subtree_size: 0, left_subgraph_size: 0,
right_subtree_size: 0, right_subgraph_size: 0,
} }
} }
pub(super) fn track(&mut self, data_keeper: &DataKeeper, subtree_type: SubtreeType) { pub(super) fn track(&mut self, data_keeper: &DataKeeper, subgraph_type: SubgraphType) {
let prev_states_count = self.saved_states_count; let prev_states_count = self.saved_states_count;
let states_count = data_keeper.result_states_count(); let states_count = data_keeper.result_states_count();
let resulted_states_count = states_count - prev_states_count; let resulted_states_count = states_count - prev_states_count;
match subtree_type { match subgraph_type {
SubtreeType::Left => self.left_subtree_size = resulted_states_count, SubgraphType::Left => self.left_subgraph_size = resulted_states_count,
SubtreeType::Right => self.right_subtree_size = resulted_states_count, SubgraphType::Right => self.right_subgraph_size = resulted_states_count,
} }
self.saved_states_count = data_keeper.result_trace.len(); self.saved_states_count = data_keeper.result_trace.len();
} }
pub(super) fn build(self) -> ExecutedState { pub(super) fn build(self) -> ExecutedState {
// TODO: check that usize could be converted into u32 // TODO: check that usize could be converted into u32
ExecutedState::par(self.left_subtree_size, self.right_subtree_size) ExecutedState::par(self.left_subgraph_size, self.right_subgraph_size)
} }
} }

View File

@ -23,12 +23,12 @@ use new_states_calculation::compute_new_states;
/// ///
/// To see why it's really needed, imagine the following trace: /// To see why it's really needed, imagine the following trace:
/// [par 9, 3] /// [par 9, 3]
/// [par 3, 5] <- left subtree of [par 9, 3] /// [par 3, 5] <- left subgraph of [par 9, 3]
/// [call rs 1] [call rs 2] [call rs 3] <- left subtree of [par 3, 5] /// [call rs 1] [call rs 2] [call rs 3] <- left subgraph of [par 3, 5]
/// [call rs 4] [call rs 5] [call rs 6] [call rs 7] [call rs 8] <- right subtree of [par 3, 5] /// [call rs 4] [call rs 5] [call rs 6] [call rs 7] [call rs 8] <- right subgraph of [par 3, 5]
/// [par 1, 1] <- right subtree of [par 9, 3] /// [par 1, 1] <- right subgraph of [par 9, 3]
/// [call e 9] <- left subtree of [par 1, 1] /// [call e 9] <- left subgraph of [par 1, 1]
/// [call e 10] <- right subtree of [par 1, 1] /// [call e 10] <- right subgraph of [par 1, 1]
/// ///
/// where /// where
/// call rs N - request sent state of Nth call /// call rs N - request sent state of Nth call
@ -50,7 +50,7 @@ use new_states_calculation::compute_new_states;
/// ) /// )
/// ///
/// Suppose that call 5 (corresponds to [call rs 5]) will fail (f.e. call_service returns a service /// Suppose that call 5 (corresponds to [call rs 5]) will fail (f.e. call_service returns a service
/// error). Since it's wrapped with xor, then right subtree of xor (null) will be executed. /// error). Since it's wrapped with xor, then right subgraph of xor (null) will be executed.
/// After that next par will be executed. This par has corresponding state [par 1, 1] in a trace, /// After that next par will be executed. This par has corresponding state [par 1, 1] in a trace,
/// and to allow slider to pop it it's needed to set updated position in a proper way, because /// and to allow slider to pop it it's needed to set updated position in a proper way, because
/// otherwise [call rs 6] will be returned. /// otherwise [call rs 6] will be returned.
@ -65,24 +65,24 @@ pub(super) struct CtxStateHandler {
} }
impl CtxStateHandler { impl CtxStateHandler {
/// Prepare new states that sliders will have after finishing executing of each subtree. /// Prepare new states that sliders will have after finishing executing of each subgraph.
pub(super) fn prepare( pub(super) fn prepare(
prev_par: ParResult, prev_par: ParResult,
current_par: ParResult, current_par: ParResult,
data_keeper: &mut DataKeeper, data_keeper: &mut DataKeeper,
) -> FSMResult<Self> { ) -> FSMResult<Self> {
let left_pair = compute_new_states(data_keeper, prev_par, current_par, SubtreeType::Left)?; let left_pair = compute_new_states(data_keeper, prev_par, current_par, SubgraphType::Left)?;
let right_pair = compute_new_states(data_keeper, prev_par, current_par, SubtreeType::Right)?; let right_pair = compute_new_states(data_keeper, prev_par, current_par, SubgraphType::Right)?;
let handler = Self { left_pair, right_pair }; let handler = Self { left_pair, right_pair };
Ok(handler) Ok(handler)
} }
pub(super) fn handle_subtree_end(self, data_keeper: &mut DataKeeper, subtree_type: SubtreeType) { pub(super) fn handle_subgraph_end(self, data_keeper: &mut DataKeeper, subgraph_type: SubgraphType) {
match subtree_type { match subgraph_type {
SubtreeType::Left => update_ctx_states(self.left_pair, data_keeper), SubgraphType::Left => update_ctx_states(self.left_pair, data_keeper),
SubtreeType::Right => update_ctx_states(self.right_pair, data_keeper), SubgraphType::Right => update_ctx_states(self.right_pair, data_keeper),
} }
} }
} }

View File

@ -21,11 +21,11 @@ pub(super) fn compute_new_states(
data_keeper: &DataKeeper, data_keeper: &DataKeeper,
prev_par: ParResult, prev_par: ParResult,
current_par: ParResult, current_par: ParResult,
subtree_type: SubtreeType, subgraph_type: SubgraphType,
) -> FSMResult<CtxStatesPair> { ) -> FSMResult<CtxStatesPair> {
let (prev_len, current_len) = match subtree_type { let (prev_len, current_len) = match subgraph_type {
SubtreeType::Left => (prev_par.left_size, current_par.left_size), SubgraphType::Left => (prev_par.left_size, current_par.left_size),
SubtreeType::Right => { SubgraphType::Right => {
let prev_par_size = prev_par.size().ok_or(StateFSMError::ParLenOverflow(prev_par))?; let prev_par_size = prev_par.size().ok_or(StateFSMError::ParLenOverflow(prev_par))?;
let current_par_size = current_par.size().ok_or(StateFSMError::ParLenOverflow(current_par))?; let current_par_size = current_par.size().ok_or(StateFSMError::ParLenOverflow(current_par))?;
@ -40,15 +40,15 @@ pub(super) fn compute_new_states(
Ok(pair) Ok(pair)
} }
fn compute_new_state(par_subtree_len: usize, slider: &TraceSlider, par: ParResult) -> FSMResult<CtxState> { fn compute_new_state(par_subgraph_len: usize, slider: &TraceSlider, par: ParResult) -> FSMResult<CtxState> {
let pos = slider let pos = slider
.position() .position()
.checked_add(par_subtree_len) .checked_add(par_subgraph_len)
.ok_or_else(|| StateFSMError::ParPosOverflow(par, slider.position(), MergeCtxType::Previous))?; .ok_or_else(|| StateFSMError::ParPosOverflow(par, slider.position(), MergeCtxType::Previous))?;
let subtrace_len = slider let subtrace_len = slider
.subtrace_len() .subtrace_len()
.checked_sub(par_subtree_len) .checked_sub(par_subgraph_len)
.ok_or_else(|| StateFSMError::ParLenUnderflow(par, slider.subtrace_len(), MergeCtxType::Current))?; .ok_or_else(|| StateFSMError::ParLenUnderflow(par, slider.subtrace_len(), MergeCtxType::Current))?;
let new_state = CtxState::new(pos, subtrace_len); let new_state = CtxState::new(pos, subtrace_len);