Skip to main content

swh_graph/views/spy/
strings.rs

1// Copyright (C) 2024-2025  The Software Heritage developers
2// See the AUTHORS file at the top-level directory of this distribution
3// License: GNU General Public License version 3, or any later version
4// See top-level LICENSE file for more information
5
6//! Implementation of [`properties::Strings`] spy for [`GraphSpy`]
7
8use super::*;
9use properties::{OptStrings, PropertiesBackend, PropertiesResult};
10
11impl<
12        G: SwhGraphWithProperties<Strings: OptStrings>,
13        MAPS: properties::MaybeMaps,
14        TIMESTAMPS: properties::MaybeTimestamps,
15        PERSONS: properties::MaybePersons,
16        CONTENTS: properties::MaybeContents,
17        LABELNAMES: properties::MaybeLabelNames,
18    > GraphSpy<G, MAPS, TIMESTAMPS, PERSONS, CONTENTS, properties::NoStrings, LABELNAMES>
19{
20    pub fn with_strings(
21        self,
22    ) -> GraphSpy<G, MAPS, TIMESTAMPS, PERSONS, CONTENTS, StringsSpy<G>, LABELNAMES> {
23        let GraphSpy {
24            properties:
25                properties::SwhGraphProperties {
26                    path,
27                    num_nodes,
28                    maps,
29                    timestamps,
30                    persons,
31                    contents,
32                    strings: properties::NoStrings,
33                    label_names,
34                    label_names_are_in_base64_order,
35                },
36            inner,
37            history,
38        } = self;
39
40        GraphSpy {
41            properties: properties::SwhGraphProperties {
42                path,
43                num_nodes,
44                maps,
45                timestamps,
46                persons,
47                contents,
48                strings: StringsSpy {
49                    graph: Arc::clone(&inner),
50                    history: Arc::clone(&history),
51                },
52                label_names,
53                label_names_are_in_base64_order,
54            },
55            inner,
56            history,
57        }
58    }
59}
60
61pub struct StringsSpy<G: SwhGraphWithProperties<Strings: OptStrings>> {
62    graph: Arc<GraphSpyInner<G>>,
63    history: Arc<Mutex<Vec<GraphAccessRecord>>>,
64}
65
66impl<G: SwhGraphWithProperties<Strings: OptStrings>> PropertiesBackend for StringsSpy<G> {
67    type DataFilesAvailability =
68        <<G as SwhGraphWithProperties>::Strings as PropertiesBackend>::DataFilesAvailability;
69}
70
71impl<G: SwhGraphWithProperties<Strings: OptStrings>> OptStrings for StringsSpy<G> {
72    fn message(&self) -> PropertiesResult<'_, &[u8], Self> {
73        // no need to log, every access necessarily calls message_offset too
74        self.graph.graph.properties().strings.message()
75    }
76
77    fn message_offset(&self, node: NodeId) -> PropertiesResult<'_, Option<u64>, Self> {
78        self.history
79            .lock()
80            .unwrap()
81            .push(GraphAccessRecord::Property(PropertyAccess::Message(node)));
82        self.graph.graph.properties().strings.message_offset(node)
83    }
84
85    fn tag_name(&self) -> PropertiesResult<'_, &[u8], Self> {
86        // no need to log, every access necessarily call tag_name_offset too
87        self.graph.graph.properties().strings.tag_name()
88    }
89
90    fn tag_name_offset(&self, node: NodeId) -> PropertiesResult<'_, Option<u64>, Self> {
91        self.history
92            .lock()
93            .unwrap()
94            .push(GraphAccessRecord::Property(PropertyAccess::TagName(node)));
95        self.graph.graph.properties().strings.tag_name_offset(node)
96    }
97}