Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update DB schema and add support for overlapping #8

Merged
merged 5 commits into from Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
99 changes: 86 additions & 13 deletions src/algo_loc.rs
@@ -1,19 +1,20 @@
use std::collections::HashMap;
use crate::git_command_algo::extract_details;
use crate::db::DB;
use crate::git_command_algo::extract_details;
use std::collections::HashMap;

pub fn get_unique_files_changed(
origin_file_path: String,
start_line_number: usize,
end_line_number: usize,
db_obj: &mut DB,
) -> String {
let configured_file_path: String =
format!("{origin_file_path}**{start_line_number}**{end_line_number}");
let configured_file_path: String = origin_file_path.clone();
let line_str: String = format!("{start_line_number}_{end_line_number}");
// Check in the DB first
let mut res = String::new();
let mut visited: HashMap<String, usize> = HashMap::new();
if let Some(obj) = db_obj.exists(&configured_file_path) {
if let (Some(obj), search_field_second) = db_obj.exists(&configured_file_path, &line_str) {
// means nothing to do...
for author_detail in obj {
for each_file in author_detail.contextual_file_paths.clone() {
if visited.contains_key(&each_file) {
Expand All @@ -27,13 +28,50 @@ pub fn get_unique_files_changed(
if res.ends_with(',') {
res.pop();
}
return res;
if !search_field_second.is_empty() {
// find if multiple splits are there
let split_search_field: Vec<&str> = search_field_second.split('_').collect();
if split_search_field.len() == 4 {
let start_line_number: usize = split_search_field.first().unwrap().parse().unwrap();
let end_line_number: usize = split_search_field.get(1).unwrap().parse().unwrap();
let output = get_unique_files_changed(
origin_file_path.clone(),
start_line_number,
end_line_number,
db_obj,
);
let start_line_number: usize = split_search_field.get(2).unwrap().parse().unwrap();
let end_line_number: usize = split_search_field.get(3).unwrap().parse().unwrap();
let output_second = get_unique_files_changed(
origin_file_path,
start_line_number,
end_line_number,
db_obj,
);
return output + &output_second;
} else {
let start_line_number: usize = split_search_field.first().unwrap().parse().unwrap();
let end_line_number: usize = split_search_field.get(1).unwrap().parse().unwrap();
return get_unique_files_changed(
origin_file_path,
start_line_number,
end_line_number,
db_obj,
);
}
} else {
return res;
}
}
// INSERT HERE
let output = extract_details(start_line_number, end_line_number, origin_file_path);
let mut res: HashMap<String, usize> = HashMap::new();
for single_struct in output {
db_obj.append(&configured_file_path, single_struct.clone());
db_obj.append(
&configured_file_path,
start_line_number,
end_line_number,
single_struct.clone(),
);
for each_file in single_struct.contextual_file_paths {
if res.contains_key(&each_file) {
let count = res.get(&each_file).unwrap() + 1;
Expand Down Expand Up @@ -61,12 +99,13 @@ pub fn get_contextual_authors(
end_line_number: usize,
db_obj: &mut DB,
) -> String {
let configured_file_path: String =
format!("{file_path}**{start_line_number}**{end_line_number}");
let configured_file_path: String = file_path.clone();
let line_str: String = format!("{start_line_number}_{end_line_number}");
// Check in the DB first
let mut res = String::new();
let mut visited: HashMap<String, usize> = HashMap::new();
if let Some(obj) = db_obj.exists(&configured_file_path) {
if let (Some(obj), search_field_second) = db_obj.exists(&configured_file_path, &line_str) {
// means nothing to do...
for author_detail in obj {
if visited.contains_key(&author_detail.author_full_name) {
continue;
Expand All @@ -81,12 +120,46 @@ pub fn get_contextual_authors(
if res.ends_with(',') {
res.pop();
}
return res;
if !search_field_second.is_empty() {
// find if multiple splits are there
let split_search_field: Vec<&str> = search_field_second.split('_').collect();
if split_search_field.len() == 4 {
let start_line_number: usize = split_search_field.first().unwrap().parse().unwrap();
let end_line_number: usize = split_search_field.get(1).unwrap().parse().unwrap();
let output = get_contextual_authors(
file_path.clone(),
start_line_number,
end_line_number,
db_obj,
);
let start_line_number: usize = split_search_field.get(2).unwrap().parse().unwrap();
let end_line_number: usize = split_search_field.get(3).unwrap().parse().unwrap();
let output_second =
get_contextual_authors(file_path, start_line_number, end_line_number, db_obj);
return output + &output_second;
} else {
let start_line_number: usize = split_search_field.first().unwrap().parse().unwrap();
let end_line_number: usize = split_search_field.get(1).unwrap().parse().unwrap();
return get_contextual_authors(
file_path,
start_line_number,
end_line_number,
db_obj,
);
}
} else {
return res;
}
}
let output = extract_details(start_line_number, end_line_number, file_path);
let mut res: HashMap<String, usize> = HashMap::new();
for single_struct in output {
db_obj.append(&configured_file_path, single_struct.clone());
db_obj.append(
&configured_file_path,
start_line_number,
end_line_number,
single_struct.clone(),
);
let author_full_name = single_struct.author_full_name;
if res.contains_key(&author_full_name) {
let count = res.get(&author_full_name).unwrap() + 1;
Expand Down
145 changes: 119 additions & 26 deletions src/db.rs
@@ -1,24 +1,20 @@
use std::{
collections::HashMap,
fs::File,
io::Write,
path::Path,
};
use std::{collections::HashMap, fs::File, io::Write, path::Path};

use crate::{config, contextgpt_structs::AuthorDetails};

#[derive(Default)]
pub struct DB {
pub db_file_name: String,
pub current_data: HashMap<String, Vec<AuthorDetails>>,
pub current_data: HashMap<String, HashMap<String, Vec<AuthorDetails>>>,
pub db_file_path: String,
}

impl DB {
pub fn read(&mut self) -> HashMap<String, Vec<AuthorDetails>> {
pub fn read(&mut self) -> HashMap<String, HashMap<String, Vec<AuthorDetails>>> {
let data_buffer = std::fs::read_to_string(self.db_file_path.clone()).unwrap();
let v: HashMap<String, Vec<AuthorDetails>> = serde_json::from_str(data_buffer.as_str())
.expect("Unable to deserialize the file, something went wrong");
let v: HashMap<String, HashMap<String, Vec<AuthorDetails>>> =
serde_json::from_str(data_buffer.as_str())
.expect("Unable to deserialize the file, something went wrong");
v
}

Expand All @@ -42,38 +38,135 @@ impl DB {
self.current_data = self.read();
}

pub fn append(&mut self, configured_file_path: &String, data: AuthorDetails) {
pub fn append(
&mut self,
configured_file_path: &String,
start_line_number: usize,
end_line_number: usize,
data: AuthorDetails,
) {
let mut existing_data = vec![];
let line_str: String = format!("{start_line_number}_{end_line_number}");
if self.current_data.contains_key(configured_file_path) {
existing_data = self
.current_data
.get_mut(configured_file_path)
.unwrap()
.to_vec();
existing_data.append(&mut vec![data]);
let file_data = self.current_data.get_mut(configured_file_path).unwrap();
if !file_data.contains_key(&line_str) {
file_data.insert(line_str.clone(), vec![data]);
} else {
file_data
.get_mut(&line_str)
.unwrap()
.append(&mut vec![data]);
}
} else {
existing_data.append(&mut vec![data]);
let mut map = HashMap::new();
map.insert(line_str, existing_data);
self.current_data
.insert(configured_file_path.to_string(), map);
}
self.current_data
.insert(configured_file_path.to_string(), existing_data);
}

pub fn store(&mut self) {
let mut file_obj =
File::create(self.db_file_path.as_str()).expect("Couldn't open the given file");
let output_string =
serde_json::to_string_pretty(&self.current_data).expect("Unable to write data");
// file_obj
// .write_all(output_string.as_bytes())
// .expect("Unable to write bytes to the file");
write!(file_obj, "{}", output_string).expect("Couldn't write, uhmmm");
}

pub fn exists(&self, search_field: &String) -> Option<&Vec<AuthorDetails>> {
if self.current_data.contains_key(search_field) {
self.current_data.get(search_field)
pub fn exists(
&self,
search_field_first: &String,
search_field_second: &String,
) -> (Option<Vec<AuthorDetails>>, String) {
if self.current_data.contains_key(search_field_first) {
let line_numbers: Vec<&str> = search_field_second.split('_').collect();
let start_line_number: usize = line_numbers.first().unwrap().parse().unwrap();
let end_line_number: usize = line_numbers.last().unwrap().parse().unwrap();
let file_searched = self.current_data.get(search_field_first);
match file_searched {
Some(existing_lines) => {
let keys = existing_lines.keys();
if keys.len() == 0 {
return (None, search_field_second.to_string());
}
let mut output_vec = None;
let mut output_string = "".to_string();
for each_key_combination in keys {
let line_numbers: Vec<&str> = each_key_combination.split('_').collect();
let received_start_line_number: usize =
line_numbers.first().unwrap().parse().unwrap();
let received_end_line_number: usize =
line_numbers.last().unwrap().parse().unwrap();
if start_line_number == received_start_line_number
&& end_line_number == received_end_line_number
{
output_vec = existing_lines.get(each_key_combination).cloned();
output_string = "".to_string();
} else if start_line_number >= received_start_line_number
&& end_line_number <= received_end_line_number
{
// in between
let full_data = existing_lines.get(each_key_combination).unwrap();
let mut final_data: Vec<AuthorDetails> = Vec::new();
for line_data in full_data {
if line_data.line_number >= start_line_number
&& line_data.line_number <= end_line_number
{
final_data.push(line_data.clone());
}
}
output_vec = Some(final_data);
output_string = "".to_string();
} else if start_line_number > received_end_line_number {
output_vec = None;
output_string = search_field_second.to_string();
} else if start_line_number >= received_start_line_number
// && end_line_number > received_start_line_number
{
let full_data = existing_lines.get(each_key_combination).unwrap();
let mut final_data: Vec<AuthorDetails> = Vec::new();
for line_data in full_data {
if line_data.line_number >= start_line_number
&& line_data.line_number <= received_end_line_number
{
final_data.push(line_data.clone());
}
}
output_vec = Some(final_data);
let final_start_line_number = received_end_line_number + 1;
output_string = format!("{final_start_line_number}_{end_line_number}");
} else if start_line_number <= received_start_line_number
&& end_line_number >= received_start_line_number
{
let full_data = existing_lines.get(each_key_combination).unwrap();
let mut final_data: Vec<AuthorDetails> = Vec::new();
for line_data in full_data {
if line_data.line_number >= received_start_line_number
&& line_data.line_number <= end_line_number
{
final_data.push(line_data.clone());
}
}
output_vec = Some(final_data);
if end_line_number > received_end_line_number {
let final_received_end_line_number = received_end_line_number + 1;
output_string = format!("{start_line_number}_{received_start_line_number}_{final_received_end_line_number}_{end_line_number}");
} else {
output_string =
format!("{start_line_number}_{received_start_line_number}");
}
} else {
output_vec = None;
output_string = search_field_second.to_string();
}
}
(output_vec, output_string)
}
_ => (None, search_field_second.to_string()),
}
} else {
None
(None, search_field_second.to_string())
}
}
}