Skip to content

Commit

Permalink
Migration kernel for the blueprint space-view-related breaking changes (
Browse files Browse the repository at this point in the history
#8439)

Our first migration kernel! This makes it possible to load <0.21
blueprints into Rerun 0.21, transparently, without user intervention.

More importantly, this marks the first step in exploring these kinds of
tools, as part of our general promise of becoming more and more stable
over time.

Basically a gloried search and replace.

To test it, save any blueprint from 0.20
(https://app.rerun.io/version/0.20.3/index.html), and load it into 0.21.
  • Loading branch information
teh-cmc authored Dec 12, 2024
1 parent abccbe4 commit e85cc13
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 1 deletion.
1 change: 1 addition & 0 deletions crates/store/re_chunk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod id;
mod iter;
mod latest_at;
mod merge;
mod migration;
mod range;
mod shuffle;
mod slice;
Expand Down
95 changes: 95 additions & 0 deletions crates/store/re_chunk/src/migration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use arrow2::array::{Array, Utf8Array};

use itertools::Itertools;
use nohash_hasher::IntMap;

use crate::Chunk;

impl Chunk {
/// A temporary migration kernel for blueprint data.
///
/// Deals with all the space-view terminology breaking changes (`SpaceView`->`View`, `space_view`->`view`, etc).
#[inline]
pub fn patched_for_blueprint_021_compat(&self) -> Self {
let mut chunk = self.clone();

const PATCHES: &[(&str, &str)] = &[("SpaceView", "View"), ("space_view", "view")];

// First, patch any entity path that still use space-view terminology.
// We expect this to only ever be called for blueprint data, so these entity paths
// are all builtin ones -- we're not overriding any user data.
let mut entity_path = chunk.entity_path.to_string();
for (from, to) in PATCHES {
entity_path = entity_path.replace(from, to);
}
chunk.entity_path = entity_path.into();

let mut components_patched = IntMap::default();
for (component_name, per_desc) in chunk.components.iter_mut() {
if PATCHES
.iter()
.any(|(from, _to)| component_name.contains(from))
{
// Second, patch all descriptors that still use space-view terminology.
for (mut descriptor, list_array) in std::mem::take(per_desc) {
for (from, to) in PATCHES {
if let Some(archetype_name) = descriptor.archetype_name.as_mut() {
*archetype_name = archetype_name.replace(from, to).into();
}
descriptor.component_name =
descriptor.component_name.replace(from, to).into();
}
components_patched.insert(descriptor, list_array.clone());
}
}

// Finally, patch actual data that still uses space-view terminology.
// As far as we know, this only concerns `IncludedContent` specifically.
if component_name == "rerun.blueprint.components.IncludedContent" {
for list_array in per_desc.values_mut() {
let arrays = list_array
.iter()
.map(|utf8_array| {
utf8_array.map(|array| {
let Some(array) = array.as_any().downcast_ref::<Utf8Array<i32>>()
else {
// Unreachable, just avoiding unwraps.
return array;
};

array
.iter()
.map(|s| {
s.map(|s| {
let mut s = s.to_owned();
for (from, to) in PATCHES {
s = s.replace(from, to);
}
s
})
})
.collect::<Utf8Array<i32>>()
.to_boxed()
})
})
.collect_vec();
let arrays = arrays
.iter()
.map(|a| a.as_deref() as Option<&dyn Array>)
.collect_vec();

if let Some(list_array_patched) = crate::util::arrays_to_list_array_opt(&arrays)
{
*list_array = list_array_patched;
}
}
}
}

for (desc, list_array) in components_patched {
chunk.components.insert_descriptor(desc, list_array);
}

chunk
}
}
4 changes: 3 additions & 1 deletion crates/store/re_chunk_store/src/writes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ impl ChunkStore {
// * Somebody loads an old .rbl from somewhere and starts logging new blueprint data to it.
// * Etc.
if self.id.kind == re_log_types::StoreKind::Blueprint {
chunk = Arc::new(chunk.clone_as_untagged());
let patched = chunk.patched_for_blueprint_021_compat();
let patched = patched.clone_as_untagged();
chunk = Arc::new(patched);
}

#[cfg(debug_assertions)]
Expand Down

0 comments on commit e85cc13

Please sign in to comment.