extract deltas reader

This commit is contained in:
Nikita Galaiko 2023-05-16 09:19:07 +02:00
parent 92e4e7604e
commit 59352d3247
8 changed files with 110 additions and 76 deletions

View File

@ -356,11 +356,12 @@ impl App {
.get_session(session_id) .get_session(session_id)
.context("failed to get session")?; .context("failed to get session")?;
let reader = gb_repository let session_reader = gb_repository
.get_session_reader(&session) .get_session_reader(&session)
.context("failed to get session reader")?; .context("failed to get session reader")?;
let deltas_reader = deltas::Reader::new(&session_reader);
reader.deltas(paths) deltas_reader.read(paths)
} }
pub fn git_activity( pub fn git_activity(

View File

@ -1,7 +1,9 @@
mod delta; mod delta;
mod document; mod document;
mod operations; mod operations;
mod reader;
pub use delta::Delta; pub use delta::Delta;
pub use document::Document; pub use document::Document;
pub use operations::Operation; pub use operations::Operation;
pub use reader::DeltasReader as Reader;

View File

@ -0,0 +1,61 @@
use std::{collections::HashMap, path};
use anyhow::Result;
use crate::app::{
reader::{self, Reader},
sessions,
};
use super::Delta;
pub struct DeltasReader<'reader> {
sessions_reader: &'reader sessions::SessionReader<'reader>,
}
impl<'reader> DeltasReader<'reader> {
pub fn new(session_reader: &'reader sessions::SessionReader) -> Self {
DeltasReader {
sessions_reader: session_reader,
}
}
pub fn read_file<P: AsRef<std::path::Path>>(&self, path: P) -> Result<Option<Vec<Delta>>> {
let path = path.as_ref();
let file_deltas_path = std::path::Path::new("session/deltas").join(path);
match self
.sessions_reader
.read_to_string(file_deltas_path.to_str().unwrap())
{
Ok(content) => {
if content.is_empty() {
// this is a leftover from some bug, shouldn't happen anymore
Ok(None)
} else {
Ok(Some(serde_json::from_str(&content)?))
}
}
Err(reader::Error::NotFound) => Ok(None),
Err(err) => Err(err.into()),
}
}
pub fn read(&self, paths: Option<Vec<&str>>) -> Result<HashMap<String, Vec<Delta>>> {
let deltas_dir = path::Path::new("session/deltas");
let files = self
.sessions_reader
.list_files(deltas_dir.to_str().unwrap())?;
let mut result = HashMap::new();
for file_path in files {
if let Some(paths) = paths.as_ref() {
if !paths.iter().any(|path| file_path.eq(path)) {
continue;
}
}
if let Some(deltas) = self.read_file(file_path.clone())? {
result.insert(file_path, deltas);
}
}
Ok(result)
}
}

View File

@ -241,8 +241,9 @@ fn test_list_deltas_from_current_session() -> Result<()> {
}], }],
)?; )?;
let reader = gb_repo.get_session_reader(&current_session)?; let session_reader = gb_repo.get_session_reader(&current_session)?;
let deltas = reader.deltas(None)?; let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read(None)?;
assert_eq!(deltas.len(), 1); assert_eq!(deltas.len(), 1);
assert_eq!(deltas.get("test.txt").unwrap()[0].operations.len(), 1); assert_eq!(deltas.get("test.txt").unwrap()[0].operations.len(), 1);
@ -281,8 +282,9 @@ fn test_list_deltas_from_flushed_session() -> Result<()> {
)?; )?;
let session = gb_repo.flush()?; let session = gb_repo.flush()?;
let reader = gb_repo.get_session_reader(&session.unwrap())?; let session_reader = gb_repo.get_session_reader(&session.unwrap())?;
let deltas = reader.deltas(None)?; let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read(None)?;
assert_eq!(deltas.len(), 1); assert_eq!(deltas.len(), 1);
assert_eq!(deltas.get("test.txt").unwrap()[0].operations.len(), 1); assert_eq!(deltas.get("test.txt").unwrap()[0].operations.len(), 1);
@ -439,9 +441,10 @@ fn test_remote_syncronization() -> Result<()> {
assert_eq!(sessions_two.len(), 1); assert_eq!(sessions_two.len(), 1);
assert_eq!(sessions_two[0].id, session_one.id); assert_eq!(sessions_two[0].id, session_one.id);
let reader = gb_repo_two.get_session_reader(&sessions_two[0])?; let session_reader = gb_repo_two.get_session_reader(&sessions_two[0])?;
let deltas = reader.deltas(None)?; let deltas_reader = deltas::Reader::new(&session_reader);
let files = reader.files(None)?; let deltas = deltas_reader.read(None)?;
let files = session_reader.files(None)?;
assert_eq!(deltas.len(), 1); assert_eq!(deltas.len(), 1);
assert_eq!(files.len(), 1); assert_eq!(files.len(), 1);
assert_eq!(files.get("test.txt").unwrap(), "Hello World"); assert_eq!(files.get("test.txt").unwrap(), "Hello World");

View File

@ -216,16 +216,17 @@ fn index_session(
session: &sessions::Session, session: &sessions::Session,
repository: &app::gb_repository::Repository, repository: &app::gb_repository::Repository,
) -> Result<()> { ) -> Result<()> {
let reader = repository let session_reader = repository
.get_session_reader(&session) .get_session_reader(&session)
.with_context(|| "could not get session reader")?; .with_context(|| "could not get session reader")?;
let deltas = reader let deltas_reader = deltas::Reader::new(&session_reader);
.deltas(None) let deltas = deltas_reader
.read(None)
.with_context(|| "could not list deltas for session")?; .with_context(|| "could not list deltas for session")?;
if deltas.is_empty() { if deltas.is_empty() {
return Ok(()); return Ok(());
} }
let files = reader let files = session_reader
.files(Some(deltas.keys().map(|k| k.as_str()).collect())) .files(Some(deltas.keys().map(|k| k.as_str()).collect()))
.with_context(|| "could not list files for session")?; .with_context(|| "could not list files for session")?;
// index every file // index every file

View File

@ -3,7 +3,7 @@ use std::collections::HashMap;
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use crate::app::{ use crate::app::{
deltas, gb_repository, gb_repository,
reader::{self, CommitReader, Reader}, reader::{self, CommitReader, Reader},
}; };
@ -113,44 +113,4 @@ impl<'reader> SessionReader<'reader> {
Ok(files_with_content) Ok(files_with_content)
} }
pub fn file_deltas<P: AsRef<std::path::Path>>(
&self,
path: P,
) -> Result<Option<Vec<deltas::Delta>>> {
let path = path.as_ref();
let file_deltas_path = std::path::Path::new("session/deltas").join(path);
match self
.reader
.read_to_string(file_deltas_path.to_str().unwrap())
{
Ok(content) => {
if content.is_empty() {
// this is a leftover from some bug, shouldn't happen anymore
Ok(None)
} else {
Ok(Some(serde_json::from_str(&content)?))
}
}
Err(reader::Error::NotFound) => Ok(None),
Err(err) => Err(err.into()),
}
}
pub fn deltas(&self, paths: Option<Vec<&str>>) -> Result<HashMap<String, Vec<deltas::Delta>>> {
let deltas_dir = std::path::Path::new("session/deltas");
let files = self.reader.list_files(deltas_dir.to_str().unwrap())?;
let mut result = HashMap::new();
for file_path in files {
if let Some(paths) = paths.as_ref() {
if !paths.iter().any(|path| file_path.eq(path)) {
continue;
}
}
if let Some(deltas) = self.file_deltas(file_path.clone())? {
result.insert(file_path, deltas);
}
}
Ok(result)
}
} }

View File

@ -141,12 +141,13 @@ impl<'listener> Handler<'listener> {
return Ok(None); return Ok(None);
} }
let current_session = current_session.unwrap(); let current_session = current_session.unwrap();
let reader = self let session_reader = self
.gb_repository .gb_repository
.get_session_reader(&current_session) .get_session_reader(&current_session)
.context("failed to get session reader")?; .context("failed to get session reader")?;
let deltas = reader let deltas_reader = deltas::Reader::new(&session_reader);
.file_deltas(path) let deltas = deltas_reader
.read_file(path)
.context("failed to get file deltas")?; .context("failed to get file deltas")?;
Ok(deltas) Ok(deltas)
} }
@ -199,9 +200,7 @@ impl<'listener> Handler<'listener> {
(Some(latest_contents), Some(deltas)) => { (Some(latest_contents), Some(deltas)) => {
deltas::Document::new(Some(&latest_contents), deltas)? deltas::Document::new(Some(&latest_contents), deltas)?
} }
(Some(latest_contents), None) => { (Some(latest_contents), None) => deltas::Document::new(Some(&latest_contents), vec![])?,
deltas::Document::new(Some(&latest_contents), vec![])?
}
(None, Some(deltas)) => deltas::Document::new(None, deltas)?, (None, Some(deltas)) => deltas::Document::new(None, deltas)?,
(None, None) => deltas::Document::new(None, vec![])?, (None, None) => deltas::Document::new(None, vec![])?,
}; };

View File

@ -83,7 +83,8 @@ fn test_register_existing_commited_file() -> Result<()> {
let session = gb_repo.get_current_session()?.unwrap(); let session = gb_repo.get_current_session()?.unwrap();
let session_reader = gb_repo.get_session_reader(&session)?; let session_reader = gb_repo.get_session_reader(&session)?;
let deltas = session_reader.file_deltas("test.txt")?.unwrap(); let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 1); assert_eq!(deltas.len(), 1);
assert_eq!(deltas[0].operations.len(), 1); assert_eq!(deltas[0].operations.len(), 1);
assert_eq!( assert_eq!(
@ -182,9 +183,10 @@ fn test_register_new_file() -> Result<()> {
listener.handle(file_path)?; listener.handle(file_path)?;
let sesssion = gb_repo.get_current_session()?.unwrap(); let session = gb_repo.get_current_session()?.unwrap();
let reader = gb_repo.get_session_reader(&sesssion)?; let session_reader = gb_repo.get_session_reader(&session)?;
let deltas = reader.file_deltas("test.txt")?.unwrap(); let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 1); assert_eq!(deltas.len(), 1);
assert_eq!(deltas[0].operations.len(), 1); assert_eq!(deltas[0].operations.len(), 1);
assert_eq!( assert_eq!(
@ -222,8 +224,9 @@ fn test_register_new_file_twice() -> Result<()> {
listener.handle(file_path)?; listener.handle(file_path)?;
let session = gb_repo.get_current_session()?.unwrap(); let session = gb_repo.get_current_session()?.unwrap();
let reader = gb_repo.get_session_reader(&session)?; let session_reader = gb_repo.get_session_reader(&session)?;
let deltas = reader.file_deltas("test.txt")?.unwrap(); let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 1); assert_eq!(deltas.len(), 1);
assert_eq!(deltas[0].operations.len(), 1); assert_eq!(deltas[0].operations.len(), 1);
assert_eq!( assert_eq!(
@ -238,7 +241,7 @@ fn test_register_new_file_twice() -> Result<()> {
std::fs::write(project_repo.root().join(file_path), "test2")?; std::fs::write(project_repo.root().join(file_path), "test2")?;
listener.handle(file_path)?; listener.handle(file_path)?;
let deltas = reader.file_deltas("test.txt")?.unwrap(); let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 2); assert_eq!(deltas.len(), 2);
assert_eq!(deltas[0].operations.len(), 1); assert_eq!(deltas[0].operations.len(), 1);
assert_eq!( assert_eq!(
@ -281,8 +284,9 @@ fn test_register_file_delted() -> Result<()> {
listener.handle(file_path)?; listener.handle(file_path)?;
let session = gb_repo.get_current_session()?.unwrap(); let session = gb_repo.get_current_session()?.unwrap();
let reader = gb_repo.get_session_reader(&session)?; let session_reader = gb_repo.get_session_reader(&session)?;
let deltas = reader.file_deltas("test.txt")?.unwrap(); let deltas_reader = deltas::Reader::new(&session_reader);
let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 1); assert_eq!(deltas.len(), 1);
assert_eq!(deltas[0].operations.len(), 1); assert_eq!(deltas[0].operations.len(), 1);
assert_eq!( assert_eq!(
@ -297,7 +301,7 @@ fn test_register_file_delted() -> Result<()> {
std::fs::remove_file(project_repo.root().join(file_path))?; std::fs::remove_file(project_repo.root().join(file_path))?;
listener.handle(file_path)?; listener.handle(file_path)?;
let deltas = reader.file_deltas("test.txt")?.unwrap(); let deltas = deltas_reader.read_file("test.txt")?.unwrap();
assert_eq!(deltas.len(), 2); assert_eq!(deltas.len(), 2);
assert_eq!(deltas[0].operations.len(), 1); assert_eq!(deltas[0].operations.len(), 1);
assert_eq!( assert_eq!(
@ -366,8 +370,9 @@ fn test_flow_with_commits() -> Result<()> {
// collect all operations from sessions in the reverse order // collect all operations from sessions in the reverse order
let mut operations: Vec<deltas::Operation> = vec![]; let mut operations: Vec<deltas::Operation> = vec![];
sessions_slice.iter().for_each(|session| { sessions_slice.iter().for_each(|session| {
let reader = gb_repo.get_session_reader(&session).unwrap(); let session_reader = gb_repo.get_session_reader(&session).unwrap();
let deltas_by_filepath = reader.deltas(None).unwrap(); let deltas_reader = deltas::Reader::new(&session_reader);
let deltas_by_filepath = deltas_reader.read(None).unwrap();
for deltas in deltas_by_filepath.values() { for deltas in deltas_by_filepath.values() {
deltas.iter().for_each(|delta| { deltas.iter().for_each(|delta| {
delta.operations.iter().for_each(|operation| { delta.operations.iter().for_each(|operation| {
@ -458,8 +463,9 @@ fn test_flow_no_commits() -> Result<()> {
// collect all operations from sessions in the reverse order // collect all operations from sessions in the reverse order
let mut operations: Vec<deltas::Operation> = vec![]; let mut operations: Vec<deltas::Operation> = vec![];
sessions_slice.iter().for_each(|session| { sessions_slice.iter().for_each(|session| {
let reader = gb_repo.get_session_reader(&session).unwrap(); let session_reader = gb_repo.get_session_reader(&session).unwrap();
let deltas_by_filepath = reader.deltas(None).unwrap(); let deltas_reader = deltas::Reader::new(&session_reader);
let deltas_by_filepath = deltas_reader.read(None).unwrap();
for deltas in deltas_by_filepath.values() { for deltas in deltas_by_filepath.values() {
deltas.iter().for_each(|delta| { deltas.iter().for_each(|delta| {
delta.operations.iter().for_each(|operation| { delta.operations.iter().for_each(|operation| {
@ -528,8 +534,9 @@ fn test_flow_signle_session() -> Result<()> {
// collect all operations from sessions in the reverse order // collect all operations from sessions in the reverse order
let mut operations: Vec<deltas::Operation> = vec![]; let mut operations: Vec<deltas::Operation> = vec![];
let session = gb_repo.get_current_session()?.unwrap(); let session = gb_repo.get_current_session()?.unwrap();
let reader = gb_repo.get_session_reader(&session).unwrap(); let session_reader = gb_repo.get_session_reader(&session).unwrap();
let deltas_by_filepath = reader.deltas(None).unwrap(); let deltas_reader = deltas::Reader::new(&session_reader);
let deltas_by_filepath = deltas_reader.read(None).unwrap();
for deltas in deltas_by_filepath.values() { for deltas in deltas_by_filepath.values() {
deltas.iter().for_each(|delta| { deltas.iter().for_each(|delta| {
delta.operations.iter().for_each(|operation| { delta.operations.iter().for_each(|operation| {