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