mirror of
https://gitlab.com/famedly/conduit.git
synced 2025-08-11 17:50:59 +00:00
feat(spaces): sort space room children & simplify
This commit is contained in:
parent
1a4a348ccf
commit
b631621f8c
1 changed files with 37 additions and 37 deletions
|
@ -1,5 +1,4 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::VecDeque,
|
|
||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
|
@ -457,7 +456,7 @@ impl Service {
|
||||||
max_depth: usize,
|
max_depth: usize,
|
||||||
suggested_only: bool,
|
suggested_only: bool,
|
||||||
) -> Result<client::space::get_hierarchy::v1::Response> {
|
) -> Result<client::space::get_hierarchy::v1::Response> {
|
||||||
let mut parents = VecDeque::new();
|
let mut parents = Vec::new();
|
||||||
|
|
||||||
// Don't start populating the results if we have to start at a specific room.
|
// Don't start populating the results if we have to start at a specific room.
|
||||||
let mut populate_results = short_room_ids.is_empty();
|
let mut populate_results = short_room_ids.is_empty();
|
||||||
|
@ -489,27 +488,25 @@ impl Service {
|
||||||
get_parent_children_via(*summary.clone(), suggested_only)
|
get_parent_children_via(*summary.clone(), suggested_only)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|(room, _)| parents.iter().all(|parent| parent != room))
|
.filter(|(room, _)| parents.iter().all(|parent| parent != room))
|
||||||
.rev()
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if populate_results {
|
if populate_results {
|
||||||
results.push(summary_to_chunk(*summary.clone()))
|
results.push(summary_to_chunk(*summary.clone()));
|
||||||
} else {
|
} else {
|
||||||
|
let mut prev_child_in_short_ids = false;
|
||||||
children = children
|
children = children
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.rev()
|
.take_while(|(room, _)| {
|
||||||
.skip_while(|(room, _)| {
|
|
||||||
if let Ok(short) = services().rooms.short.get_shortroomid(room)
|
if let Ok(short) = services().rooms.short.get_shortroomid(room)
|
||||||
{
|
{
|
||||||
short.as_ref() != short_room_ids.get(parents.len())
|
let tmp = prev_child_in_short_ids;
|
||||||
|
prev_child_in_short_ids =
|
||||||
|
short.as_ref() == short_room_ids.get(parents.len());
|
||||||
|
!tmp
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
|
||||||
// skip_while doesn't implement DoubleEndedIterator, which is needed for rev
|
|
||||||
.into_iter()
|
|
||||||
.rev()
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if children.is_empty() {
|
if children.is_empty() {
|
||||||
|
@ -526,7 +523,7 @@ impl Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !children.is_empty() && parents.len() < max_depth {
|
if !children.is_empty() && parents.len() < max_depth {
|
||||||
parents.push_back(current_room.clone());
|
parents.push(current_room.clone());
|
||||||
stack.push(children);
|
stack.push(children);
|
||||||
}
|
}
|
||||||
// Root room in the space hierarchy, we return an error if this one fails.
|
// Root room in the space hierarchy, we return an error if this one fails.
|
||||||
|
@ -553,19 +550,18 @@ impl Service {
|
||||||
|
|
||||||
Ok(client::space::get_hierarchy::v1::Response {
|
Ok(client::space::get_hierarchy::v1::Response {
|
||||||
next_batch: if let Some((room, _)) = next_room_to_traverse(&mut stack, &mut parents) {
|
next_batch: if let Some((room, _)) = next_room_to_traverse(&mut stack, &mut parents) {
|
||||||
parents.pop_front();
|
parents.push(room);
|
||||||
parents.push_back(room);
|
|
||||||
|
|
||||||
let mut short_room_ids = vec![];
|
let mut short_room_ids = vec![];
|
||||||
|
|
||||||
for room in parents {
|
for room in parents.into_iter().skip(1) {
|
||||||
short_room_ids.push(services().rooms.short.get_or_create_shortroomid(&room)?);
|
short_room_ids.push(services().rooms.short.get_or_create_shortroomid(&room)?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
PagnationToken {
|
PagnationToken {
|
||||||
short_room_ids,
|
short_room_ids,
|
||||||
limit: UInt::new(max_depth as u64)
|
limit: UInt::new(limit as u64)
|
||||||
.expect("When sent in request it must have been valid UInt"),
|
.expect("When sent in request it must have been valid UInt"),
|
||||||
max_depth: UInt::new(max_depth as u64)
|
max_depth: UInt::new(max_depth as u64)
|
||||||
.expect("When sent in request it must have been valid UInt"),
|
.expect("When sent in request it must have been valid UInt"),
|
||||||
|
@ -583,11 +579,11 @@ impl Service {
|
||||||
|
|
||||||
fn next_room_to_traverse(
|
fn next_room_to_traverse(
|
||||||
stack: &mut Vec<Vec<(OwnedRoomId, Vec<OwnedServerName>)>>,
|
stack: &mut Vec<Vec<(OwnedRoomId, Vec<OwnedServerName>)>>,
|
||||||
parents: &mut VecDeque<OwnedRoomId>,
|
parents: &mut Vec<OwnedRoomId>,
|
||||||
) -> Option<(OwnedRoomId, Vec<OwnedServerName>)> {
|
) -> Option<(OwnedRoomId, Vec<OwnedServerName>)> {
|
||||||
while stack.last().is_some_and(|s| s.is_empty()) {
|
while stack.last().is_some_and(|s| s.is_empty()) {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
parents.pop_back();
|
parents.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
stack.last_mut().and_then(|s| s.pop())
|
stack.last_mut().and_then(|s| s.pop())
|
||||||
|
@ -727,18 +723,20 @@ fn get_parent_children_via(
|
||||||
parent: SpaceHierarchyParentSummary,
|
parent: SpaceHierarchyParentSummary,
|
||||||
suggested_only: bool,
|
suggested_only: bool,
|
||||||
) -> Vec<(OwnedRoomId, Vec<OwnedServerName>)> {
|
) -> Vec<(OwnedRoomId, Vec<OwnedServerName>)> {
|
||||||
parent
|
let mut children = parent
|
||||||
.children_state
|
.children_state
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|raw_ce| {
|
.filter_map(|raw| raw.deserialize().ok())
|
||||||
raw_ce.deserialize().map_or(None, |ce| {
|
.filter(|child| !suggested_only || child.content.suggested)
|
||||||
if suggested_only && !ce.content.suggested {
|
.collect::<Vec<_>>();
|
||||||
None
|
|
||||||
} else {
|
children.sort();
|
||||||
Some((ce.state_key, ce.content.via))
|
|
||||||
}
|
children
|
||||||
})
|
.into_iter()
|
||||||
})
|
// We reverse, as we want to traverse the ones that come first in the list first (via `Vec::pop`)
|
||||||
|
.rev()
|
||||||
|
.map(|child| (child.state_key, child.content.via))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,7 +765,7 @@ mod tests {
|
||||||
],
|
],
|
||||||
"suggested": false
|
"suggested": false
|
||||||
},
|
},
|
||||||
"origin_server_ts": 1629413349153,
|
"origin_server_ts": 111,
|
||||||
"sender": "@alice:example.org",
|
"sender": "@alice:example.org",
|
||||||
"state_key": "!foo:example.org",
|
"state_key": "!foo:example.org",
|
||||||
"type": "m.space.child"
|
"type": "m.space.child"
|
||||||
|
@ -782,7 +780,7 @@ mod tests {
|
||||||
],
|
],
|
||||||
"suggested": true
|
"suggested": true
|
||||||
},
|
},
|
||||||
"origin_server_ts": 1629413349157,
|
"origin_server_ts": 333,
|
||||||
"sender": "@alice:example.org",
|
"sender": "@alice:example.org",
|
||||||
"state_key": "!bar:example.org",
|
"state_key": "!bar:example.org",
|
||||||
"type": "m.space.child"
|
"type": "m.space.child"
|
||||||
|
@ -794,9 +792,10 @@ mod tests {
|
||||||
"content": {
|
"content": {
|
||||||
"via": [
|
"via": [
|
||||||
"example.org"
|
"example.org"
|
||||||
]
|
],
|
||||||
|
"order": ""
|
||||||
},
|
},
|
||||||
"origin_server_ts": 1629413349160,
|
"origin_server_ts": 222,
|
||||||
"sender": "@alice:example.org",
|
"sender": "@alice:example.org",
|
||||||
"state_key": "!baz:example.org",
|
"state_key": "!baz:example.org",
|
||||||
"type": "m.space.child"
|
"type": "m.space.child"
|
||||||
|
@ -806,21 +805,22 @@ mod tests {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// it's in reverse order, so `pop` gives the first room to be fetched
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
get_parent_children_via(summary.clone(), false),
|
get_parent_children_via(summary.clone(), false),
|
||||||
vec![
|
vec![
|
||||||
(
|
|
||||||
owned_room_id!("!foo:example.org"),
|
|
||||||
vec![owned_server_name!("example.org")]
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
owned_room_id!("!bar:example.org"),
|
owned_room_id!("!bar:example.org"),
|
||||||
vec![owned_server_name!("example.org")]
|
vec![owned_server_name!("example.org")]
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
owned_room_id!("!foo:example.org"),
|
||||||
|
vec![owned_server_name!("example.org")]
|
||||||
|
),
|
||||||
(
|
(
|
||||||
owned_room_id!("!baz:example.org"),
|
owned_room_id!("!baz:example.org"),
|
||||||
vec![owned_server_name!("example.org")]
|
vec![owned_server_name!("example.org")]
|
||||||
)
|
),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue