Add nested attribute entity host support

This commit is contained in:
Felix Riestra committed 2026-09-19 13:16:40 +02:00
1 parent 5ef7000b67
commit cf2a923568
6 files changed
+2509 -541

No files matched your search

+29 -5
View File
@@ -83,13 +83,19 @@ impl<T: SnapshotData> DocumentSnapshotStore<T> {
/// page.
pub fn new(tab_id: u64, segment_size: usize) -> io::Result<Self> {
let segment_size = segment_size.checked_next_multiple_of(4096).ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput, "snapshot segment size overflow")
io::Error::new(
io::ErrorKind::InvalidInput,
"snapshot segment size overflow",
)
})?;
let total = segment_size
.checked_mul(2)
.and_then(|segments| CONTROL_SIZE.checked_add(segments))
.ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput, "snapshot mapping size overflow")
io::Error::new(
io::ErrorKind::InvalidInput,
"snapshot mapping size overflow",
)
})?;
if total > MAX_SNAPSHOT_SIZE {
return Err(io::Error::new(
@@ -245,7 +251,10 @@ impl<T: SnapshotData> SharedDocumentReader<T> {
));
}
let file_len = usize::try_from(file_len).map_err(|_| {
io::Error::new(io::ErrorKind::InvalidData, "snapshot file size is unsupported")
io::Error::new(
io::ErrorKind::InvalidData,
"snapshot file size is unsupported",
)
})?;
let mmap = unsafe { MmapOptions::new().len(file_len).map(&file)? };
let segment_size = (file_len - CONTROL_SIZE) / 2;
@@ -543,10 +552,22 @@ pub struct DocumentViewDataV4 {
impl From<&CadDocument> for DocumentViewDataV4 {
fn from(doc: &CadDocument) -> Self {
let mut entities: Vec<_> = doc.entities().map(EntityViewV4::from).collect();
// ATTRIB records live inside their owning INSERT in CadDocument rather
// than in the flat entity index. Flatten them into the plugin snapshot
// as addressable entities while keeping the INSERT's canonical nested
// copy intact for rendering and file serialization.
for entity in doc.entities() {
if let EntityType::Insert(insert) = entity {
entities.extend(insert.attributes.iter().map(|attribute| {
EntityViewV4::from(&EntityType::AttributeEntity(attribute.clone()))
}));
}
}
Self {
layers: doc.layers.iter().map(LayerView::from).collect(),
app_ids: doc.app_ids.iter().map(AppIdView::from).collect(),
entities: doc.entities().map(EntityViewV4::from).collect(),
entities,
}
}
}
@@ -721,7 +742,10 @@ mod tests {
let archived = reader.archived().unwrap();
let entity = &archived.entities[0];
assert_eq!(entity.handle, doc.entities().next().unwrap().common().handle.value());
assert_eq!(
entity.handle,
doc.entities().next().unwrap().common().handle.value()
);
let decoded: EntityType = bincode::deserialize(&entity.data).expect("bincode decode");
assert!(matches!(decoded, EntityType::Point(_)));
}