Skip to content

Commit

Permalink
Merge pull request #8 from krshrimali/kush/pr/collisions
Browse files Browse the repository at this point in the history
Update DB schema and add support for overlapping
  • Loading branch information
krshrimali committed Jun 27, 2023
2 parents 519d42e + 649074b commit 1a184e7
Show file tree
Hide file tree
Showing 2 changed files with 205 additions and 39 deletions.
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())
}
}
}

0 comments on commit 1a184e7

Please sign in to comment.