Skip to content

Commit 2a2f39a

Browse files
committed
Directly extract a Digest from a PyDigest: missed optimization from pantsbuild#10905.
# Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
1 parent 2e5067f commit 2a2f39a

File tree

5 files changed

+46
-59
lines changed

5 files changed

+46
-59
lines changed

src/rust/engine/src/externs/engine_aware.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub struct Artifacts {}
8888
impl EngineAwareInformation for Artifacts {
8989
type MaybeOutput = Vec<(String, Digest)>;
9090

91-
fn retrieve(types: &Types, value: &Value) -> Option<Self::MaybeOutput> {
91+
fn retrieve(_types: &Types, value: &Value) -> Option<Self::MaybeOutput> {
9292
let artifacts_val = match externs::call_method(&value, "artifacts", &[]) {
9393
Ok(value) => value,
9494
Err(py_err) => {
@@ -119,7 +119,7 @@ impl EngineAwareInformation for Artifacts {
119119
log::error!("Error in EngineAware.artifacts() - no `digest` attr: {}", e);
120120
})
121121
.ok()?;
122-
let digest = match lift_directory_digest(types, &Value::new(digest_value)) {
122+
let digest = match lift_directory_digest(&Value::new(digest_value)) {
123123
Ok(digest) => digest,
124124
Err(e) => {
125125
log::error!("Error in EngineAware.artifacts() implementation: {}", e);

src/rust/engine/src/externs/fs.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,25 @@ use fs::PathStat;
4545
use hashing::{Digest, Fingerprint};
4646
use store::Snapshot;
4747

48+
///
49+
/// Data members and `create_instance` methods are module-private by default, so we expose them
50+
/// with public top-level functions.
51+
///
4852
/// TODO: See https://github.com/dgrunwald/rust-cpython/issues/242
49-
pub fn new_py_digest(digest: Digest) -> PyResult<PyDigest> {
53+
///
54+
55+
pub fn to_py_digest(digest: Digest) -> PyResult<PyDigest> {
5056
let gil = Python::acquire_gil();
5157
PyDigest::create_instance(gil.python(), digest)
5258
}
5359

60+
pub fn from_py_digest(digest: &PyObject) -> PyResult<Digest> {
61+
let gil = Python::acquire_gil();
62+
let py = gil.python();
63+
let py_digest = digest.extract::<PyDigest>(py)?;
64+
Ok(*py_digest.digest(py))
65+
}
66+
5467
py_class!(pub class PyDigest |py| {
5568
data digest: Digest;
5669
def __new__(_cls, fingerprint: Cow<str>, serialized_bytes_length: usize) -> PyResult<Self> {
@@ -88,8 +101,7 @@ py_class!(pub class PyDigest |py| {
88101
}
89102
});
90103

91-
/// TODO: See https://github.com/dgrunwald/rust-cpython/issues/242
92-
pub fn new_py_snapshot(snapshot: Snapshot) -> PyResult<PySnapshot> {
104+
pub fn to_py_snapshot(snapshot: Snapshot) -> PyResult<PySnapshot> {
93105
let gil = Python::acquire_gil();
94106
PySnapshot::create_instance(gil.python(), snapshot)
95107
}
@@ -101,7 +113,7 @@ py_class!(pub class PySnapshot |py| {
101113
}
102114

103115
@property def digest(&self) -> PyResult<PyDigest> {
104-
new_py_digest(self.snapshot(py).digest)
116+
to_py_digest(self.snapshot(py).digest)
105117
}
106118

107119
@property def files(&self) -> PyResult<PyTuple> {

src/rust/engine/src/externs/interface.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -1562,10 +1562,7 @@ fn capture_snapshots(
15621562
if maybe_digest == externs::none() {
15631563
None
15641564
} else {
1565-
Some(nodes::lift_directory_digest(
1566-
&core.types,
1567-
&Value::new(maybe_digest),
1568-
)?)
1565+
Some(nodes::lift_directory_digest(&Value::new(maybe_digest))?)
15691566
}
15701567
};
15711568
path_globs.map(|path_globs| (path_globs, root, digest_hint))
@@ -1615,7 +1612,7 @@ fn ensure_remote_has_recursive(
16151612
.iter(py)
16161613
.map(|item| {
16171614
let value = item.into();
1618-
crate::nodes::lift_directory_digest(&core.types, &value)
1615+
crate::nodes::lift_directory_digest(&value)
16191616
.or_else(|_| crate::nodes::lift_file_digest(&core.types, &value))
16201617
})
16211618
.collect::<Result<Vec<Digest>, _>>()
@@ -1696,7 +1693,7 @@ fn run_local_interactive_process(
16961693

16971694
let run_in_workspace: bool = externs::getattr(&value, "run_in_workspace").unwrap();
16981695
let input_digest_value: Value = externs::getattr(&value, "input_digest").unwrap();
1699-
let input_digest: Digest = nodes::lift_directory_digest(types, &input_digest_value)?;
1696+
let input_digest: Digest = nodes::lift_directory_digest(&input_digest_value)?;
17001697
let hermetic_env: bool = externs::getattr(&value, "hermetic_env").unwrap();
17011698
let env = externs::getattr_from_frozendict(&value, "env");
17021699

@@ -1738,7 +1735,7 @@ fn write_digest(
17381735
// TODO: A parent_id should be an explicit argument.
17391736
session.workunit_store().init_thread_state(None);
17401737

1741-
let lifted_digest = nodes::lift_directory_digest(&scheduler.core.types, &digest.into())
1738+
let lifted_digest = nodes::lift_directory_digest(&digest.into())
17421739
.map_err(|e| PyErr::new::<exc::ValueError, _>(py, (e,)))?;
17431740

17441741
// Python will have already validated that path_prefix is a relative path.

src/rust/engine/src/intrinsics.rs

+15-21
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,12 @@ fn multi_platform_process_request_to_process_result(
141141
// TODO: The platform will be used in a followup.
142142
let _platform_val = &args[1];
143143

144-
let process_request = MultiPlatformExecuteProcess::lift(&context.core.types, process_val)
145-
.map_err(|str| {
146-
throw(&format!(
147-
"Error lifting MultiPlatformExecuteProcess: {}",
148-
str
149-
))
150-
})?;
144+
let process_request = MultiPlatformExecuteProcess::lift(process_val).map_err(|str| {
145+
throw(&format!(
146+
"Error lifting MultiPlatformExecuteProcess: {}",
147+
str
148+
))
149+
})?;
151150
let result = context.get(process_request).await?.0;
152151

153152
let maybe_stdout = context
@@ -205,7 +204,7 @@ fn directory_digest_to_digest_contents(
205204
args: Vec<Value>,
206205
) -> BoxFuture<'static, NodeResult<Value>> {
207206
async move {
208-
let digest = lift_directory_digest(&context.core.types, &args[0]).map_err(|s| throw(&s))?;
207+
let digest = lift_directory_digest(&args[0]).map_err(|s| throw(&s))?;
209208
let snapshot = context
210209
.core
211210
.store()
@@ -227,9 +226,8 @@ fn remove_prefix_request_to_digest(
227226
let store = core.store();
228227

229228
async move {
230-
let input_digest =
231-
lift_directory_digest(&core.types, &externs::getattr(&args[0], "digest").unwrap())
232-
.map_err(|e| throw(&e))?;
229+
let input_digest = lift_directory_digest(&externs::getattr(&args[0], "digest").unwrap())
230+
.map_err(|e| throw(&e))?;
233231
let prefix = externs::getattr_as_string(&args[0], "prefix");
234232
let prefix = RelativePath::new(PathBuf::from(prefix))
235233
.map_err(|e| throw(&format!("The `prefix` must be relative: {:?}", e)))?;
@@ -249,9 +247,8 @@ fn add_prefix_request_to_digest(
249247
let core = context.core;
250248
let store = core.store();
251249
async move {
252-
let input_digest =
253-
lift_directory_digest(&core.types, &externs::getattr(&args[0], "digest").unwrap())
254-
.map_err(|e| throw(&e))?;
250+
let input_digest = lift_directory_digest(&externs::getattr(&args[0], "digest").unwrap())
251+
.map_err(|e| throw(&e))?;
255252
let prefix = externs::getattr_as_string(&args[0], "prefix");
256253
let prefix = RelativePath::new(PathBuf::from(prefix))
257254
.map_err(|e| throw(&format!("The `prefix` must be relative: {:?}", e)))?;
@@ -267,7 +264,7 @@ fn add_prefix_request_to_digest(
267264
fn digest_to_snapshot(context: Context, args: Vec<Value>) -> BoxFuture<'static, NodeResult<Value>> {
268265
let store = context.core.store();
269266
async move {
270-
let digest = lift_directory_digest(&context.core.types, &args[0])?;
267+
let digest = lift_directory_digest(&args[0])?;
271268
let snapshot = store::Snapshot::from_digest(store, digest).await?;
272269
Snapshot::store_snapshot(snapshot)
273270
}
@@ -285,7 +282,7 @@ fn merge_digests_request_to_digest(
285282
externs::getattr::<Vec<Value>>(&args[0], "digests")
286283
.unwrap()
287284
.into_iter()
288-
.map(|val: Value| lift_directory_digest(&core.types, &val))
285+
.map(|val: Value| lift_directory_digest(&val))
289286
.collect();
290287
async move {
291288
let digest = store
@@ -396,11 +393,8 @@ fn digest_subset_to_digest(
396393

397394
async move {
398395
let path_globs = Snapshot::lift_prepared_path_globs(&globs).map_err(|e| throw(&e))?;
399-
let original_digest = lift_directory_digest(
400-
&context.core.types,
401-
&externs::getattr(&args[0], "digest").unwrap(),
402-
)
403-
.map_err(|e| throw(&e))?;
396+
let original_digest = lift_directory_digest(&externs::getattr(&args[0], "digest").unwrap())
397+
.map_err(|e| throw(&e))?;
404398
let subset_params = SubsetParams { globs: path_globs };
405399
let digest = store
406400
.subset(original_digest, subset_params)

src/rust/engine/src/nodes.rs

+9-25
Original file line numberDiff line numberDiff line change
@@ -208,19 +208,8 @@ impl From<Select> for NodeKey {
208208
}
209209
}
210210

211-
pub fn lift_directory_digest(types: &Types, digest: &Value) -> Result<hashing::Digest, String> {
212-
if types.directory_digest != externs::get_type_for(digest) {
213-
return Err(format!(
214-
"{} is not of type {}.",
215-
digest, types.directory_digest
216-
));
217-
}
218-
let fingerprint = externs::getattr_as_string(&digest, "fingerprint");
219-
let digest_length: usize = externs::getattr(&digest, "serialized_bytes_length").unwrap();
220-
Ok(hashing::Digest(
221-
hashing::Fingerprint::from_hex_string(&fingerprint)?,
222-
digest_length,
223-
))
211+
pub fn lift_directory_digest(digest: &Value) -> Result<hashing::Digest, String> {
212+
externs::fs::from_py_digest(digest).map_err(|e| format!("{:?}", e))
224213
}
225214

226215
pub fn lift_file_digest(types: &Types, digest: &Value) -> Result<hashing::Digest, String> {
@@ -244,11 +233,7 @@ pub struct MultiPlatformExecuteProcess {
244233
}
245234

246235
impl MultiPlatformExecuteProcess {
247-
fn lift_process(
248-
types: &Types,
249-
value: &Value,
250-
platform_constraint: Option<Platform>,
251-
) -> Result<Process, String> {
236+
fn lift_process(value: &Value, platform_constraint: Option<Platform>) -> Result<Process, String> {
252237
let env = externs::getattr_from_frozendict(&value, "env");
253238

254239
let working_directory = {
@@ -261,8 +246,8 @@ impl MultiPlatformExecuteProcess {
261246
};
262247

263248
let py_digest: Value = externs::getattr(&value, "input_digest").unwrap();
264-
let digest = lift_directory_digest(types, &py_digest)
265-
.map_err(|err| format!("Error parsing digest {}", err))?;
249+
let digest =
250+
lift_directory_digest(&py_digest).map_err(|err| format!("Error parsing digest {}", err))?;
266251

267252
let output_files = externs::getattr::<Vec<String>>(&value, "output_files")
268253
.unwrap()
@@ -336,7 +321,7 @@ impl MultiPlatformExecuteProcess {
336321
})
337322
}
338323

339-
pub fn lift(types: &Types, value: &Value) -> Result<MultiPlatformExecuteProcess, String> {
324+
pub fn lift(value: &Value) -> Result<MultiPlatformExecuteProcess, String> {
340325
let raw_constraints = externs::getattr::<Vec<Option<String>>>(&value, "platform_constraints")?;
341326
let constraints = raw_constraints
342327
.into_iter()
@@ -356,8 +341,7 @@ impl MultiPlatformExecuteProcess {
356341

357342
let mut request_by_constraint: BTreeMap<Option<Platform>, Process> = BTreeMap::new();
358343
for (constraint, execute_process) in constraints.iter().zip(processes.iter()) {
359-
let underlying_req =
360-
MultiPlatformExecuteProcess::lift_process(types, execute_process, *constraint)?;
344+
let underlying_req = MultiPlatformExecuteProcess::lift_process(execute_process, *constraint)?;
361345
request_by_constraint.insert(*constraint, underlying_req.clone());
362346
}
363347

@@ -640,7 +624,7 @@ impl Snapshot {
640624
}
641625

642626
pub fn store_directory_digest(item: &hashing::Digest) -> Result<Value, String> {
643-
externs::fs::new_py_digest(*item)
627+
externs::fs::to_py_digest(*item)
644628
.map(|d| d.into_object().into())
645629
.map_err(|e| format!("{:?}", e))
646630
}
@@ -656,7 +640,7 @@ impl Snapshot {
656640
}
657641

658642
pub fn store_snapshot(item: store::Snapshot) -> Result<Value, String> {
659-
externs::fs::new_py_snapshot(item)
643+
externs::fs::to_py_snapshot(item)
660644
.map(|d| d.into_object().into())
661645
.map_err(|e| format!("{:?}", e))
662646
}

0 commit comments

Comments
 (0)