Skip to main content

NodeId

Struct NodeId 

Source
pub struct NodeId(/* private fields */);

Implementations§

Source§

impl NodeId

Source

pub fn from_index(index: usize) -> Option<Self>

Source

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§

Source§

impl Clone for NodeId

Source§

fn clone(&self) -> NodeId

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for NodeId

Source§

impl Debug for NodeId

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for NodeId

Source§

impl Hash for NodeId

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for NodeId

Source§

fn eq(&self, other: &NodeId) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for NodeId

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.