oxgraph_postgres/artifact/
sections.rs1use oxgraph_csc::{SNAPSHOT_KIND_PG_INBOUND_OFFSETS_U32, SNAPSHOT_KIND_PG_INBOUND_TARGETS_U32};
4use oxgraph_csr::CsrSnapshotIndex;
5use oxgraph_snapshot::{Snapshot, SnapshotBuilder};
6
7use super::metadata::{PostgresMetadata, write_postgres_metadata_section};
8use crate::error::{BuildError, PostgresGraphError};
9
10pub fn attach_postgres_sections(
25 forward_topology_bytes: &[u8],
26 inbound_topology_bytes: Option<&[u8]>,
27 metadata: &PostgresMetadata,
28) -> Result<Vec<u8>, PostgresGraphError> {
29 let forward = Snapshot::open(forward_topology_bytes)?;
30 let inbound = inbound_topology_bytes.map(Snapshot::open).transpose()?;
31 let mut builder = SnapshotBuilder::new();
32 for section in forward.sections() {
33 if is_postgres_owned_kind(section.kind()) {
34 continue;
35 }
36 builder.add_section(
37 section.kind(),
38 section.version(),
39 alignment_log2_from_section(§ion),
40 section.bytes().to_vec(),
41 )?;
42 }
43 if let Some(inbound_snapshot) = inbound.as_ref() {
44 copy_csr_section(
45 inbound_snapshot,
46 u32::OFFSETS_KIND,
47 SNAPSHOT_KIND_PG_INBOUND_OFFSETS_U32,
48 &mut builder,
49 )?;
50 copy_csr_section(
51 inbound_snapshot,
52 u32::TARGETS_KIND,
53 SNAPSHOT_KIND_PG_INBOUND_TARGETS_U32,
54 &mut builder,
55 )?;
56 }
57 write_postgres_metadata_section(&mut builder, metadata)?;
58 builder.finish().map_err(PostgresGraphError::from)
59}
60
61pub fn attach_metadata(
74 base_bytes: &[u8],
75 metadata: &PostgresMetadata,
76) -> Result<Vec<u8>, PostgresGraphError> {
77 attach_postgres_sections(base_bytes, None, metadata)
78}
79
80fn copy_csr_section(
82 snapshot: &Snapshot<'_>,
83 source_kind: u32,
84 dest_kind: u32,
85 builder: &mut SnapshotBuilder,
86) -> Result<(), PostgresGraphError> {
87 let section = snapshot
88 .section(source_kind)
89 .ok_or(PostgresGraphError::Build(BuildError::MissingCsrSection {
90 kind: source_kind,
91 }))?;
92 builder.add_section(
93 dest_kind,
94 section.version(),
95 alignment_log2_from_section(§ion),
96 section.bytes().to_vec(),
97 )?;
98 Ok(())
99}
100
101fn is_postgres_owned_kind(kind: u32) -> bool {
103 (0x0200..0x0300).contains(&kind)
104}
105
106fn alignment_log2_from_section(section: &oxgraph_snapshot::Section<'_>) -> u8 {
108 let alignment = section.declared_alignment();
109 if alignment <= 1 {
110 0
111 } else {
112 u8::try_from(alignment.trailing_zeros()).unwrap_or(u8::MAX)
113 }
114}