9 if (paths[id2] < paths[id1])
13PathId Similarity_Table::find_id_path(
const Path& path) {
14 auto [it, inserted] = path_id.try_emplace(path, paths.size());
17 paths.push_back(path);
18 similarity_graph.emplace_back();
24void Similarity_Table::read_comparation(std::ifstream& table_file) {
25 std::string string_path1, string_path2;
27 table_file >> string_path1 >> string_path2 >> similarity;
34 similarity_graph[id1].push_back(std::make_pair(id2, similarity));
35 similarity_graph[id2].push_back(std::make_pair(id1, similarity));
36 similarity_table[std::make_pair(id1, id2)] = similarity;
39void Similarity_Table::read_file_table(std::ifstream& table_file) {
40 int number_comparations;
41 table_file >> number_comparations;
42 for (
int i = 0; i < number_comparations; i++) {
43 read_comparation(table_file);
56 std::ifstream table_file;
58 table_file.open(similarity_table_file_name);
61 read_file_table(table_file);
68 : similarity_threshold{_similarity_threshold} { }
71 : similarity_threshold{DEFAULT_SIMILARITY} { }
74 return init_similarity_table();
78 similarity_threshold = new_similarity_threshold;
82 PathId id1 = find_id_path(path1);
83 PathId id2 = find_id_path(path2);
86 return MAXIMUM_SIMILARITY;
89 std::pair<PathId, PathId> aux = std::make_pair(id1, id2);
90 auto it = similarity_table.find(aux);
91 if (it != similarity_table.end())
93 return MINIMUM_SIMILARITY;
100bool Similarity_Table::is_above_threshold(
double similarity)
const {
101 return similarity_threshold <= similarity + EPS_ERROR_MARGIN;
105 return similarity_threshold;
110 return is_above_threshold(similarity);
118 int reference_id = find_id_path(reference);
119 std::vector<Path> ret;
120 for (
auto [neighbor_id, similarity] : similarity_graph[reference_id]) {
121 if (is_above_threshold(similarity)) {
122 ret.push_back(paths[neighbor_id]);
129 std::vector<SimilarPair> similar_pairs;
131 for (
const auto& [ids, similarity] : similarity_table) {
132 const Path& path1 = paths[ids.first];
133 const Path& path2 = paths[ids.second];
138 auto function = loader.
load(path1);
140 similar_pairs.push_back({
142 function.scope_location().size(),
147 return similar_pairs;
151 if (paths[a.
id1] != paths[b.
id1])
152 return paths[a.
id1] < paths[b.
id1];
154 if (paths[a.
id2] != paths[b.
id2])
155 return paths[a.
id2] < paths[b.
id2];
162 similar_pairs.begin(),
165 if (a.similarity != b.similarity)
166 return a.similarity > b.similarity;
168 return compare_paths(a, b);
174 similar_pairs.begin(),
177 if (a.number_lines != b.number_lines)
178 return a.number_lines > b.number_lines;
180 return compare_paths(a, b);
186 auto f1 = loader.
load(path1);
187 auto f2 = loader.
load(path2);
192 int n = paths.size();
194 std::vector<bool> visited(n,
false);
195 std::vector<Cluster> clusters;
197 for (
int i = 0; i < n; i++) {
198 if (visited[i])
continue;
200 std::vector<int> stack;
201 std::vector<int> component;
206 while (!stack.empty()) {
207 int current = stack.back();
210 component.push_back(current);
212 for (
auto [neighbor, similarity] : similarity_graph[current]) {
213 if (!visited[neighbor] && is_above_threshold(similarity)) {
214 visited[neighbor] =
true;
215 stack.push_back(neighbor);
220 if (component.size() > 1) {
221 clusters.push_back({component});
230 std::vector<ClusterInfo> clusters_info;
232 for (
const auto& cluster : raw_clusters) {
235 for (
int id : cluster.members) {
236 info.
paths.push_back(paths[
id]);
239 for (
size_t i = 0; i < info.
paths.size(); i++) {
240 for (
size_t j = i + 1; j < info.
paths.size(); j++) {
250 clusters_info.push_back(info);
255 std::sort(clusters_info.begin(), clusters_info.end(),
257 return a.score() > b.score();
261 return clusters_info;
Function load(const Path &path)
Loads a function from a path.
fs::path build_similarity_path() const
Builds similarity file path.
const FunctionLocation & scope_location() const
Gets the function location inside the source file.
Represents a logical path to a function in the codebase.
static PreprocessRunParams read_current_run_params()
read preprocessing parameters runs
static bool is_cache_compatible(const std::string &cache_version)
void update_similarity(double new_similarity_threshold)
Updates similarity threshold.
std::vector< SimilarPair > get_all_similar_pairs()
Gets all similar path pairs with scores, sorted.
bool compare_paths(const SimilarPair &a, const SimilarPair &b) const
std::vector< ClusterInfo > get_clusters_info(bool sorted)
Returns detailed information about all clusters found in the similarity table.
int get_number_lines_in_pair(const Path &path1, const Path &path2)
const Path & get_path(PathId id) const
void sort_pairs_by_line_number(std::vector< SimilarPair > &similar_pairs) const
Sorts path pairs by line count.
Similarity_Table()
Constructs with default similarity threshold.
void sort_pairs_by_similarity(std::vector< SimilarPair > &similar_pairs) const
Sorts path pairs by similarity.
double get_similarity(const Path &path1, const Path &path2)
Gets similarity between two paths.
std::vector< Cluster > get_clusters()
Generate clusters of similar functions using DFS on the similarity graph.
void normalize_pair(PathId &id1, PathId &id2) const
const std::vector< Path > & get_path_list() const
Gets list of all known paths.
Cache_Compatibility load()
bool is_similar(const Path &path1, const Path &path2)
Checks if two paths are similar.
std::vector< Path > get_similar_path_to_the_reference(const Path &reference)
Gets paths similar to reference path.
double get_threshold_similarity() const
Gets the similarity threshold.
Provides functionality to load Function objects from external sources.
Provides access to function storage locations.
void ensure_file_is_open(const Stream &file, const fs::path &file_name)
Ensures that a file stream is successfully opened.
Similarity relationships storage and analysis.
std::vector< Path > paths
constexpr uint32_t size() const noexcept
Defines utility functions used across all files.