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

end-to-end arrow-based text entries #654

Merged
merged 190 commits into from
Jan 3, 2023
Merged
Show file tree
Hide file tree
Changes from 189 commits
Commits
Show all changes
190 commits
Select commit Hold shift + click to select a range
940364b
get is supposed to return a row, not a [row]
teh-cmc Dec 18, 2022
fcf6d5a
unwrap note
teh-cmc Dec 18, 2022
1a86bee
the bench too
teh-cmc Dec 18, 2022
9e22ac1
self review
teh-cmc Dec 18, 2022
2fac6d2
doc test also
teh-cmc Dec 18, 2022
8682229
and re_query ofc!
teh-cmc Dec 18, 2022
b7e5fd5
slicing is _very_ slow, don't do it if you don't have to
teh-cmc Dec 18, 2022
da816d1
no more col_arrays in re_query
teh-cmc Dec 18, 2022
b22eecc
there's actually no need for concatenating at all
teh-cmc Dec 16, 2022
4a7b7ef
incrementally compute and cache bucket sizes
teh-cmc Dec 17, 2022
f88f248
cleaning up and documenting existing limitations
teh-cmc Dec 17, 2022
2bcd47e
introducing bucket retirement
teh-cmc Dec 17, 2022
c8b40b6
issue ref
teh-cmc Dec 17, 2022
36ce4db
some more doc stuff
teh-cmc Dec 17, 2022
751c2e8
self-review
teh-cmc Dec 17, 2022
6776365
polars/fmt should always be there for tests
teh-cmc Dec 18, 2022
9652013
streamlining batch support
teh-cmc Dec 18, 2022
bce700e
take list header into account
teh-cmc Dec 18, 2022
5c6fec8
it's fine
teh-cmc Dec 18, 2022
e97eab6
self-review
teh-cmc Dec 18, 2022
37cd9b2
just something i want to keep around for later
teh-cmc Dec 18, 2022
4682c60
(un)wrapping lists is a bit slow... and slicing them is _extremely_ s…
teh-cmc Dec 18, 2022
5abfffe
merge cmc/datastore/get_a_single_row (#590)
teh-cmc Dec 18, 2022
02170b9
no more col_arrays in re_query
teh-cmc Dec 18, 2022
782f0d5
introducing the notion of clustering key, thankfully breaking all tes…
teh-cmc Dec 16, 2022
17cb879
making good use of that shiny new Instance component
teh-cmc Dec 16, 2022
c311caf
merge cmc/datastore/get_rid_of_copies (#584)
teh-cmc Dec 18, 2022
b9453c4
missed one
teh-cmc Dec 18, 2022
4a36e70
introducing arrow_util with is_dense_array()
teh-cmc Dec 18, 2022
f32b1bd
finding the clustering comp of the row... or creating it!
teh-cmc Dec 18, 2022
805be22
rebasin'
teh-cmc Dec 18, 2022
2e3d674
post rebase clean up
teh-cmc Dec 18, 2022
d3a33cf
addressing PR comments, I hope
teh-cmc Dec 18, 2022
9091e29
Merge remote-tracking branch 'origin/main' into cmc/datastore/get_rid…
teh-cmc Dec 18, 2022
072e645
ensure that clustering components are properly sorted, failing the ex…
teh-cmc Dec 18, 2022
def04ef
build_instances now generate sorted ids, thus greenlighting the test …
teh-cmc Dec 18, 2022
5e6b997
Merge branch 'cmc/datastore/get_rid_of_copies' into cmc/datastore/clu…
teh-cmc Dec 18, 2022
af046b5
missed a couple
teh-cmc Dec 18, 2022
5d19e5f
addressed PR comments
teh-cmc Dec 19, 2022
8bd348b
Merge branch 'cmc/datastore/get_rid_of_copies' into cmc/datastore/clu…
teh-cmc Dec 19, 2022
7420b40
Merge branch 'main' into cmc/datastore/clustering_keys
teh-cmc Dec 19, 2022
951da08
going for the ArrayExt route
teh-cmc Dec 19, 2022
0778300
completing the quadrifecta of checks
teh-cmc Dec 19, 2022
f6d137b
Merge branch 'main' into cmc/datastore/clustering_keys
teh-cmc Dec 19, 2022
6f270ec
the unavoidable typed error revolution is on its way, and it's early
teh-cmc Dec 19, 2022
4578a27
where we're going we don't need polars
teh-cmc Dec 19, 2022
0e6d79e
update everything for the new APIs
teh-cmc Dec 19, 2022
c6f5c52
error for unsupported clustering key types
teh-cmc Dec 19, 2022
0f3a191
clean up and actually testing our error paths
teh-cmc Dec 19, 2022
de5ba78
Merge branch 'main' into cmc/datastore/clustering_keys
teh-cmc Dec 19, 2022
48cfaab
Merge remote-tracking branch 'origin/main' into cmc/datastore/cluster…
teh-cmc Dec 19, 2022
c402deb
move those nasty internal tests into their own dirty corner
teh-cmc Dec 19, 2022
2f8e76e
finally some high-level tests in here
teh-cmc Dec 19, 2022
b81fb40
Merge remote-tracking branch 'origin/main' into cmc/datastore/cluster…
teh-cmc Dec 19, 2022
f178dfa
i happen to like where this is going
teh-cmc Dec 19, 2022
eed6f47
Merge branch 'main' into cmc/datastore/clustering_keys
teh-cmc Dec 20, 2022
b35c9c2
shuffling things
teh-cmc Dec 20, 2022
616dd74
demonstrating that implicit instances are somehow broken
teh-cmc Dec 20, 2022
f4c191c
fully working implicit clustering keys, but demonstrating a sorting i…
teh-cmc Dec 20, 2022
b1fbc88
there is still something weird going on tho
teh-cmc Dec 20, 2022
47ca668
latest_at behaving as one would expect
teh-cmc Dec 20, 2022
7c599eb
automatically cache generated cluster instances
teh-cmc Dec 20, 2022
c5248c4
time to clean up en masse
teh-cmc Dec 20, 2022
1ac590a
Merge remote-tracking branch 'origin/main' into cmc/datastore/cluster…
teh-cmc Dec 20, 2022
61a8148
still want to put some stress on the bucketing
teh-cmc Dec 20, 2022
1277155
make ArrayExt::is_dense a little more friendly, just in case...
teh-cmc Dec 20, 2022
5d7f611
TimeType::format_range
teh-cmc Dec 20, 2022
a3bf10e
independent latest_at query and using appropriate types everywhere
teh-cmc Dec 20, 2022
395ccf0
re_query: use polars/fmt in tests
teh-cmc Dec 20, 2022
4da345e
re_query: remove implicit instances
teh-cmc Dec 20, 2022
25fb915
fixing the u32 vs u64 instance drama
teh-cmc Dec 20, 2022
e356b69
Merge branch 'cmc/datastore/clustering_keys' into cmc/datastore/range…
teh-cmc Dec 20, 2022
367d5f7
really starting to like how this looks
teh-cmc Dec 20, 2022
432d845
cluster-aware polars helpers :>
teh-cmc Dec 20, 2022
c997c28
cleanin up tests
teh-cmc Dec 20, 2022
2a00bb8
continuing cleanup and doc
teh-cmc Dec 20, 2022
a1903b3
updating visuals for this brave new world
teh-cmc Dec 20, 2022
56a9aee
docs
teh-cmc Dec 20, 2022
56fe27a
self-review
teh-cmc Dec 20, 2022
c62a408
Merge remote-tracking branch 'origin/main' into cmc/datastore/cluster…
teh-cmc Dec 20, 2022
9448cc6
bruh
teh-cmc Dec 20, 2022
02e7407
Merge branch 'cmc/datastore/clustering_keys' into cmc/datastore/range…
teh-cmc Dec 20, 2022
669bd54
bruh...
teh-cmc Dec 20, 2022
28f51ad
...
teh-cmc Dec 20, 2022
da81555
outdated comment
teh-cmc Dec 20, 2022
772874c
no reason to search for it multiple times
teh-cmc Dec 20, 2022
1d25265
Merge branch 'main' into cmc/datastore/clustering_keys
teh-cmc Dec 21, 2022
a221de0
polars_helpers => polars_util for consistency's sake
teh-cmc Dec 21, 2022
eff6343
addressing PR comments and a couple other things
teh-cmc Dec 21, 2022
63c02ad
xxx
teh-cmc Dec 21, 2022
33163b2
Merge branch 'main' into cmc/datastore/clustering_keys
teh-cmc Dec 21, 2022
bb3c3ce
Merge branch 'cmc/datastore/clustering_keys' into cmc/datastore/range…
teh-cmc Dec 21, 2022
546d796
post-merge fixes
teh-cmc Dec 21, 2022
1eb08c9
TimeInt should be nohash
teh-cmc Dec 21, 2022
ae97848
high-level polar range tools + making first half of range impl pass
teh-cmc Dec 21, 2022
dea943e
implement the streaming half
teh-cmc Dec 21, 2022
1cb10fc
finally defeated all demons
teh-cmc Dec 21, 2022
0780010
still passes?
teh-cmc Dec 21, 2022
add17ba
can it please stop
teh-cmc Dec 22, 2022
51367d7
it looks like we've made it out alive
teh-cmc Dec 22, 2022
4bdefbe
polars util: join however you wish
teh-cmc Dec 22, 2022
a73fd8f
fixed formatting
teh-cmc Dec 22, 2022
16e625c
point2d's PoVs working as expected
teh-cmc Dec 22, 2022
f07d6a8
passing full ranges
teh-cmc Dec 22, 2022
086dad3
docs and such part 1, the semantics are hell
teh-cmc Dec 22, 2022
b02fa2e
fixing the filtering mess in tests
teh-cmc Dec 22, 2022
42b4b4a
me stoopid
teh-cmc Dec 22, 2022
7d84d4a
polars docs
teh-cmc Dec 22, 2022
4a454cf
addressing the clones
teh-cmc Dec 22, 2022
780e8f7
Merge remote-tracking branch 'origin/main' into cmc/datastore/range_q…
teh-cmc Dec 22, 2022
bf378b7
xxx
teh-cmc Dec 22, 2022
00719c2
missed a gazillon conflict somehow
teh-cmc Dec 22, 2022
fbd39f5
polars util spring cleaning
teh-cmc Dec 22, 2022
290b048
do indicate and demonstrate that range_components is _not_ a real str…
teh-cmc Dec 22, 2022
76648fe
fixed some comments
teh-cmc Dec 22, 2022
1d693f3
bruh
teh-cmc Dec 22, 2022
083e45e
screw it, going for the real deal: full streaming joins
teh-cmc Dec 23, 2022
38d8874
YESgit sgit s FINALLY SEMANTICS I ACTUALLY LIKE
teh-cmc Dec 23, 2022
bba0056
yep yep i like this
teh-cmc Dec 23, 2022
b0cbd3b
I hereby declare myself _satisfied_
teh-cmc Dec 23, 2022
887c60c
initiating the great cleanup
teh-cmc Dec 23, 2022
5fa8a2c
add notes for upcoming terminology pr
teh-cmc Dec 23, 2022
b64a2b6
bringing IndexRowNr into the mix and slowly starting to fix terminolo…
teh-cmc Dec 23, 2022
b5e5532
improving range_components ergonomics
teh-cmc Dec 23, 2022
8ef74dc
putting it all in self-reviewable state
teh-cmc Dec 23, 2022
2dea6de
self-review
teh-cmc Dec 23, 2022
3969c80
add bench
teh-cmc Dec 23, 2022
abc7488
xxx
teh-cmc Dec 23, 2022
afc10d8
Merge branch 'main' into cmc/datastore/range_queries2
teh-cmc Dec 23, 2022
ea4140c
addressing PR comments
teh-cmc Dec 26, 2022
1c41e2c
Merge branch 'main' into cmc/datastore/range_queries2
teh-cmc Dec 27, 2022
a674da3
first impl
teh-cmc Dec 27, 2022
9c0eb4b
ported simple_query() to simple_range
teh-cmc Dec 27, 2022
cbc69a9
doc and such
teh-cmc Dec 27, 2022
13fd956
added e2e example for range queries
teh-cmc Dec 27, 2022
f763887
self-review
teh-cmc Dec 27, 2022
5f3e0c3
Merge remote-tracking branch 'origin/main' into cmc/datastore/range_q…
teh-cmc Dec 28, 2022
e00984e
Merge remote-tracking branch 'origin/cmc/datastore/range_queries2' in…
teh-cmc Dec 28, 2022
7233444
support for new EntityView
teh-cmc Dec 28, 2022
30d8fdb
demonstrating nasty edge-case with streaming-joins
teh-cmc Dec 28, 2022
6405f19
Merge remote-tracking branch 'origin/main' into cmc/datastore/range_q…
teh-cmc Dec 28, 2022
731affe
update streaming-join merging rules to fix said edge case
teh-cmc Dec 28, 2022
bc31e41
Merge branch 'cmc/datastore/range_queries2' into cmc/query/range_support
teh-cmc Dec 28, 2022
41aaf16
mimicking range_components' new merging rules
teh-cmc Dec 28, 2022
e6a6fd5
implement timepoints-as-components and insert them automatically
teh-cmc Dec 28, 2022
20b864e
derive proper ObjectType TextEntry component
teh-cmc Dec 28, 2022
3e0c2de
introducing the TextEntry component
teh-cmc Dec 28, 2022
813a560
re_viewer now supports both legacy and arrow data sources
teh-cmc Dec 28, 2022
228e3ee
added pure rust example for text entries
teh-cmc Dec 28, 2022
760e159
plugging everything on the python side
teh-cmc Dec 28, 2022
c84524f
self-review
teh-cmc Dec 28, 2022
7812791
bruh
teh-cmc Dec 28, 2022
f0f4e00
it's decent, but we won't ever be able to deduplicate that way :(
teh-cmc Dec 29, 2022
fefd090
Revert "it's decent, but we won't ever be able to deduplicate that wa…
teh-cmc Dec 29, 2022
6f8a4d9
Demonstrating how insanely slow the obvious solution is
teh-cmc Dec 29, 2022
8186e5d
it'd be a tiny bit better with some kind of splats...
teh-cmc Dec 29, 2022
91b3d45
and now with MsgId being a full fledged component
teh-cmc Dec 29, 2022
51e16eb
stuff
teh-cmc Dec 29, 2022
c437b2a
bruh
teh-cmc Dec 29, 2022
dfcda8e
Merge branch 'cmc/datastore/msgid_as_component' into cmc/arrowificati…
teh-cmc Dec 29, 2022
071da13
storing msg metadata
teh-cmc Dec 29, 2022
ab69455
Revert "implement timepoints-as-components and insert them automatica…
teh-cmc Dec 29, 2022
d36710e
I guess it's decent
teh-cmc Dec 29, 2022
c4fbda7
implement PoV-less, always-yield lower-level API + adapt higher-level…
teh-cmc Dec 30, 2022
ac91d1d
addressing PR comments
teh-cmc Jan 2, 2023
3cda444
Merge branch 'cmc/datastore/range_queries2' into cmc/query/range_support
teh-cmc Jan 2, 2023
fe3e1d3
ported to new low-level APIs
teh-cmc Jan 2, 2023
ae300a3
xxx
teh-cmc Jan 2, 2023
94930dd
addressed PR comments
teh-cmc Jan 2, 2023
c478199
Merge branch 'main' into cmc/datastore/range_queries2
teh-cmc Jan 2, 2023
399d097
self and not-so-self reviews
teh-cmc Jan 2, 2023
ce1d4e7
Merge branch 'cmc/datastore/range_queries2' into cmc/query/range_support
teh-cmc Jan 2, 2023
35c1b36
Merge branch 'main' into cmc/query/range_support
teh-cmc Jan 2, 2023
80188bb
the future is quite literally here
teh-cmc Jan 2, 2023
9b539ef
add MsgBundle helpers
teh-cmc Jan 3, 2023
e01a7fc
remove hardwired ref to Instance
teh-cmc Jan 3, 2023
45c6f78
Merge branch 'cmc/datastore/range_queries2' into cmc/arrowification/t…
teh-cmc Jan 3, 2023
fe8c00a
Merge branch 'cmc/query/range_support' into cmc/arrowification/text_logs
teh-cmc Jan 3, 2023
31669bf
post-merge fixes
teh-cmc Jan 3, 2023
275e8a7
merge some more
teh-cmc Jan 3, 2023
56a0e11
cleanup
teh-cmc Jan 3, 2023
14ec1e1
guess that isnt very useful anymore
teh-cmc Jan 3, 2023
11fb218
Merge branch 'cmc/msgbundle_helpers' into cmc/arrowification/text_logs
teh-cmc Jan 3, 2023
186f049
using new msgbundle helpers
teh-cmc Jan 3, 2023
4fc062e
Merge branch 'main' into cmc/arrowification/text_logs
teh-cmc Jan 3, 2023
7d0c836
updating my non-sensical msgbundle helpers
teh-cmc Jan 3, 2023
715a889
explaining the example
teh-cmc Jan 3, 2023
2a03852
Merge remote-tracking branch 'origin/main' into cmc/arrowification/te…
teh-cmc Jan 3, 2023
32786d7
woops
teh-cmc Jan 3, 2023
49bb91c
addressed PR comments
teh-cmc Jan 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions crates/re_arrow_store/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use nohash_hasher::IntMap;
use parking_lot::RwLock;
use re_format::{arrow, format_bytes, format_number};
use re_log_types::{
ComponentName, ObjPath as EntityPath, ObjPathHash as EntityPathHash, TimeInt, TimeRange,
Timeline,
ComponentName, MsgId, ObjPath as EntityPath, ObjPathHash as EntityPathHash, TimeInt, TimePoint,
TimeRange, Timeline,
};

// --- Indices & offsets ---
Expand Down Expand Up @@ -200,6 +200,11 @@ pub struct DataStore {
/// so that they can be properly deduplicated.
pub(crate) cluster_comp_cache: IntMap<usize, RowIndex>,

/// Maps `MsgId`s to some metadata (just timepoints at the moment).
///
/// `BTreeMap` because of garbage collection.
pub(crate) messages: BTreeMap<MsgId, TimePoint>,

/// Maps an entity to its index, for a specific timeline.
///
/// An index maps specific points in time to rows in component tables.
Expand All @@ -223,6 +228,7 @@ impl DataStore {
cluster_key,
config,
cluster_comp_cache: Default::default(),
messages: Default::default(),
indices: Default::default(),
components: Default::default(),
insert_id: 0,
Expand Down Expand Up @@ -328,6 +334,7 @@ impl std::fmt::Display for DataStore {
cluster_key,
config,
cluster_comp_cache: _,
messages: _,
indices,
components,
insert_id: _,
Expand Down
10 changes: 8 additions & 2 deletions crates/re_arrow_store/src/store_write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use parking_lot::RwLock;
use re_log::{debug, trace};
use re_log_types::{
msg_bundle::{wrap_in_listarray, ComponentBundle, MsgBundle},
ComponentName, ObjPath as EntityPath, TimeInt, TimePoint, TimeRange, Timeline,
ComponentName, MsgId, ObjPath as EntityPath, TimeInt, TimePoint, TimeRange, Timeline,
};

use crate::{
Expand Down Expand Up @@ -70,7 +70,7 @@ impl DataStore {
self.insert_id += 1;

let MsgBundle {
msg_id: _,
msg_id,
obj_path: ent_path,
time_point,
components,
Expand Down Expand Up @@ -152,6 +152,8 @@ impl DataStore {
index.insert(&self.config, *time, &row_indices)?;
}

self.messages.insert(*msg_id, time_point.clone());

Ok(())
}

Expand Down Expand Up @@ -313,6 +315,10 @@ impl DataStore {
}
}
}

pub fn get_msg_metadata(&self, msg_id: &MsgId) -> Option<&TimePoint> {
self.messages.get(msg_id)
}
}

// --- Indices ---
Expand Down
2 changes: 1 addition & 1 deletion crates/re_arrow_store/tests/data_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ fn joint_df(cluster_key: ComponentName, bundles: &[(ComponentName, &MsgBundle)])
Series::try_from((
cluster_key.as_str(),
wrap_in_listarray(
UInt64Array::from_vec((0..bundle.len() as u64).collect()).to_boxed(),
UInt64Array::from_vec((0..bundle.row_len(0) as u64).collect()).to_boxed(),
)
.to_boxed(),
))
Expand Down
25 changes: 19 additions & 6 deletions crates/re_data_store/src/log_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use itertools::Itertools as _;
use nohash_hasher::IntMap;

use re_log_types::{
field_types::Instance,
field_types::{Instance, TextEntry},
msg_bundle::{Component as _, MsgBundle},
objects, ArrowMsg, BatchIndex, BeginRecordingMsg, DataMsg, DataPath, DataVec, LogMsg,
LoggedData, MsgId, ObjPath, ObjPathHash, ObjTypePath, ObjectType, PathOp, PathOpMsg,
Expand Down Expand Up @@ -128,11 +128,24 @@ impl ObjDb {
fn try_add_arrow_data_msg(&mut self, msg: &ArrowMsg) -> Result<(), Error> {
let msg_bundle = MsgBundle::try_from(msg).map_err(Error::MsgBundleError)?;

// TODO(jleibs): Hack in a type so the UI treats these objects as visible
// This can go away once we determine object categories directly from the arrow table
self.types
.entry(msg_bundle.obj_path.obj_type_path().clone())
.or_insert(ObjectType::ArrowObject);
// Determine the kind of object we're looking at based on the components that have been
// uploaded _first_.
//
// TODO(cmc): That's an extension of the hack below, and will disappear at the same time
// and for the same reasons.
{
let obj_type = if msg_bundle.find_component(&TextEntry::name()).is_some() {
ObjectType::TextEntry
} else {
// TODO(jleibs): Hack in a type so the UI treats these objects as visible
// This can go away once we determine object categories directly from the arrow
// table
ObjectType::ArrowObject
};
self.types
.entry(msg_bundle.obj_path.obj_type_path().clone())
.or_insert(obj_type);
}

self.register_obj_path(&msg_bundle.obj_path);

Expand Down
5 changes: 4 additions & 1 deletion crates/re_log_types/src/field_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod quaternion;
mod radius;
mod rect;
mod size;
mod text_entry;

pub use class_id::ClassId;
pub use color::ColorRGBA;
Expand All @@ -31,10 +32,11 @@ pub use quaternion::Quaternion;
pub use radius::Radius;
pub use rect::Rect2D;
pub use size::Size3D;
pub use text_entry::TextEntry;

lazy_static! {
//TODO(john) actully use a run-time type registry
static ref FIELDS: [Field; 11] = [
static ref FIELDS: [Field; 12] = [
<ColorRGBA as Component>::field(),
<Instance as Component>::field(),
<KeypointId as Component>::field(),
Expand All @@ -46,6 +48,7 @@ lazy_static! {
<Radius as Component>::field(),
<Rect2D as Component>::field(),
<Size3D as Component>::field(),
<TextEntry as Component>::field(),
];
}

Expand Down
48 changes: 48 additions & 0 deletions crates/re_log_types/src/field_types/text_entry.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use arrow2_convert::ArrowField;

use crate::msg_bundle::Component;

/// A text entry component, comprised of a text body and its log level.
///
/// ```
/// use re_log_types::field_types::TextEntry;
/// use arrow2_convert::field::ArrowField;
/// use arrow2::datatypes::{DataType, Field};
///
/// assert_eq!(
/// TextEntry::data_type(),
/// DataType::Struct(vec![
/// Field::new("body", DataType::Utf8, false),
/// Field::new("level", DataType::Utf8, true),
/// ])
/// );
/// ```
#[derive(Clone, Debug, ArrowField, PartialEq, Eq)]
pub struct TextEntry {
pub body: String,
pub level: Option<String>,
Wumpf marked this conversation as resolved.
Show resolved Hide resolved
}

impl TextEntry {
#[inline]
pub fn new(body: impl Into<String>, level: Option<impl Into<String>>) -> Self {
Self {
body: body.into(),
level: level.map(Into::into),
}
}

#[inline]
pub fn from_body(body: impl Into<String>) -> Self {
Self {
body: body.into(),
level: None,
}
}
}

impl Component for TextEntry {
fn name() -> crate::ComponentName {
"rerun.text_entry".into()
}
}
25 changes: 21 additions & 4 deletions crates/re_log_types/src/msg_bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ impl MsgBundle {
//
// TODO(#440): support splats & remove this hack.
this.components
.push(vec![msg_id; this.len()].try_into().unwrap());
.push(vec![msg_id; this.row_len(0)].try_into().unwrap());

this
}
Expand Down Expand Up @@ -242,16 +242,33 @@ impl MsgBundle {
Ok(())
}

/// Returns the length of the bundle, i.e. its _number of rows_.
pub fn len(&self) -> usize {
/// Returns the length of a specific row within the bundle, i.e. the row's _number of
/// instances_.
///
/// Panics if `row_nr` is out of bounds.
pub fn row_len(&self, row_nr: usize) -> usize {
// TODO(#440): won't be able to pick any component randomly once we support splats!
self.components.first().map_or(0, |bundle| {
let offsets = bundle
.value
.as_any()
.downcast_ref::<ListArray<i32>>()
.unwrap()
.offsets();
(offsets[1] - offsets[0]) as usize
(offsets[row_nr + 1] - offsets[row_nr]) as usize
})
}

/// Returns the length of the bundle, i.e. its _number of rows_.
pub fn len(&self) -> usize {
// TODO(#440): won't be able to pick any component randomly once we support splats!
self.components.first().map_or(0, |bundle| {
bundle
.value
.as_any()
.downcast_ref::<ListArray<i32>>()
.unwrap()
.len()
})
}

Expand Down
88 changes: 84 additions & 4 deletions crates/re_viewer/src/ui/view_text/scene.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
use re_arrow_store::TimeRange;
use re_data_store::{query::visit_type_data_2, FieldName, ObjPath, TimeQuery};
use re_log_types::{IndexHash, MsgId, ObjectType};
use re_log_types::{
field_types::{self, Instance},
msg_bundle::Component,
IndexHash, MsgId, ObjectType,
};
use re_query::{range_entity_with_primary, QueryError};

use crate::{ui::SceneQuery, ViewerContext};

use super::ui::ViewTextFilters;

// ---

/// A single text entry.
#[derive(Debug, Clone)]
pub struct TextEntry {
// props
pub msg_id: MsgId,
Expand All @@ -18,6 +24,9 @@ pub struct TextEntry {
// text entry
pub level: Option<String>,
pub body: String,

// temp
teh-cmc marked this conversation as resolved.
Show resolved Hide resolved
pub is_arrow: bool,
}

/// A text scene, with everything needed to render it.
Expand All @@ -37,6 +46,8 @@ impl SceneText {
crate::profile_function!();

self.load_text_entries(ctx, query, filters);

self.load_text_entries_arrow(ctx, query, filters);
}

fn load_text_entries(
Expand Down Expand Up @@ -87,6 +98,7 @@ impl SceneText {
color: color.copied(),
level: level.map(ToOwned::to_owned),
body: body.clone(),
is_arrow: false,
});
}
},
Expand All @@ -97,7 +109,75 @@ impl SceneText {
// The most important order is the the `time` for whatever timeline we are on.
// For a tie-breaker, we use MsgId as that is ordered by a high-resolution wall-time.
crate::profile_scope!("sort");
self.text_entries
.sort_by_key(|entry| (entry.time, entry.msg_id));
self.text_entries.sort_by_key(|te| (te.time, te.msg_id));
}

fn load_text_entries_arrow(
&mut self,
ctx: &ViewerContext<'_>,
query: &SceneQuery<'_>,
filters: &ViewTextFilters,
) {
crate::profile_function!();

let store = &ctx.log_db.obj_db.arrow_store;

for obj_path in query.obj_paths {
let ent_path = obj_path;

// Early filtering: if we're not showing it the view, there isn't much point
// in querying it to begin with... at least for now.
if !filters.is_obj_path_visible(ent_path) {
return;
}

let query = re_arrow_store::RangeQuery::new(
query.timeline,
TimeRange::new(i64::MIN.into(), i64::MAX.into()),
);

let components = [
Instance::name(),
MsgId::name(),
field_types::TextEntry::name(),
field_types::ColorRGBA::name(),
];
let ent_views = range_entity_with_primary::<field_types::TextEntry, 4>(
store, &query, ent_path, components,
);

for (time, ent_view) in ent_views {
match ent_view.visit3(
|_instance,
text_entry: field_types::TextEntry,
msg_id: Option<MsgId>,
color: Option<field_types::ColorRGBA>| {
let field_types::TextEntry { body, level } = text_entry;

// Early filtering once more, see above.
let is_visible = level
.as_ref()
.map_or(true, |lvl| filters.is_log_level_visible(lvl));

if is_visible {
self.text_entries.push(TextEntry {
msg_id: msg_id.unwrap(), // always present
obj_path: obj_path.clone(),
time: time.as_i64(),
color: color.map(|c| c.to_array()),
level,
body,
is_arrow: true,
});
}
},
) {
Ok(_) | Err(QueryError::PrimaryNotFound) => {}
Err(err) => {
re_log::error_once!("Unexpected error querying '{ent_path:?}': {err:?}");
}
}
}
}
}
}
Loading