X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=nucleus%2Flibrary%2Ffilesystem%2Fheavy_file_ops.cpp;h=b9de0f9ab6c166d4628db7165ebe27e9857dd258;hb=ef338226ccf699c8d8a149d9b74e9888175c7099;hp=0d2f91bc3463383ffcc1d0285597886af0abac03;hpb=8d5adf2438ee63c6ee88ca9a42aea2d763f0b03d;p=feisty_meow.git diff --git a/nucleus/library/filesystem/heavy_file_ops.cpp b/nucleus/library/filesystem/heavy_file_ops.cpp index 0d2f91bc..b9de0f9a 100644 --- a/nucleus/library/filesystem/heavy_file_ops.cpp +++ b/nucleus/library/filesystem/heavy_file_ops.cpp @@ -27,16 +27,17 @@ using namespace structures; namespace filesystem { -#define DEBUG_HEAVY_FILE_OPS +//#define DEBUG_HEAVY_FILE_OPS // uncomment for noisier debugging. #undef LOG -#ifdef DEBUG_HEAVY_FILE_OPS - #include - #define LOG(to_print) printf("%s::%s: %s\n", static_class_name(), func, astring(to_print).s()) -#else - #define LOG(s) {if(!!s){}} -#endif +#include +#define LOG(to_print) printf("%s::%s: %s\n", static_class_name(), func, astring(to_print).s()) + +////////////// + +// the smallest we let the packing area's available space get before we stop filling it. +const int MINIMUM_ARRAY_SIZE = 1024; ////////////// @@ -167,14 +168,18 @@ outcome heavy_file_operations::write_file_chunk(const astring &target, double byte_start, const byte_array &chunk, bool truncate, int copy_chunk_factor) { -#ifdef DEBUG_HEAVY_FILE_OPS -// FUNCDEF("write_file_chunk"); -#endif + FUNCDEF("write_file_chunk"); if (byte_start < 0) return BAD_INPUT; filename targ_name(target); - if (!directory::recursive_create(targ_name.dirname().raw())) + astring targ_dir = targ_name.dirname().raw(); +#ifdef DEBUG_HEAVY_FILE_OPS + LOG(astring("creating target's directory: ") + targ_name.dirname().raw()); +#endif + if (!directory::recursive_create(targ_dir)) { + LOG(astring("failed to create directory: ") + targ_name.dirname().raw()); return TARGET_DIR_ERROR; + } if (!targ_name.exists()) { huge_file target_file(target, "w"); @@ -184,6 +189,7 @@ outcome heavy_file_operations::write_file_chunk(const astring &target, // open the file for updating (either read or write). if (!target_file.good()) return TARGET_ACCESS_ERROR; double curr_len = target_file.length(); + target_file.touch(); if (curr_len < byte_start) { byte_array new_chunk; @@ -208,15 +214,13 @@ outcome heavy_file_operations::write_file_chunk(const astring &target, return OKAY; } -bool heavy_file_operations::advance(const filename_list &to_transfer, +basis::outcome heavy_file_operations::advance(const filename_list &to_transfer, file_transfer_header &last_action) { -#ifdef DEBUG_HEAVY_FILE_OPS FUNCDEF("advance"); -#endif int indy = to_transfer.locate(last_action._filename); - if (negative(indy)) return false; // error. - if (indy == to_transfer.elements() - 1) return false; // done. + if (negative(indy)) return BAD_INPUT; // error, file not found in list. + if (indy >= to_transfer.elements() - 1) return FINISHED; // done. const file_info *currfile = to_transfer.get(indy + 1); last_action._filename = currfile->raw(); last_action._time = currfile->_time; @@ -228,7 +232,7 @@ bool heavy_file_operations::advance(const filename_list &to_transfer, last_action._byte_start = 0; last_action._length = 0; - return true; + return OKAY; } outcome heavy_file_operations::buffer_files(const astring &source_root, @@ -245,11 +249,14 @@ outcome heavy_file_operations::buffer_files(const astring &source_root, outcome to_return = OKAY; + // this records if we're working on a new file. + bool fresh_file = false; + // start filling the array with bytes from the files. while (storage.length() < maximum_bytes) { double remaining_in_array = maximum_bytes - storage.length() - last_action.packed_size(); - if (remaining_in_array < 128) { + if (remaining_in_array < MINIMUM_ARRAY_SIZE) { // ensure that we at least have a reasonable amount of space left // for storing into the array. break; @@ -263,11 +270,13 @@ outcome heavy_file_operations::buffer_files(const astring &source_root, last_action._time = currfile->_time; last_action._byte_start = 0; last_action._length = 0; + fresh_file = true; } const file_info *found = to_transfer.find(last_action._filename); if (!found) { // they have referenced a file that we don't have. that's bad news. + LOG(astring("unknown last file requested in transfer: ") + last_action._filename); return BAD_INPUT; } @@ -275,16 +284,28 @@ outcome heavy_file_operations::buffer_files(const astring &source_root, huge_file current(full_file, "rb"); if (!current.good()) { // we need to skip this file. - if (!advance(to_transfer, last_action)) break; + LOG(astring("skipping bad file: ") + full_file); + fresh_file = true; + to_return = advance(to_transfer, last_action); + if (to_return != OKAY) break; continue; } +//LOG(astring("working on file: ") + current.name()); - if (last_action._byte_start + last_action._length >= current.length()) { -// && current.length()) { + // we don't try to check done if we just started this file. + if (!fresh_file && (last_action._byte_start + last_action._length >= current.length())) { // this file is done now. go to the next one. - if (!advance(to_transfer, last_action)) break; +#ifdef DEBUG_HEAVY_FILE_OPS + LOG(astring("finished stuffing file: ") + full_file); +#endif + fresh_file = true; + to_return = advance(to_transfer, last_action); + if (to_return != OKAY) break; continue; } + // now that we tested if the file was fresh in our 'finished' check above, we + // consider the file not to be fresh until told otherwise. + fresh_file = false; // calculate the largest piece remaining of that file that will fit in the // allotted space. @@ -301,7 +322,9 @@ outcome heavy_file_operations::buffer_files(const astring &source_root, if (bytes_read != new_len) { if (!bytes_read) { // some kind of problem reading the file. - if (!advance(to_transfer, last_action)) break; + fresh_file = true; + to_return = advance(to_transfer, last_action); + if (to_return != OKAY) break; continue; } //why would this happen? just complain, i guess. @@ -318,7 +341,9 @@ outcome heavy_file_operations::buffer_files(const astring &source_root, if (!current.length()) { // ensure we don't get stuck redoing zero length files, which we allowed // to go past their end above (since otherwise we'd never see them). - if (!advance(to_transfer, last_action)) break; + fresh_file = true; + to_return = advance(to_transfer, last_action); + if (to_return != OKAY) break; continue; }