Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor InstanceId #999

Merged
merged 17 commits into from
Jan 31, 2023
167 changes: 0 additions & 167 deletions crates/re_data_store/src/instance.rs

This file was deleted.

158 changes: 158 additions & 0 deletions crates/re_data_store/src/instance_path.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
use std::hash::Hash;

use re_log_types::{component_types::Instance, EntityPath, EntityPathHash};

use crate::log_db::EntityDb;

// ----------------------------------------------------------------------------

/// The path to either a specific instance of an entity, or the whole entity (splat).
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct InstancePath {
pub entity_path: EntityPath,

/// If this is a concrete instance, what instance index are we?
///
/// If we refer to all instance, [`Instance::SPLAT`] is used.
pub instance_index: Instance,
}

impl InstancePath {
/// Indicate the whole entity (all instances of it) - i.e. a splat.
///
/// For instance: the whole point cloud, rather than a specific point.
#[inline]
pub fn entity_splat(entity_path: EntityPath) -> Self {
Self {
entity_path,
instance_index: Instance::SPLAT,
}
}

/// Indicate a specific instance of the entity,
/// e.g. a specific point in a point cloud entity.
#[inline]
pub fn instance(entity_path: EntityPath, instance_index: Instance) -> Self {
Self {
entity_path,
instance_index,
}
}

/// Do we refer to the whole entity (all instances of it)?
///
/// For instance: the whole point cloud, rather than a specific point.
#[inline]
pub fn is_splat(&self) -> bool {
self.instance_index.is_splat()
}

#[inline]
pub fn hash(&self) -> InstancePathHash {
InstancePathHash {
entity_path_hash: self.entity_path.hash(),
instance_index: self.instance_index,
}
}
}

impl std::fmt::Display for InstancePath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.instance_index.is_splat() {
self.entity_path.fmt(f)
} else {
format!("{}[{}]", self.entity_path, self.instance_index).fmt(f)
}
}
}

// ----------------------------------------------------------------------------

/// Hashes of the components of an [`InstancePath`].
///
/// This is unique to either a specific instance of an entity, or the whole entity (splat).
#[derive(Clone, Copy, Debug, Eq)]
pub struct InstancePathHash {
pub entity_path_hash: EntityPathHash,

/// If this is a concrete instance, what instance index are we?
///
/// If we refer to all instance, [`Instance::SPLAT`] is used.
///
/// Note that this is NOT hashed, because we don't need to (it's already small).
pub instance_index: Instance,
}

impl std::hash::Hash for InstancePathHash {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
state.write_u64(self.entity_path_hash.hash64());
state.write_u64(self.instance_index.0);
}
}

impl std::cmp::PartialEq for InstancePathHash {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.entity_path_hash == other.entity_path_hash
&& self.instance_index == other.instance_index
}
}

impl InstancePathHash {
pub const NONE: Self = Self {
entity_path_hash: EntityPathHash::NONE,
instance_index: Instance::SPLAT,
};

/// Indicate the whole entity (all instances of it) - i.e. a splat.
///
/// For instance: the whole point cloud, rather than a specific point.
#[inline]
pub fn entity_splat(entity_path: &EntityPath) -> Self {
Self {
entity_path_hash: entity_path.hash(),
instance_index: Instance::SPLAT,
}
}

/// Indicate a specific instance of the entity,
/// e.g. a specific point in a point cloud entity.
#[inline]
pub fn instance(entity_path: &EntityPath, instance_index: Instance) -> Self {
Self {
entity_path_hash: entity_path.hash(),
instance_index,
}
}

#[inline]
pub fn is_some(&self) -> bool {
self.entity_path_hash.is_some()
}

#[inline]
pub fn is_none(&self) -> bool {
self.entity_path_hash.is_none()
}

pub fn resolve(&self, entity_db: &EntityDb) -> Option<InstancePath> {
let entity_path = entity_db
.entity_path_from_hash(&self.entity_path_hash)
.cloned()?;

let instance_index = self.instance_index;

Some(InstancePath {
entity_path,
instance_index,
})
}
}

impl Default for InstancePathHash {
fn default() -> Self {
Self::NONE
}
}
4 changes: 2 additions & 2 deletions crates/re_data_store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

pub mod entity_properties;
pub mod entity_tree;
mod instance;
mod instance_path;
pub mod log_db;

pub use entity_properties::*;
pub use entity_tree::*;
pub use instance::*;
pub use instance_path::*;
pub use log_db::LogDb;

use re_log_types::msg_bundle;
Expand Down
28 changes: 23 additions & 5 deletions crates/re_log_types/src/component_types/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use arrow2_convert::{ArrowDeserialize, ArrowField, ArrowSerialize};

use crate::msg_bundle::Component;

/// The Instance used to identify an entity within a batch
/// A number used to specify a specific instance in an entity.
///
/// Each entity can have many component of the same type.
/// These are identified with [`Instance`].
///
/// ```
/// use re_log_types::component_types::Instance;
Expand All @@ -29,14 +32,29 @@ use crate::msg_bundle::Component;
pub struct Instance(pub u64);

impl Instance {
/// A special value indicating that this [`Instance]` is referring to all instances of an entity,
/// for example all points in a point cloud entity.
pub const SPLAT: Self = Self(u64::MAX);

/// Are we referring to all instances of the entity (e.g. all points in a point cloud entity)?
///
/// The opposite of [`Self::is_specific`].
#[inline]
pub fn splat() -> Instance {
Self(u64::MAX)
pub fn is_splat(self) -> bool {
self == Self::SPLAT
}

/// Are we referring to a specific instance of the entity (e.g. a specific point in a point cloud)?
///
/// The opposite of [`Self::is_splat`].
#[inline]
pub fn is_splat(&self) -> bool {
self.0 == u64::MAX
pub fn is_specific(self) -> bool {
self != Self::SPLAT
}

/// Returns `None` if splat, otherwise the index.
pub fn specific_index(self) -> Option<Instance> {
self.is_specific().then_some(self)
}
}

Expand Down
Loading