13ZSNode ASTMethod::from_tsnode(TSNode node) {
15 out.
symbol = ts_node_symbol(node);
17 uint32_t count = ts_node_named_child_count(node);
19 for (uint32_t i = 0; i < count; i++) {
20 out.
children.push_back(from_tsnode(ts_node_named_child(node, i)));
29 for (
const auto& child : node.
children) {
38 int id = tree.
labels.size();
46 tree.
lmd.push_back(leftmost);
52 size_t n = a.
labels.size();
53 size_t m = b.
labels.size();
55 std::vector<std::vector<int>> dp(n + 1, std::vector<int>(m + 1));
57 for (
size_t i = 0; i <= n; i++) {
61 for (
size_t j = 0; j <= m; j++) {
65 for (
size_t i = 1; i <= n; i++) {
66 for (
size_t j = 1; j <= m; j++) {
68 int rename_cost = a.
labels[i - 1] == b.
labels[j - 1] ? 0 : 1;
73 dp[i - 1][j - 1] + rename_cost
82 int dist = tree_distance(a, b);
84 int max_size = std::max(a.
labels.size(), b.
labels.size());
86 return 1.0 - (
static_cast<double>(dist) / max_size);
90 base_path = base_path_;
91 similarity = similarity_;
94 std::cerr <<
"SIMILARITY SHOULD BE GREATER OR EQUAL 0 TO USE DUPLICATION FINDER BY AST COMMAND";
98void ASTMethod::save_duplications(std::vector<DuplicationEntry>& file_duplication_pairs) {
99 for (
const auto& [similarity, path1, path2] : file_duplication_pairs) {
100 output_file << path1 <<
' ' << path2 <<
' ';
101 output_file << std::fixed << std::setprecision(2) << similarity <<
'\n';
105void ASTMethod::header_duplications() {
106 fs::path output_file_path = base_path /
"output_parsed.tmp";
110 std::ios::out | std::ios::trunc
114void ASTMethod::flush_duplications(std::vector<DuplicationEntry>& local) {
118 std::lock_guard<std::mutex> lock(output_mutex);
120 save_duplications(local);
122 total_matches.fetch_add(local.size(), std::memory_order_relaxed);
127void ASTMethod::compare_range(
128 const std::vector<PostOrderTree>& processed,
129 size_t begin,
size_t end,
130 std::vector<DuplicationEntry>& local
132 for (
size_t i = begin; i < end; i++) {
133 for (
size_t j = i + 1; j < processed.size(); j++) {
134 double sim = similarity_score(processed[i], processed[j]) * 100.0;
136 if (sim >= similarity)
137 local.push_back({sim, processed[i].path.string(), processed[j].path.string()});
147 auto tree = from_tsnode(ast->root);
152 fs::path path{fd.
path};
153 std::string filename = fd.
function_name + path.extension().string();
155 p.
path = path / filename;
158 std::lock_guard<std::mutex> lock(processed_mutex);
159 processed.push_back(p);
164 unsigned int thread_count = std::thread::hardware_concurrency();
165 const size_t threads = std::max<size_t>(1, thread_count);
167 size_t n = processed.size();
168 size_t chunk = (n + threads - 1) / threads;
170 constexpr size_t block_size = 4;
171 constexpr size_t flush_size = 10000;
172 std::atomic<size_t> next{0};
173 std::vector<std::thread> workers;
175 header_duplications();
177 for (
size_t t = 0; t < threads; t++) {
178 workers.emplace_back([&]() {
179 std::vector<DuplicationEntry> local;
180 local.reserve(flush_size);
183 size_t begin = next.fetch_add(block_size);
184 if (begin >= processed.size())
break;
186 size_t end = std::min(begin + block_size, processed.size());
188 compare_range(processed, begin, end, local);
190 if (local.size() >= flush_size)
191 flush_duplications(local);
194 flush_duplications(local);
198 for (
auto& w : workers)
204 std::ifstream tmp(base_path /
"output_parsed.tmp");
207 final << total_matches.load() <<
'\n';
208 final << tmp.rdbuf();
213 fs::remove(base_path /
"output_parsed.tmp");
int build_postorder(const ZSNode &node, PostOrderTree &tree)
ASTMethod(const fs::path &base_path_, double similarity_)
Constructs preprocessor with configuration.
void on_function(const FunctionData &fd) override
void execute() override
Executes the preprocessing pipeline.
std::string function_name
Name of the function.
std::shared_ptr< T > get_feature() const
fs::path build_similarity_path() const
Builds similarity file path.
Configuration management interface.
Provides access to function storage locations.
std::vector< int > lmd
Left-most descendant index for each node.
std::vector< TSSymbol > labels
Tree-sitter grammar symbol for each node.
std::vector< ZSNode > children
Defines utility functions used across all files.