mirror of
https://github.com/YGGverse/Yoda.git
synced 2026-03-31 16:45:27 +00:00
reorganize history memory model
This commit is contained in:
parent
6526ca85d8
commit
268af30830
14 changed files with 172 additions and 218 deletions
|
|
@ -1,13 +1,15 @@
|
|||
// mod database;
|
||||
mod item;
|
||||
mod memory;
|
||||
|
||||
use gtk::glib::GString;
|
||||
use item::Item;
|
||||
use memory::Memory;
|
||||
|
||||
use sqlite::Connection;
|
||||
use std::{rc::Rc, sync::RwLock};
|
||||
use std::{cell::RefCell, rc::Rc, sync::RwLock};
|
||||
|
||||
pub struct History {
|
||||
pub memory: Rc<Memory>, // fast search index
|
||||
memory: RefCell<Memory>, // fast search index
|
||||
}
|
||||
|
||||
impl History {
|
||||
|
|
@ -16,9 +18,36 @@ impl History {
|
|||
/// Create new `Self`
|
||||
pub fn build(_connection: &Rc<RwLock<Connection>>, _profile_id: &Rc<i64>) -> Self {
|
||||
// Init children components
|
||||
let memory = Rc::new(Memory::new());
|
||||
let memory = RefCell::new(Memory::new());
|
||||
|
||||
// Return new `Self`
|
||||
Self { memory }
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
/// Create new history record
|
||||
pub fn open(&self, request: GString) {
|
||||
let mut memory = self.memory.borrow_mut();
|
||||
if !memory.open(&request) {
|
||||
memory.add(Item::create(0, request)) // @TODO
|
||||
}
|
||||
}
|
||||
|
||||
/// Close existing history record
|
||||
pub fn close(&self, request: &str) {
|
||||
self.memory.borrow_mut().close(request)
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
/// Get recently `opened` Items vector from the memory index, sorted by ASC
|
||||
pub fn recently_opened(&self, limit: Option<usize>) -> Vec<Item> {
|
||||
self.memory.borrow().recently_opened(limit)
|
||||
}
|
||||
|
||||
/// Get recently `closed` Items vector from the memory index, sorted by ASC
|
||||
pub fn recently_closed(&self, limit: Option<usize>) -> Vec<Item> {
|
||||
self.memory.borrow().recently_closed(limit)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
src/profile/history/item.rs
Normal file
40
src/profile/history/item.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
use gtk::glib::{DateTime, GString};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Item {
|
||||
pub id: i64,
|
||||
pub request: GString,
|
||||
pub created: DateTime,
|
||||
pub opened: DateTime,
|
||||
pub closed: Option<DateTime>,
|
||||
}
|
||||
|
||||
impl Item {
|
||||
// Constructors
|
||||
|
||||
pub fn create(id: i64, request: GString) -> Self {
|
||||
Self {
|
||||
id,
|
||||
request,
|
||||
created: now(),
|
||||
opened: now(),
|
||||
closed: None,
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
pub fn open(&mut self) {
|
||||
self.opened = now()
|
||||
}
|
||||
|
||||
pub fn close(&mut self) {
|
||||
self.closed = Some(now())
|
||||
}
|
||||
}
|
||||
|
||||
// Tools
|
||||
|
||||
fn now() -> DateTime {
|
||||
DateTime::now_local().unwrap()
|
||||
}
|
||||
|
|
@ -1,13 +1,81 @@
|
|||
mod request;
|
||||
mod tab;
|
||||
|
||||
use request::Request;
|
||||
use tab::Tab;
|
||||
use super::Item;
|
||||
use itertools::Itertools;
|
||||
|
||||
/// Reduce disk usage by cache Bookmarks index in memory
|
||||
pub struct Memory {
|
||||
pub request: Request,
|
||||
pub tab: Tab,
|
||||
pub struct Memory(Vec<Item>);
|
||||
|
||||
impl Memory {
|
||||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new() -> Self {
|
||||
Self(Vec::new())
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
pub fn add(&mut self, item: Item) {
|
||||
self.0.push(item)
|
||||
}
|
||||
|
||||
/// Update `opened` time for given `request`
|
||||
/// * return `false` if the `request` not found in memory index
|
||||
pub fn open(&mut self, request: &str) -> bool {
|
||||
for record in &mut self.0 {
|
||||
if record.request == request {
|
||||
record.open();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Update `closed` time for given `request`
|
||||
pub fn close(&mut self, request: &str) {
|
||||
for record in &mut self.0 {
|
||||
if record.request == request {
|
||||
record.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Getters
|
||||
|
||||
/// Get recent Items vector sorted by `closed` ASC
|
||||
pub fn recently_closed(&self, limit: Option<usize>) -> Vec<Item> {
|
||||
let mut recent: Vec<Item> = Vec::new();
|
||||
for (i, item) in self
|
||||
.0
|
||||
.iter()
|
||||
.filter(|x| x.closed.is_some())
|
||||
.sorted_by(|a, b| Ord::cmp(&a.closed, &b.closed))
|
||||
.enumerate()
|
||||
{
|
||||
if limit.is_some_and(|l| i > l) {
|
||||
break;
|
||||
}
|
||||
recent.push(item.clone())
|
||||
}
|
||||
recent
|
||||
}
|
||||
|
||||
/// Get recent Items vector sorted by `opened` ASC
|
||||
pub fn recently_opened(&self, limit: Option<usize>) -> Vec<Item> {
|
||||
let mut recent: Vec<Item> = Vec::new();
|
||||
for (i, item) in self
|
||||
.0
|
||||
.iter()
|
||||
.sorted_by(|a, b| Ord::cmp(&a.opened, &b.opened))
|
||||
.enumerate()
|
||||
{
|
||||
if limit.is_some_and(|l| i > l) {
|
||||
break;
|
||||
}
|
||||
recent.push(item.clone())
|
||||
}
|
||||
recent
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Memory {
|
||||
|
|
@ -15,15 +83,3 @@ impl Default for Memory {
|
|||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Memory {
|
||||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
request: Request::new(),
|
||||
tab: Tab::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
use gtk::glib::{DateTime, GString, Uri};
|
||||
use itertools::Itertools;
|
||||
use std::{cell::RefCell, collections::HashMap};
|
||||
|
||||
pub struct Value {
|
||||
pub unix_timestamp: i64,
|
||||
pub uri: Uri,
|
||||
}
|
||||
|
||||
/// Recent request history
|
||||
pub struct Request {
|
||||
index: RefCell<HashMap<GString, Value>>,
|
||||
}
|
||||
|
||||
impl Default for Request {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Request {
|
||||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
index: RefCell::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
/// Add new record with `request` as key and `unix_timestamp` as value
|
||||
/// * replace with new value if `request` already exists
|
||||
pub fn set(&self, uri: Uri) {
|
||||
self.index.borrow_mut().insert(
|
||||
uri.to_str(),
|
||||
Value {
|
||||
unix_timestamp: DateTime::now_local().unwrap().to_unix(),
|
||||
uri,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/// Get recent records vector
|
||||
/// * sorted by `unix_timestamp` DESC
|
||||
pub fn recent(&self) -> Vec<Uri> {
|
||||
let mut recent: Vec<Uri> = Vec::new();
|
||||
for (_, value) in self
|
||||
.index
|
||||
.borrow()
|
||||
.iter()
|
||||
.sorted_by(|a, b| Ord::cmp(&b.1.unix_timestamp, &a.1.unix_timestamp))
|
||||
{
|
||||
recent.push(value.uri.clone())
|
||||
}
|
||||
recent
|
||||
}
|
||||
|
||||
/// Get records total
|
||||
pub fn total(&self) -> usize {
|
||||
self.index.borrow().len()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
use crate::app::browser::window::tab::Item;
|
||||
use itertools::Itertools;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub struct Record {
|
||||
pub item: Rc<Item>,
|
||||
pub unix_timestamp: i64,
|
||||
}
|
||||
|
||||
/// Recently closed tabs index
|
||||
pub struct Tab {
|
||||
index: RefCell<Vec<Record>>,
|
||||
}
|
||||
|
||||
impl Default for Tab {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Tab {
|
||||
// Constructors
|
||||
|
||||
/// Create new `Self`
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
index: RefCell::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
// Actions
|
||||
|
||||
/// Add new record
|
||||
/// * replace with new one if the record already exist
|
||||
pub fn add(&self, item: Rc<Item>, unix_timestamp: i64) {
|
||||
self.index.borrow_mut().push(Record {
|
||||
item,
|
||||
unix_timestamp,
|
||||
});
|
||||
}
|
||||
|
||||
/// Get recent `Item` vector sorted by `unix_timestamp` DESC
|
||||
pub fn recent(&self) -> Vec<Rc<Item>> {
|
||||
let mut recent: Vec<Rc<Item>> = Vec::new();
|
||||
for record in self
|
||||
.index
|
||||
.borrow()
|
||||
.iter()
|
||||
.sorted_by(|a, b| Ord::cmp(&b.unix_timestamp, &a.unix_timestamp))
|
||||
{
|
||||
recent.push(record.item.clone())
|
||||
}
|
||||
recent
|
||||
}
|
||||
|
||||
/// Get records total
|
||||
pub fn total(&self) -> usize {
|
||||
self.index.borrow().len()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue