static void rm_tm_cluster_up(RmTreeMerger *self, RmDirectory *directory) { char *parent_dir = g_path_get_dirname(directory->dirname); bool is_root = strcmp(parent_dir, "/") == 0; /* Lookup if we already found this parent before (if yes, merge with it) */ RmDirectory *parent = rm_trie_search(&self->dir_tree, parent_dir); if(parent == NULL) { /* none yet, basically copy child */ parent = rm_directory_new(parent_dir); rm_trie_insert(&self->dir_tree, parent_dir, parent); /* Get the actual file count */ parent->file_count = GPOINTER_TO_UINT(rm_trie_search(&self->count_tree, parent_dir)); } else { g_free(parent_dir); } rm_directory_add_subdir(parent, directory); if(parent->dupe_count == parent->file_count && parent->file_count > 0) { rm_tm_insert_dir(self, parent); if(!is_root) { rm_tm_cluster_up(self, parent); } } }
void rm_tm_feed(RmTreeMerger *self, RmFile *file) { RM_DEFINE_PATH(file); char *dirname = g_path_get_dirname(file_path); /* See if we know that directory already */ RmDirectory *directory = rm_trie_search(&self->dir_tree, dirname); if(directory == NULL) { /* Get the actual file count */ int file_count = GPOINTER_TO_INT(rm_trie_search(&self->count_tree, dirname)); if(file_count == 0) { rm_log_error( RED "Empty directory or weird RmFile encountered; rejecting.\n" RESET); file_count = -1; } directory = rm_directory_new(dirname); directory->file_count = file_count; /* Make the new directory known */ rm_trie_insert(&self->dir_tree, dirname, directory); g_queue_push_head(&self->valid_dirs, directory); } else { g_free(dirname); } g_queue_push_tail(self->free_list, file); rm_directory_add(directory, file); /* Add the file to this directory */ g_queue_push_head(&directory->known_files, file); /* Remember the digest (if only to free it later...) */ g_hash_table_replace(self->known_hashs, file->digest, NULL); /* Check if the directory reached the number of actual files in it */ if(directory->dupe_count == directory->file_count && directory->file_count > 0) { rm_tm_insert_dir(self, directory); } }