Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  tree.rs   Sprache: unbekannt

 
Spracherkennung für: .rs vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

use std::collections::{hash_map::DefaultHasher, HashMap, HashSet};
use std::fmt;
use std::hash::{Hash, Hasher};

use super::{Backtrace, Symbol, SymbolTrace, Trace};

/// An adjacency list representation of an execution tree.
///
/// This tree provides a convenient intermediate representation for formatting
/// [`Trace`] as a tree.
pub(super) struct Tree {
    /// The roots of the trees.
    ///
    /// There should only be one root, but the code is robust to multiple roots.
    roots: HashSet<Symbol>,

    /// The adjacency list of symbols in the execution tree(s).
    edges: HashMap<Symbol, HashSet<Symbol>>,
}

impl Tree {
    /// Constructs a [`Tree`] from [`Trace`]
    pub(super) fn from_trace(trace: Trace) -> Self {
        let mut roots: HashSet<Symbol> = HashSet::default();
        let mut edges: HashMap<Symbol, HashSet<Symbol>> = HashMap::default();

        for trace in trace.backtraces {
            let trace = to_symboltrace(trace);

            if let Some(first) = trace.first() {
                roots.insert(first.to_owned());
            }

            let mut trace = trace.into_iter().peekable();
            while let Some(frame) = trace.next() {
                let subframes = edges.entry(frame).or_default();
                if let Some(subframe) = trace.peek() {
                    subframes.insert(subframe.clone());
                }
            }
        }

        Tree { roots, edges }
    }

    /// Produces the sub-symbols of a given symbol.
    fn consequences(&self, frame: &Symbol) -> Option<impl ExactSizeIterator<Item = &Symbol>> {
        Some(self.edges.get(frame)?.iter())
    }

    /// Format this [`Tree`] as a textual tree.
    fn display<W: fmt::Write>(
        &self,
        f: &mut W,
        root: &Symbol,
        is_last: bool,
        prefix: &str,
    ) -> fmt::Result {
        let root_fmt = format!("{}", root);

        let current;
        let next;

        if is_last {
            current = format!("{prefix}└╼\u{a0}{root_fmt}");
            next = format!("{}\u{a0}\u{a0}\u{a0}", prefix);
        } else {
            current = format!("{prefix}├╼\u{a0}{root_fmt}");
            next = format!("{}│\u{a0}\u{a0}", prefix);
        }

        write!(f, "{}", {
            let mut current = current.chars();
            current.next().unwrap();
            current.next().unwrap();
            ¤t.as_str()
        })?;

        if let Some(consequences) = self.consequences(root) {
            let len = consequences.len();
            for (i, consequence) in consequences.enumerate() {
                let is_last = i == len - 1;
                writeln!(f)?;
                self.display(f, consequence, is_last, &next)?;
            }
        }

        Ok(())
    }
}

impl fmt::Display for Tree {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for root in &self.roots {
            self.display(f, root, true, " ")?;
        }
        Ok(())
    }
}

/// Resolve a sequence of [`backtrace::BacktraceFrame`]s into a sequence of
/// [`Symbol`]s.
fn to_symboltrace(backtrace: Backtrace) -> SymbolTrace {
    // Resolve the backtrace frames to symbols.
    let backtrace: Backtrace = {
        let mut backtrace = backtrace::Backtrace::from(backtrace);
        backtrace.resolve();
        backtrace.into()
    };

    // Accumulate the symbols in descending order into `symboltrace`.
    let mut symboltrace: SymbolTrace = vec![];
    let mut state = DefaultHasher::new();
    for frame in backtrace.into_iter().rev() {
        for symbol in frame.symbols().iter().rev() {
            let symbol = Symbol {
                symbol: symbol.clone(),
                parent_hash: state.finish(),
            };
            symbol.hash(&mut state);
            symboltrace.push(symbol);
        }
    }

    symboltrace
}

[ Dauer der Verarbeitung: 0.37 Sekunden  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge