summaryrefslogtreecommitdiff
path: root/src/database/key_value/rooms/search.rs
diff options
context:
space:
mode:
authorNyaaori <+@nyaaori.cat>2022-10-09 18:52:58 +0200
committerNyaaori <+@nyaaori.cat>2022-10-09 18:52:58 +0200
commit877ee484803e0a3b3b36aa292bc08189ae078275 (patch)
tree04848348c1501022d05a45de0f5dbbba5b01cb7f /src/database/key_value/rooms/search.rs
parent03e6e43ecd00e739d85f99ebd1bfe289e2bbecb3 (diff)
downloadconduit-877ee484803e0a3b3b36aa292bc08189ae078275.zip
refactor: prepare database/key_value/rooms/search.rs from service/rooms/search/mod.rs
Diffstat (limited to 'src/database/key_value/rooms/search.rs')
-rw-r--r--src/database/key_value/rooms/search.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/database/key_value/rooms/search.rs b/src/database/key_value/rooms/search.rs
new file mode 100644
index 0000000..ce05505
--- /dev/null
+++ b/src/database/key_value/rooms/search.rs
@@ -0,0 +1,50 @@
+
+ #[tracing::instrument(skip(self))]
+ pub fn search_pdus<'a>(
+ &'a self,
+ room_id: &RoomId,
+ search_string: &str,
+ ) -> Result<Option<(impl Iterator<Item = Vec<u8>> + 'a, Vec<String>)>> {
+ let prefix = self
+ .get_shortroomid(room_id)?
+ .expect("room exists")
+ .to_be_bytes()
+ .to_vec();
+ let prefix_clone = prefix.clone();
+
+ let words: Vec<_> = search_string
+ .split_terminator(|c: char| !c.is_alphanumeric())
+ .filter(|s| !s.is_empty())
+ .map(str::to_lowercase)
+ .collect();
+
+ let iterators = words.clone().into_iter().map(move |word| {
+ let mut prefix2 = prefix.clone();
+ prefix2.extend_from_slice(word.as_bytes());
+ prefix2.push(0xff);
+
+ let mut last_possible_id = prefix2.clone();
+ last_possible_id.extend_from_slice(&u64::MAX.to_be_bytes());
+
+ self.tokenids
+ .iter_from(&last_possible_id, true) // Newest pdus first
+ .take_while(move |(k, _)| k.starts_with(&prefix2))
+ .map(|(key, _)| key[key.len() - size_of::<u64>()..].to_vec())
+ });
+
+ Ok(utils::common_elements(iterators, |a, b| {
+ // We compare b with a because we reversed the iterator earlier
+ b.cmp(a)
+ })
+ .map(|iter| {
+ (
+ iter.map(move |id| {
+ let mut pduid = prefix_clone.clone();
+ pduid.extend_from_slice(&id);
+ pduid
+ }),
+ words,
+ )
+ }))
+ }
+