[fractal/fractal-next] categories: add new rooms in batch
- From: Julian Sparber <jsparber src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [fractal/fractal-next] categories: add new rooms in batch
- Date: Wed, 5 May 2021 14:18:41 +0000 (UTC)
commit 86b753cb4a5f4611679bed68e71109149e6ce657
Author: Julian Sparber <julian sparber net>
Date: Wed May 5 14:47:12 2021 +0200
categories: add new rooms in batch
This reduces the number of times the singal `items-changed` is emited.
Which improves performance when adding many new rooms
src/session/categories/categories.rs | 76 ++++++++++++++++--------------------
src/session/categories/category.rs | 15 +++++++
2 files changed, 49 insertions(+), 42 deletions(-)
---
diff --git a/src/session/categories/categories.rs b/src/session/categories/categories.rs
index 7802dde9..687d67e1 100644
--- a/src/session/categories/categories.rs
+++ b/src/session/categories/categories.rs
@@ -1,5 +1,5 @@
use gtk::{gio, glib, glib::clone, prelude::*, subclass::prelude::*};
-use std::collections::{hash_map::Entry, HashMap};
+use std::collections::HashMap;
use crate::session::{
categories::{Category, CategoryType},
@@ -74,58 +74,50 @@ impl Categories {
pub fn append(&self, rooms: Vec<Room>) {
let priv_ = imp::Categories::from_instance(&self);
- for room in rooms {
- if priv_.room_map.borrow().contains_key(&room) {
- return;
+ let rooms: Vec<Room> = {
+ let room_map = priv_.room_map.borrow();
+ rooms
+ .into_iter()
+ .filter(|room| !room_map.contains_key(&room))
+ .collect()
+ };
+
+ let rooms_by_category = rooms.into_iter().fold(HashMap::new(), |mut acc, room| {
+ acc.entry(room.category()).or_insert(vec![]).push(room);
+ acc
+ });
+ let mut room_map = priv_.room_map.borrow_mut();
+ for (category_type, rooms) in rooms_by_category {
+ for room in &rooms {
+ room_map.insert(room.clone(), category_type);
+ room.connect_notify_local(
+ Some("category"),
+ clone!(@weak self as obj => move |room, _| {
+ obj.move_room(room);
+ }),
+ );
}
- room.connect_notify_local(
- Some("category"),
- clone!(@weak self as obj => move |room, _| {
- obj.move_room(room);
- }),
- );
- // TODO: Add all rooms at once
- self.move_room(&room);
+ self.find_category_by_type(category_type)
+ .append_batch(rooms);
}
}
- fn move_room(&self, room: &Room) {
+ fn find_category_by_type(&self, type_: CategoryType) -> &Category {
let priv_ = imp::Categories::from_instance(&self);
- let mut room_map = priv_.room_map.borrow_mut();
-
- let entry = room_map.entry(room.clone());
-
- match entry {
- Entry::Occupied(mut entry) => {
- if entry.get() != &room.category() {
- entry.insert(room.category());
- self.remove_from_category(entry.get(), room);
- self.add_to_category(entry.get(), room);
- }
- }
- Entry::Vacant(entry) => {
- entry.insert(room.category());
- self.add_to_category(&room.category(), room);
- }
- }
+ let position = priv_.list.iter().position(|item| item.type_() == type_);
+ priv_.list.get(position.unwrap()).unwrap()
}
- fn add_to_category(&self, type_: &CategoryType, room: &Room) {
+ fn move_room(&self, room: &Room) {
let priv_ = imp::Categories::from_instance(&self);
+ let mut room_map = priv_.room_map.borrow_mut();
- let position = priv_.list.iter().position(|item| item.type_() == *type_);
- if let Some(position) = position {
- priv_.list.get(position).unwrap().append(room);
+ if let Some(old_category_type) = room_map.remove(&room) {
+ self.find_category_by_type(old_category_type).remove(room);
}
- }
- fn remove_from_category(&self, type_: &CategoryType, room: &Room) {
- let priv_ = imp::Categories::from_instance(&self);
-
- let position = priv_.list.iter().position(|item| item.type_() == *type_);
- if let Some(position) = position {
- priv_.list.get(position).unwrap().remove(room);
- }
+ room_map.insert(room.clone(), room.category());
+ self.find_category_by_type(room.category()).append(room);
}
}
diff --git a/src/session/categories/category.rs b/src/session/categories/category.rs
index 3becb53e..08823535 100644
--- a/src/session/categories/category.rs
+++ b/src/session/categories/category.rs
@@ -113,6 +113,21 @@ impl Category {
self.items_changed(index as u32, 0, 1);
}
+ pub fn append_batch(&self, rooms: Vec<Room>) {
+ let priv_ = imp::Category::from_instance(self);
+ let added = rooms.len();
+ let index = {
+ let mut list = priv_.list.borrow_mut();
+ let index = list.len();
+ list.reserve(added);
+ for room in rooms {
+ list.push(room);
+ }
+ index
+ };
+ self.items_changed(index as u32, 0, added as u32);
+ }
+
pub fn remove(&self, room: &Room) {
let priv_ = imp::Category::from_instance(self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]