pub struct NodeId(/* private fields */);Implementations§
Source§impl NodeId
impl NodeId
pub fn from_index(index: usize) -> Option<Self>
Sourcepub fn index(self) -> usize
pub fn index(self) -> usize
Examples found in repository?
examples/processing_benchmark.rs (line 402)
232fn measure(stage: Stage, shape: Shape, depth: Option<usize>, path: &PathBuf) -> Measurement {
233 let registry = DialectRegistry::baseline();
234 let mut limits = ParseLimits::default();
235 if let Some(depth) = depth {
236 limits.max_delimiter_depth = limits.max_delimiter_depth.max(depth.saturating_add(8));
237 }
238 let mut bytes = Vec::new();
239 File::open(path).unwrap().read_to_end(&mut bytes).unwrap();
240 let mut parsed = if stage == Stage::Parse {
241 None
242 } else {
243 Some(
244 ParsedFile::parse_with_limits_and_registry(
245 Arc::<[u8]>::from(bytes.clone()),
246 limits,
247 registry,
248 )
249 .unwrap(),
250 )
251 };
252 let retention = if shape == Shape::Primary
253 && matches!(
254 stage,
255 Stage::Lower | Stage::Preserving | Stage::DirtyPreserving
256 ) {
257 RetentionProfile::Hybrid
258 } else {
259 RetentionProfile::SemanticOnly
260 };
261 let mut document = if matches!(
262 stage,
263 Stage::Lower
264 | Stage::Parse
265 | Stage::Traverse
266 | Stage::SyntaxPayload
267 | Stage::SyntaxOperationPayload
268 | Stage::SyntaxOperationTraverse
269 ) {
270 None
271 } else {
272 Some(
273 lower_with_dialect_registry_and_retention(
274 parsed.as_ref().unwrap(),
275 LoweringMode::Strict,
276 retention,
277 registry,
278 )
279 .document
280 .expect("strict lowering"),
281 )
282 };
283 if stage == Stage::DirtyPreserving {
284 let document = document.as_mut().unwrap();
285 let operations = document
286 .operations()
287 .filter(|operation| {
288 document
289 .operation_regions(*operation)
290 .unwrap_or(&[])
291 .is_empty()
292 })
293 .collect::<Vec<_>>();
294 let mut editor = document.edit(registry).unwrap();
295 for operation in operations {
296 editor
297 .set_attribute(
298 operation,
299 AttributeSpec {
300 name: "bench_dirty".into(),
301 spelling: "\"yes\"".into(),
302 value: AttributeValue::String("\"yes\"".into()),
303 },
304 )
305 .unwrap();
306 }
307 editor.commit().unwrap();
308 }
309 let baseline = LIVE.load(Ordering::Relaxed);
310 PEAK.store(baseline, Ordering::Relaxed);
311 let started = Instant::now();
312 let mut output = 0;
313 let mut checksum = 0_u64;
314 match stage {
315 Stage::Parse => {
316 parsed = Some(
317 ParsedFile::parse_with_limits_and_registry(
318 Arc::<[u8]>::from(bytes),
319 limits,
320 registry,
321 )
322 .unwrap(),
323 )
324 }
325 Stage::Traverse => {
326 for node in parsed
327 .as_ref()
328 .unwrap()
329 .syntax()
330 .tree()
331 .subtree(parsed.as_ref().unwrap().syntax().tree().root())
332 .unwrap()
333 {
334 let tree = parsed.as_ref().unwrap().syntax().tree();
335 checksum = checksum
336 .wrapping_mul(0x100000001b3)
337 .wrapping_add(tree.kind(node).unwrap() as u64)
338 .wrapping_add(tree.token_indices(node).unwrap().len() as u64);
339 }
340 }
341 Stage::SyntaxPayload => {
342 let tree = parsed.as_ref().unwrap().syntax().tree();
343 let mut node_kind = Vec::with_capacity(tree.node_count() * 2);
344 let mut node_start = Vec::with_capacity(tree.node_count() * 4);
345 let mut node_end = Vec::with_capacity(tree.node_count() * 4);
346 let mut node_subtree_end = Vec::with_capacity(tree.node_count() * 4);
347 let mut node_flags = Vec::with_capacity(tree.node_count());
348 for index in 0..tree.node_count() {
349 let id = tree.node(index).unwrap();
350 node_kind.extend_from_slice(&(tree.kind(id).unwrap() as u16).to_ne_bytes());
351 node_start.extend_from_slice(
352 &tree
353 .text_range(id)
354 .map_or(u32::MAX, |r| r.start())
355 .to_ne_bytes(),
356 );
357 node_end.extend_from_slice(
358 &tree
359 .text_range(id)
360 .map_or(u32::MAX, |r| r.end())
361 .to_ne_bytes(),
362 );
363 node_subtree_end
364 .extend_from_slice(&(tree.subtree_end(id).unwrap() as u32).to_ne_bytes());
365 node_flags.push(u8::from(tree.has_error(id).unwrap()));
366 }
367 let mut token_kind = Vec::with_capacity(tree.token_count() * 2);
368 let mut token_start = Vec::with_capacity(tree.token_count() * 4);
369 let mut token_end = Vec::with_capacity(tree.token_count() * 4);
370 for index in 0..tree.token_count() {
371 let token = tree.token(index).unwrap();
372 token_kind.extend_from_slice(&(token.kind() as u16).to_ne_bytes());
373 token_start.extend_from_slice(&token.range().start().to_ne_bytes());
374 token_end.extend_from_slice(&token.range().end().to_ne_bytes());
375 }
376 output = node_kind.len()
377 + node_start.len()
378 + node_end.len()
379 + node_subtree_end.len()
380 + node_flags.len()
381 + token_kind.len()
382 + token_start.len()
383 + token_end.len();
384 checksum = node_kind
385 .iter()
386 .chain(&token_kind)
387 .fold(0_u64, |sum, byte| sum.wrapping_add(*byte as u64));
388 black_box((
389 node_kind,
390 node_start,
391 node_end,
392 node_subtree_end,
393 node_flags,
394 token_kind,
395 token_start,
396 token_end,
397 ));
398 }
399 Stage::SyntaxOperationTraverse => {
400 for operation in parsed.as_ref().unwrap().syntax().file().operations() {
401 checksum = checksum
402 .wrapping_add(operation.id().index() as u64)
403 .wrapping_add(operation.results().count() as u64)
404 .wrapping_add(operation.operands().count() as u64)
405 .wrapping_add(operation.successors().count() as u64)
406 .wrapping_add(operation.regions().count() as u64);
407 }
408 }
409 Stage::SyntaxOperationPayload => {
410 let operations = parsed
411 .as_ref()
412 .unwrap()
413 .syntax()
414 .file()
415 .operations()
416 .collect::<Vec<_>>();
417 let result_count = operations.iter().map(|op| op.results().count()).sum();
418 let operand_count = operations.iter().map(|op| op.operands().count()).sum();
419 let successor_count = operations.iter().map(|op| op.successors().count()).sum();
420 let region_count = operations.iter().map(|op| op.regions().count()).sum();
421 let mut columns = [
422 Vec::with_capacity(operations.len()),
423 Vec::with_capacity(operations.len() + 1),
424 Vec::with_capacity(result_count),
425 Vec::with_capacity(operations.len() + 1),
426 Vec::with_capacity(operand_count),
427 Vec::with_capacity(operations.len() + 1),
428 Vec::with_capacity(successor_count),
429 Vec::with_capacity(operations.len() + 1),
430 Vec::with_capacity(region_count),
431 ];
432 for index in [1, 3, 5, 7] {
433 columns[index].push(0);
434 }
435 for operation in operations {
436 columns[0].push(operation.id().index() as u32);
437 columns[2].extend(operation.results().map(|node| node.id().index() as u32));
438 let end = columns[2].len() as u32;
439 columns[1].push(end);
440 columns[4].extend(operation.operands().map(|node| node.id().index() as u32));
441 let end = columns[4].len() as u32;
442 columns[3].push(end);
443 columns[6].extend(operation.successors().map(|node| node.id().index() as u32));
444 let end = columns[6].len() as u32;
445 columns[5].push(end);
446 columns[8].extend(operation.regions().map(|node| node.id().index() as u32));
447 let end = columns[8].len() as u32;
448 columns[7].push(end);
449 }
450 checksum = columns
451 .iter()
452 .flatten()
453 .fold(0_u64, |sum, value| sum.wrapping_add(*value as u64));
454 output = columns
455 .iter()
456 .map(|column| column.len() * size_of::<u32>())
457 .sum();
458 black_box(columns);
459 }
460 Stage::Lower => {
461 document = Some(
462 lower_with_dialect_registry_and_retention(
463 parsed.as_ref().unwrap(),
464 LoweringMode::Strict,
465 retention,
466 registry,
467 )
468 .document
469 .expect("strict lowering"),
470 )
471 }
472 Stage::OperationPayload => {
473 let doc = document.as_ref().unwrap();
474 let mut names = std::collections::HashMap::<u32, u32>::new();
475 let mut distinct = Vec::new();
476 let mut columns = Vec::<u32>::new();
477 for id in doc.operations() {
478 let stored = doc.operation_name_index(id).unwrap();
479 let next = distinct.len() as u32;
480 let code = *names.entry(stored).or_insert_with(|| {
481 distinct.push(stored);
482 next
483 });
484 let range = doc.operation_source_range(id).unwrap();
485 columns.extend([code, range.start(), range.end()]);
486 checksum = checksum.wrapping_add(code as u64);
487 }
488 let name_bytes: usize = distinct
489 .iter()
490 .map(|&index| doc.string_at(index).unwrap().len())
491 .sum();
492 output = columns.len() * std::mem::size_of::<u32>()
493 + doc.operations().count()
494 + (distinct.len() + 1) * std::mem::size_of::<u32>()
495 + name_bytes;
496 black_box(columns);
497 }
498 Stage::OperationTraverse => {
499 let doc = document.as_ref().unwrap();
500 for id in doc.operations() {
501 checksum = checksum
502 .wrapping_add(doc.operation_name_index(id).unwrap() as u64)
503 .wrapping_add(doc.operation_source_range(id).unwrap().start() as u64);
504 }
505 }
506 Stage::Verify => document
507 .as_ref()
508 .unwrap()
509 .verify_semantics(registry)
510 .unwrap(),
511 Stage::Canonical => {
512 let mut sink = ByteCounter::default();
513 document
514 .as_ref()
515 .unwrap()
516 .write_canonical(&mut sink, PrintLayout::Compact)
517 .unwrap();
518 output = sink.0;
519 }
520 Stage::UseIndex => {
521 let doc = document.as_ref().unwrap();
522 if let Some((_op, value)) = doc.operations().find_map(|op| {
523 doc.operation(op)
524 .unwrap()
525 .result(op, 0)
526 .map(|value| (op, value))
527 }) {
528 black_box(doc.uses(value));
529 }
530 }
531 Stage::SymbolIndex => {
532 black_box(
533 document
534 .as_ref()
535 .unwrap()
536 .symbol_index_diagnostics(registry),
537 );
538 }
539 Stage::DominanceIndex => {
540 let doc = document.as_ref().unwrap();
541 let ops = doc.operations().collect::<Vec<_>>();
542 if let (Some((_, value)), Some(last)) = (
543 ops.iter().find_map(|op| {
544 doc.operation(*op)
545 .unwrap()
546 .result(*op, 0)
547 .map(|value| (*op, value))
548 }),
549 ops.last(),
550 ) {
551 black_box(doc.dominates(value, *last, registry));
552 }
553 }
554 Stage::Editor => {
555 let doc = document.as_mut().unwrap();
556 let mut editor = doc.edit(registry).unwrap();
557 if shape == Shape::BlockRich {
558 black_box(editor.compact_pools());
559 } else {
560 let leaf = editor
561 .document()
562 .operations()
563 .find(|op| editor.document().operation_name(*op) == Some("bench.op"))
564 .expect("editable leaf");
565 editor.erase(leaf).unwrap();
566 }
567 editor.commit().unwrap();
568 }
569 Stage::Preserving | Stage::DirtyPreserving => {
570 let doc = document.as_ref().unwrap();
571 let mut sink = ByteCounter::default();
572 doc.write_preserving(&mut sink, PrintLayout::Compact)
573 .unwrap();
574 output = sink.0;
575 }
576 }
577 let elapsed = started.elapsed();
578 let peak = PEAK.load(Ordering::Relaxed).saturating_sub(baseline) as usize;
579 let stats = document.as_ref().map(|doc| { let s=doc.statistics(); format!("operations={} regions={} blocks={} pooled_entries={} direct_owned_bytes={} document_index_bytes={} retained_source_bytes={} retained_cst_nodes={} retained_cst_bytes={} source_storage_shared={} cst_storage_shared={} retained_mapping_entries={} payload_blob_bytes={} use_index_entries={} symbol_index_entries={} dominance_index_entries={}",s.operations,s.regions,s.blocks,s.pooled_list_entries,s.direct_owned_bytes,s.document_index_bytes,s.retained_source_bytes,s.retained_cst_nodes,s.retained_cst_bytes,s.source_storage_shared,s.cst_storage_shared,s.retained_mapping_entries,s.payload_blob_bytes,s.use_index_entries,s.symbol_index_entries,s.dominance_index_entries) }).unwrap_or_else(|| { let tree=parsed.as_ref().map(|p|p.syntax().tree()); format!("cst_nodes={} cst_tokens={} exact_cst_retained_bytes={}",tree.map_or(0,|t|t.node_count()),tree.map_or(0,|t|t.token_count()),tree.map_or(0,|t|t.exact_retained_bytes())) });
580 black_box(checksum);
581 Measurement {
582 ns: elapsed.as_nanos(),
583 peak,
584 output,
585 checksum,
586 stats,
587 }
588}Trait Implementations§
impl Copy for NodeId
impl Eq for NodeId
impl StructuralPartialEq for NodeId
Auto Trait Implementations§
impl Freeze for NodeId
impl RefUnwindSafe for NodeId
impl Send for NodeId
impl Sync for NodeId
impl Unpin for NodeId
impl UnsafeUnpin for NodeId
impl UnwindSafe for NodeId
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more