Solve task 1 & 2
This commit is contained in:
parent
705fbc4ef5
commit
441e0f327b
1 changed files with 77 additions and 14 deletions
|
@ -35,6 +35,10 @@
|
|||
#include "parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
const unsigned long upper_bound = 100000;
|
||||
const unsigned long fs_size = 70000000;
|
||||
const unsigned long needed_space = 30000000;
|
||||
|
||||
struct dirstack* dirstack_push(struct dirstack *stack, struct dirnode *item) {
|
||||
struct dirstack *head = calloc(1, sizeof(struct dirstack));
|
||||
if (!head) {
|
||||
|
@ -111,12 +115,7 @@ command
|
|||
state->cur = state->stackptr->item;
|
||||
}
|
||||
| PROMPT CHDIR SPACE PATHSPEC NEWLINE {
|
||||
// TODO: CLEANUP
|
||||
if (!state) {
|
||||
fprintf(stderr, "\033[91m[error] the fuck\033[0m\n");
|
||||
} else {
|
||||
printf("searching in %s now for path %s\n", state->cur->name, $4);
|
||||
}
|
||||
// printf("searching in %s now for path %s\n", state->cur->name, $4);
|
||||
|
||||
// move into the new directory (creating it if it doesn't exist is not necessary, LIST does that)
|
||||
struct dirnode *cur_node = state->cur;
|
||||
|
@ -128,17 +127,18 @@ command
|
|||
if (strcmp($4, cur_node->directories[i]->name) == 0) {
|
||||
found = i;
|
||||
c = 0;
|
||||
printf("equal: [%s] and [%s]\n", $4, cur_node->directories[i]->name);
|
||||
// printf("equal: [%s] and [%s]\n", $4, cur_node->directories[i]->name);
|
||||
} else {
|
||||
printf("not equal: [%s] and [%s]\n", $4, cur_node->directories[i]->name);
|
||||
// printf("not equal: [%s] and [%s]\n", $4, cur_node->directories[i]->name);
|
||||
}
|
||||
}
|
||||
|
||||
if (c == -1) {
|
||||
fprintf(stderr, "\033[91m[error] got no such directory lol\033[0m\n");
|
||||
// TODO: error, directory not found
|
||||
} else {
|
||||
printf("found it\n");
|
||||
}
|
||||
} // else {
|
||||
// printf("found it\n");
|
||||
// }
|
||||
|
||||
struct dirnode *next = cur_node->directories[found];
|
||||
|
||||
|
@ -165,7 +165,6 @@ listing
|
|||
item->name = $3;
|
||||
|
||||
add_directory(state->cur, item);
|
||||
printf("know about %zu dirs now!\n", state->cur->num_dirs);
|
||||
}
|
||||
| SIZE SPACE PATHSPEC {
|
||||
struct filenode *item = calloc(1, sizeof(struct filenode));
|
||||
|
@ -183,13 +182,59 @@ listing
|
|||
%%
|
||||
|
||||
|
||||
unsigned long sum_and_count(struct dirnode *node) {
|
||||
unsigned long total_sum = 0;
|
||||
|
||||
for (size_t i = 0; i < node->num_files; i++) {
|
||||
node->size += node->files[i]->size;
|
||||
}
|
||||
|
||||
for (size_t j = 0; j < node->num_dirs; j++) {
|
||||
// recursively call function on subdirectory to compute its size
|
||||
total_sum += sum_and_count(node->directories[j]);
|
||||
node->size += node->directories[j]->size;
|
||||
}
|
||||
|
||||
if (node->size <= upper_bound) {
|
||||
total_sum += node->size;
|
||||
}
|
||||
|
||||
return total_sum;
|
||||
}
|
||||
|
||||
|
||||
struct dirnode* find_deletion_candidate(struct dirnode *cur, unsigned long needed_space) {
|
||||
if (cur->size < needed_space) {
|
||||
// abort recursion if directory sizes get too small
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct dirnode *best_candidate = cur;
|
||||
unsigned long best_diff = best_candidate->size - needed_space;
|
||||
|
||||
for (size_t i = 0; i < cur->num_dirs; i++) {
|
||||
struct dirnode *candidate = find_deletion_candidate(cur->directories[i], needed_space);
|
||||
// only proceed if there's an actual candidate
|
||||
if (candidate) {
|
||||
unsigned long delta = candidate->size - needed_space;
|
||||
if (delta < best_diff) {
|
||||
best_candidate = candidate;
|
||||
best_diff = delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return best_candidate;
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
struct dirnode *root = calloc(1, sizeof(struct dirnode));
|
||||
if (!root) {
|
||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
root->name = "\0";
|
||||
root->name = "/\0";
|
||||
|
||||
struct dirstack *stack_ptr = dirstack_push(NULL, root);
|
||||
|
||||
|
@ -217,7 +262,25 @@ int main(void) {
|
|||
|
||||
yylex_destroy(scanner);
|
||||
|
||||
// TODO: evaluation (bottom-up computation of sizes using a dirstack)
|
||||
// task 1
|
||||
unsigned long sum_of_sizes = sum_and_count(root);
|
||||
printf("The sum of all directory sizes < %zu is: %zu\n", upper_bound, sum_of_sizes);
|
||||
|
||||
// task 2
|
||||
unsigned long free_space = fs_size - root->size;
|
||||
unsigned long to_clear = needed_space - free_space;
|
||||
|
||||
printf("------------------------------------------------\n");
|
||||
printf("Total Disk Space Available: %zu\n", fs_size);
|
||||
printf("Total Disk Space Used: %zu\n", root->size);
|
||||
printf("Free Disk Space: %zu\n", free_space);
|
||||
printf("Required Disk Space: %zu\n", needed_space);
|
||||
printf("------------------------------------------------\n\n");
|
||||
printf("Looking to free %zu units\n", to_clear);
|
||||
|
||||
struct dirnode *closest_match = find_deletion_candidate(root, to_clear);
|
||||
|
||||
printf("Recommended deletion candidate: `%s` (size %zu)\n", closest_match->name, closest_match->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue