Move profiling metadata collecting to function (#8198)

This commit is contained in:
Jakub Žádník 2023-02-25 00:29:07 +02:00 committed by GitHub
parent 42f0b55de0
commit e93a8b1d32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,7 +5,7 @@ use nu_protocol::{
Argument, Assignment, Bits, Block, Boolean, Call, Comparison, Expr, Expression, Math,
Operator, PathMember, PipelineElement, Redirection,
},
engine::{EngineState, Stack},
engine::{EngineState, ProfilingConfig, Stack},
Config, DataSource, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData,
PipelineMetadata, Range, ShellError, Span, Spanned, Unit, Value, VarId, ENV_VARIABLE_ID,
};
@ -1046,95 +1046,23 @@ pub fn eval_block(
if let (Some(start_time), Some(end_time), Some(input_metadata)) =
(start_time, end_time, input_metadata.as_deref_mut())
{
let span = pipeline.elements[i].span();
let element_str = Value::string(
String::from_utf8_lossy(
engine_state.get_span_contents(&pipeline.elements[i].span()),
),
span,
let element_span = pipeline.elements[i].span();
let element_str = String::from_utf8_lossy(
engine_state.get_span_contents(&pipeline.elements[i].span()),
)
.to_string();
collect_profiling_metadata(
pipeline_idx,
i,
element_str,
element_span,
start_time,
end_time,
&stack.profiling_config,
&eval_result,
input_metadata,
);
let time_ns = (end_time - start_time).as_nanos() as i64;
let mut cols = vec![
"pipeline_idx".to_string(),
"element_idx".to_string(),
"depth".to_string(),
"span".to_string(),
];
let mut vals = vec![
Value::int(pipeline_idx as i64, span),
Value::int(i as i64, span),
Value::int(stack.profiling_config.depth, span),
Value::record(
vec!["start".to_string(), "end".to_string()],
vec![
Value::int(span.start as i64, span),
Value::int(span.end as i64, span),
],
span,
),
];
if stack.profiling_config.collect_source {
cols.push("source".to_string());
vals.push(element_str.clone());
}
if stack.profiling_config.collect_values {
let value = match &eval_result {
Ok((PipelineData::Value(val, ..), ..)) => val.clone(),
Ok((PipelineData::ListStream(..), ..)) => {
Value::string("list stream", span)
}
Ok((PipelineData::ExternalStream { .. }, ..)) => {
Value::string("raw stream", span)
}
Ok((PipelineData::Empty, ..)) => Value::Nothing { span },
Err(err) => Value::Error { error: err.clone() },
};
cols.push("value".to_string());
vals.push(value);
}
cols.push("time".to_string());
vals.push(Value::Duration { val: time_ns, span });
let record = Value::Record { cols, vals, span };
let element_metadata = if let Ok((pipeline_data, ..)) = &eval_result {
pipeline_data.metadata()
} else {
None
};
if let PipelineMetadata {
data_source: DataSource::Profiling(tgt_vals),
} = input_metadata
{
tgt_vals.push(record);
} else {
*input_metadata = PipelineMetadata {
data_source: DataSource::Profiling(vec![record]),
};
}
if let Some(PipelineMetadata {
data_source: DataSource::Profiling(element_vals),
}) = element_metadata.map(|m| *m)
{
if let PipelineMetadata {
data_source: DataSource::Profiling(tgt_vals),
} = input_metadata
{
tgt_vals.extend(element_vals);
} else {
*input_metadata = PipelineMetadata {
data_source: DataSource::Profiling(element_vals),
};
}
}
}
match (eval_result, redirect_stderr) {
@ -1441,3 +1369,105 @@ fn compute(size: i64, unit: Unit, span: Span) -> Value {
},
}
}
#[allow(clippy::too_many_arguments)]
fn collect_profiling_metadata(
pipeline_idx: usize,
element_idx: usize,
element_str: String,
element_span: Span,
start_time: Instant,
end_time: Instant,
profiling_config: &ProfilingConfig,
eval_result: &Result<(PipelineData, bool), ShellError>,
input_metadata: &mut PipelineMetadata,
) {
let element_str = Value::string(element_str, element_span);
let time_ns = (end_time - start_time).as_nanos() as i64;
let mut cols = vec![
"pipeline_idx".to_string(),
"element_idx".to_string(),
"depth".to_string(),
"span".to_string(),
];
let mut vals = vec![
Value::int(pipeline_idx as i64, element_span),
Value::int(element_idx as i64, element_span),
Value::int(profiling_config.depth, element_span),
Value::record(
vec!["start".to_string(), "end".to_string()],
vec![
Value::int(element_span.start as i64, element_span),
Value::int(element_span.end as i64, element_span),
],
element_span,
),
];
if profiling_config.collect_source {
cols.push("source".to_string());
vals.push(element_str);
}
if profiling_config.collect_values {
let value = match &eval_result {
Ok((PipelineData::Value(val, ..), ..)) => val.clone(),
Ok((PipelineData::ListStream(..), ..)) => Value::string("list stream", element_span),
Ok((PipelineData::ExternalStream { .. }, ..)) => {
Value::string("raw stream", element_span)
}
Ok((PipelineData::Empty, ..)) => Value::Nothing { span: element_span },
Err(err) => Value::Error { error: err.clone() },
};
cols.push("value".to_string());
vals.push(value);
}
cols.push("time".to_string());
vals.push(Value::Duration {
val: time_ns,
span: element_span,
});
let record = Value::Record {
cols,
vals,
span: element_span,
};
let element_metadata = if let Ok((pipeline_data, ..)) = &eval_result {
pipeline_data.metadata()
} else {
None
};
if let PipelineMetadata {
data_source: DataSource::Profiling(tgt_vals),
} = input_metadata
{
tgt_vals.push(record);
} else {
*input_metadata = PipelineMetadata {
data_source: DataSource::Profiling(vec![record]),
};
}
if let Some(PipelineMetadata {
data_source: DataSource::Profiling(element_vals),
}) = element_metadata.map(|m| *m)
{
if let PipelineMetadata {
data_source: DataSource::Profiling(tgt_vals),
} = input_metadata
{
tgt_vals.extend(element_vals);
} else {
*input_metadata = PipelineMetadata {
data_source: DataSource::Profiling(element_vals),
};
}
}
}