diff --git a/panda/src/downloadertools/apply_patch.cxx b/panda/src/downloadertools/apply_patch.cxx index b8703864f5..f81131b182 100644 --- a/panda/src/downloadertools/apply_patch.cxx +++ b/panda/src/downloadertools/apply_patch.cxx @@ -28,7 +28,8 @@ int main(int argc, char *argv[]) { if (argc < 3) { - cerr << "Usage: apply_patch " << endl; + cerr << "Usage: apply_patch " << endl; + cerr << "Will overwrite old_file" << endl; return 1; } diff --git a/panda/src/downloadertools/build_patch.cxx b/panda/src/downloadertools/build_patch.cxx index 103f6b2373..6fdd906f5b 100644 --- a/panda/src/downloadertools/build_patch.cxx +++ b/panda/src/downloadertools/build_patch.cxx @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { if (argc < 3) { - cerr << "Usage: build_patch " << endl; + cerr << "Usage: build_patch " << endl; return 1; } diff --git a/panda/src/express/patchfile.cxx b/panda/src/express/patchfile.cxx index 87dbcdeb14..f5d316a8ad 100644 --- a/panda/src/express/patchfile.cxx +++ b/panda/src/express/patchfile.cxx @@ -94,10 +94,11 @@ const PN_uint32 Patchfile::_magic_number = 0xfeebfaac; // To version 2 on 11/2/02 to store copy offsets as relative. const PN_uint16 Patchfile::_current_version = 2; -const PN_uint32 Patchfile::_HASHTABLESIZE = PN_uint32(1) << 16; +const PN_uint32 Patchfile::_HASHTABLESIZE = PN_uint32(1) << 24; const PN_uint32 Patchfile::_DEFAULT_FOOTPRINT_LENGTH = 9; // this produced the smallest patch file for libpanda.dll when tested, 12/20/2000 const PN_uint32 Patchfile::_NULL_VALUE = PN_uint32(0) - 1; const PN_uint32 Patchfile::_MAX_RUN_LENGTH = (PN_uint32(1) << 16) - 1; +const PN_uint32 Patchfile::_HASH_MASK = (PN_uint32(1) << 24) - 1; //////////////////////////////////////////////////////////////////// // Function: Patchfile::Constructor @@ -527,7 +528,7 @@ internal_read_header(const Filename &patch_file) { // Access: Private // Description: //////////////////////////////////////////////////////////////////// -PN_uint16 Patchfile:: +PN_uint32 Patchfile:: calc_hash(const char *buffer) { #ifdef USE_MD5_FOR_HASHTABLE_INDEX_VALUES HashVal hash; @@ -537,18 +538,18 @@ calc_hash(const char *buffer) { return PN_uint16(hash.get_value(0)); #else - PN_uint16 hash_value = 0; + PN_uint32 hash_value = 0; for(int i = 0; i < (int)_footprint_length; i++) { // this is probably not such a good hash. to be replaced /// --> TRIED MD5, was not worth it for the execution-time hit on 800Mhz PC - hash_value ^= (*buffer) << (i % 8); + hash_value ^= (*buffer) << ((i % _footprint_length) * 2); buffer++; } //cout << hash_value << " "; - return hash_value; + return hash_value & _HASH_MASK; #endif } @@ -609,7 +610,7 @@ build_hash_link_tables(const char *buffer_orig, PN_uint32 length_orig, double t = GET_PROFILE_TIME(); #endif - PN_uint16 hash_value = calc_hash(&buffer_orig[i]); + PN_uint32 hash_value = calc_hash(&buffer_orig[i]); #ifdef PROFILE_PATCH_BUILD hashCalc += GET_PROFILE_TIME() - t; @@ -673,7 +674,19 @@ build_hash_link_tables(const char *buffer_orig, PN_uint32 length_orig, // two strings of bytes //////////////////////////////////////////////////////////////////// PN_uint32 Patchfile:: -calc_match_length(const char* buf1, const char* buf2, PN_uint32 max_length) { +calc_match_length(const char* buf1, const char* buf2, PN_uint32 max_length, + PN_uint32 min_length) { + // early out: look ahead and sample the end of the minimum range + if (min_length > 2) { + if (min_length >= max_length) + return 0; + if (buf1[min_length] != buf2[min_length] || + buf1[min_length-1] != buf2[min_length-1] || + buf1[min_length-2] != buf2[min_length-2]) { + return 0; + } + } + PN_uint32 length = 0; while ((length < max_length) && (*buf1 == *buf2)) { buf1++, buf2++, length++; @@ -697,7 +710,7 @@ find_longest_match(PN_uint32 new_pos, PN_uint32 ©_pos, PN_uint16 ©_lengt copy_length = 0; // get offset of matching string (in orig file) from hash table - PN_uint16 hash_value = calc_hash(&buffer_new[new_pos]); + PN_uint32 hash_value = calc_hash(&buffer_new[new_pos]); // if no match, bail if (_NULL_VALUE == hash_table[hash_value]) @@ -706,8 +719,12 @@ find_longest_match(PN_uint32 new_pos, PN_uint32 ©_pos, PN_uint16 ©_lengt copy_pos = hash_table[hash_value]; // calc match length - copy_length = (PN_uint16)calc_match_length(&buffer_new[new_pos], &buffer_orig[copy_pos], - min(min((length_new - new_pos),(length_orig - copy_pos)), _MAX_RUN_LENGTH)); + copy_length = (PN_uint16)calc_match_length(&buffer_new[new_pos], + &buffer_orig[copy_pos], + min(min((length_new - new_pos), + (length_orig - copy_pos)), + _MAX_RUN_LENGTH), + 0); // run through link table, see if we find any longer matches PN_uint32 match_offset; @@ -715,8 +732,12 @@ find_longest_match(PN_uint32 new_pos, PN_uint32 ©_pos, PN_uint16 ©_lengt match_offset = link_table[copy_pos]; while (match_offset != _NULL_VALUE) { - match_length = (PN_uint16)calc_match_length(&buffer_new[new_pos], &buffer_orig[match_offset], - min(min((length_new - new_pos),(length_orig - match_offset)), _MAX_RUN_LENGTH)); + match_length = (PN_uint16)calc_match_length(&buffer_new[new_pos], + &buffer_orig[match_offset], + min(min((length_new - new_pos), + (length_orig - match_offset)), + _MAX_RUN_LENGTH), + copy_length); // have we found a longer match? if (match_length > copy_length) { diff --git a/panda/src/express/patchfile.h b/panda/src/express/patchfile.h index 4029174e72..b6a4a3324a 100644 --- a/panda/src/express/patchfile.h +++ b/panda/src/express/patchfile.h @@ -83,11 +83,12 @@ private: // stuff for the build operation void build_hash_link_tables(const char *buffer_orig, PN_uint32 length_orig, PN_uint32 *hash_table, PN_uint32 *link_table); - PN_uint16 calc_hash(const char *buffer); + PN_uint32 calc_hash(const char *buffer); void find_longest_match(PN_uint32 new_pos, PN_uint32 ©_pos, PN_uint16 ©_length, PN_uint32 *hash_table, PN_uint32 *link_table, const char* buffer_orig, PN_uint32 length_orig, const char* buffer_new, PN_uint32 length_new); - PN_uint32 calc_match_length(const char* buf1, const char* buf2, PN_uint32 max_length); + PN_uint32 calc_match_length(const char* buf1, const char* buf2, PN_uint32 max_length, + PN_uint32 min_length); void emit_ADD(ofstream &write_stream, PN_uint16 length, const char* buffer, PN_uint32 ADD_pos); @@ -99,6 +100,7 @@ private: static const PN_uint32 _DEFAULT_FOOTPRINT_LENGTH; static const PN_uint32 _NULL_VALUE; static const PN_uint32 _MAX_RUN_LENGTH; + static const PN_uint32 _HASH_MASK; PN_uint32 _footprint_length;