mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
Roger's patchfile generation speed optimizations
This commit is contained in:
parent
bbea3902db
commit
d0acfcc4ac
@ -28,7 +28,8 @@
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[]) {
|
main(int argc, char *argv[]) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
cerr << "Usage: apply_patch <patch> <file>" << endl;
|
cerr << "Usage: apply_patch <patch_file> <old_file>" << endl;
|
||||||
|
cerr << "Will overwrite old_file" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
int
|
int
|
||||||
main(int argc, char *argv[]) {
|
main(int argc, char *argv[]) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
cerr << "Usage: build_patch <src_file> <dest_file>" << endl;
|
cerr << "Usage: build_patch <old_file> <new_file>" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,10 +94,11 @@ const PN_uint32 Patchfile::_magic_number = 0xfeebfaac;
|
|||||||
// To version 2 on 11/2/02 to store copy offsets as relative.
|
// To version 2 on 11/2/02 to store copy offsets as relative.
|
||||||
const PN_uint16 Patchfile::_current_version = 2;
|
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::_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::_NULL_VALUE = PN_uint32(0) - 1;
|
||||||
const PN_uint32 Patchfile::_MAX_RUN_LENGTH = (PN_uint32(1) << 16) - 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
|
// Function: Patchfile::Constructor
|
||||||
@ -527,7 +528,7 @@ internal_read_header(const Filename &patch_file) {
|
|||||||
// Access: Private
|
// Access: Private
|
||||||
// Description:
|
// Description:
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PN_uint16 Patchfile::
|
PN_uint32 Patchfile::
|
||||||
calc_hash(const char *buffer) {
|
calc_hash(const char *buffer) {
|
||||||
#ifdef USE_MD5_FOR_HASHTABLE_INDEX_VALUES
|
#ifdef USE_MD5_FOR_HASHTABLE_INDEX_VALUES
|
||||||
HashVal hash;
|
HashVal hash;
|
||||||
@ -537,18 +538,18 @@ calc_hash(const char *buffer) {
|
|||||||
|
|
||||||
return PN_uint16(hash.get_value(0));
|
return PN_uint16(hash.get_value(0));
|
||||||
#else
|
#else
|
||||||
PN_uint16 hash_value = 0;
|
PN_uint32 hash_value = 0;
|
||||||
|
|
||||||
for(int i = 0; i < (int)_footprint_length; i++) {
|
for(int i = 0; i < (int)_footprint_length; i++) {
|
||||||
// this is probably not such a good hash. to be replaced
|
// 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
|
/// --> 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++;
|
buffer++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//cout << hash_value << " ";
|
//cout << hash_value << " ";
|
||||||
|
|
||||||
return hash_value;
|
return hash_value & _HASH_MASK;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,7 +610,7 @@ build_hash_link_tables(const char *buffer_orig, PN_uint32 length_orig,
|
|||||||
double t = GET_PROFILE_TIME();
|
double t = GET_PROFILE_TIME();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PN_uint16 hash_value = calc_hash(&buffer_orig[i]);
|
PN_uint32 hash_value = calc_hash(&buffer_orig[i]);
|
||||||
|
|
||||||
#ifdef PROFILE_PATCH_BUILD
|
#ifdef PROFILE_PATCH_BUILD
|
||||||
hashCalc += GET_PROFILE_TIME() - t;
|
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
|
// two strings of bytes
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
PN_uint32 Patchfile::
|
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;
|
PN_uint32 length = 0;
|
||||||
while ((length < max_length) && (*buf1 == *buf2)) {
|
while ((length < max_length) && (*buf1 == *buf2)) {
|
||||||
buf1++, buf2++, length++;
|
buf1++, buf2++, length++;
|
||||||
@ -697,7 +710,7 @@ find_longest_match(PN_uint32 new_pos, PN_uint32 ©_pos, PN_uint16 ©_lengt
|
|||||||
copy_length = 0;
|
copy_length = 0;
|
||||||
|
|
||||||
// get offset of matching string (in orig file) from hash table
|
// 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 no match, bail
|
||||||
if (_NULL_VALUE == hash_table[hash_value])
|
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];
|
copy_pos = hash_table[hash_value];
|
||||||
|
|
||||||
// calc match length
|
// calc match length
|
||||||
copy_length = (PN_uint16)calc_match_length(&buffer_new[new_pos], &buffer_orig[copy_pos],
|
copy_length = (PN_uint16)calc_match_length(&buffer_new[new_pos],
|
||||||
min(min((length_new - new_pos),(length_orig - copy_pos)), _MAX_RUN_LENGTH));
|
&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
|
// run through link table, see if we find any longer matches
|
||||||
PN_uint32 match_offset;
|
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];
|
match_offset = link_table[copy_pos];
|
||||||
|
|
||||||
while (match_offset != _NULL_VALUE) {
|
while (match_offset != _NULL_VALUE) {
|
||||||
match_length = (PN_uint16)calc_match_length(&buffer_new[new_pos], &buffer_orig[match_offset],
|
match_length = (PN_uint16)calc_match_length(&buffer_new[new_pos],
|
||||||
min(min((length_new - new_pos),(length_orig - match_offset)), _MAX_RUN_LENGTH));
|
&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?
|
// have we found a longer match?
|
||||||
if (match_length > copy_length) {
|
if (match_length > copy_length) {
|
||||||
|
@ -83,11 +83,12 @@ private:
|
|||||||
// stuff for the build operation
|
// stuff for the build operation
|
||||||
void build_hash_link_tables(const char *buffer_orig, PN_uint32 length_orig,
|
void build_hash_link_tables(const char *buffer_orig, PN_uint32 length_orig,
|
||||||
PN_uint32 *hash_table, PN_uint32 *link_table);
|
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,
|
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 *hash_table, PN_uint32 *link_table, const char* buffer_orig,
|
||||||
PN_uint32 length_orig, const char* buffer_new, PN_uint32 length_new);
|
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,
|
void emit_ADD(ofstream &write_stream, PN_uint16 length, const char* buffer,
|
||||||
PN_uint32 ADD_pos);
|
PN_uint32 ADD_pos);
|
||||||
@ -99,6 +100,7 @@ private:
|
|||||||
static const PN_uint32 _DEFAULT_FOOTPRINT_LENGTH;
|
static const PN_uint32 _DEFAULT_FOOTPRINT_LENGTH;
|
||||||
static const PN_uint32 _NULL_VALUE;
|
static const PN_uint32 _NULL_VALUE;
|
||||||
static const PN_uint32 _MAX_RUN_LENGTH;
|
static const PN_uint32 _MAX_RUN_LENGTH;
|
||||||
|
static const PN_uint32 _HASH_MASK;
|
||||||
|
|
||||||
PN_uint32 _footprint_length;
|
PN_uint32 _footprint_length;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user