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 "parser.h"
|
||||||
#include "lexer.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* dirstack_push(struct dirstack *stack, struct dirnode *item) {
|
||||||
struct dirstack *head = calloc(1, sizeof(struct dirstack));
|
struct dirstack *head = calloc(1, sizeof(struct dirstack));
|
||||||
if (!head) {
|
if (!head) {
|
||||||
|
@ -111,12 +115,7 @@ command
|
||||||
state->cur = state->stackptr->item;
|
state->cur = state->stackptr->item;
|
||||||
}
|
}
|
||||||
| PROMPT CHDIR SPACE PATHSPEC NEWLINE {
|
| PROMPT CHDIR SPACE PATHSPEC NEWLINE {
|
||||||
// TODO: CLEANUP
|
// printf("searching in %s now for path %s\n", state->cur->name, $4);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// move into the new directory (creating it if it doesn't exist is not necessary, LIST does that)
|
// move into the new directory (creating it if it doesn't exist is not necessary, LIST does that)
|
||||||
struct dirnode *cur_node = state->cur;
|
struct dirnode *cur_node = state->cur;
|
||||||
|
@ -128,17 +127,18 @@ command
|
||||||
if (strcmp($4, cur_node->directories[i]->name) == 0) {
|
if (strcmp($4, cur_node->directories[i]->name) == 0) {
|
||||||
found = i;
|
found = i;
|
||||||
c = 0;
|
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 {
|
} 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) {
|
if (c == -1) {
|
||||||
fprintf(stderr, "\033[91m[error] got no such directory lol\033[0m\n");
|
fprintf(stderr, "\033[91m[error] got no such directory lol\033[0m\n");
|
||||||
// TODO: error, directory not found
|
// TODO: error, directory not found
|
||||||
} else {
|
} // else {
|
||||||
printf("found it\n");
|
// printf("found it\n");
|
||||||
}
|
// }
|
||||||
|
|
||||||
struct dirnode *next = cur_node->directories[found];
|
struct dirnode *next = cur_node->directories[found];
|
||||||
|
|
||||||
|
@ -165,7 +165,6 @@ listing
|
||||||
item->name = $3;
|
item->name = $3;
|
||||||
|
|
||||||
add_directory(state->cur, item);
|
add_directory(state->cur, item);
|
||||||
printf("know about %zu dirs now!\n", state->cur->num_dirs);
|
|
||||||
}
|
}
|
||||||
| SIZE SPACE PATHSPEC {
|
| SIZE SPACE PATHSPEC {
|
||||||
struct filenode *item = calloc(1, sizeof(struct filenode));
|
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) {
|
int main(void) {
|
||||||
struct dirnode *root = calloc(1, sizeof(struct dirnode));
|
struct dirnode *root = calloc(1, sizeof(struct dirnode));
|
||||||
if (!root) {
|
if (!root) {
|
||||||
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
fprintf(stderr, "\033[91m[error] Ran out of memory\033[0m\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
root->name = "\0";
|
root->name = "/\0";
|
||||||
|
|
||||||
struct dirstack *stack_ptr = dirstack_push(NULL, root);
|
struct dirstack *stack_ptr = dirstack_push(NULL, root);
|
||||||
|
|
||||||
|
@ -217,7 +262,25 @@ int main(void) {
|
||||||
|
|
||||||
yylex_destroy(scanner);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue