* PStore content update perf optimization. Patch by Masaki Matsushita.
See #5248. * lib/pstore.rb (save_data): * Delete inadequate Marshal check. * Deferred file truncation: when writing the new content, truncate the saved file to the data size after writing the data, instead of truncating whole bytes before writing data. * Deferred MD5 calculation: when comparing MD5 hash to check the content modification, calculate MD5 hash of new data iif the content length is differ from the old one. * Compare content size with String#bytesize instead of String#size. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34083 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
5aea2ad18c
commit
fcec6b5c0d
19
ChangeLog
19
ChangeLog
@ -1,3 +1,22 @@
|
|||||||
|
Tue Dec 20 23:50:12 2011 Hiroshi Nakamura <nahi@ruby-lang.org>
|
||||||
|
|
||||||
|
* PStore content update perf optimization. Patch by Masaki Matsushita.
|
||||||
|
See #5248.
|
||||||
|
|
||||||
|
* lib/pstore.rb (save_data):
|
||||||
|
|
||||||
|
* Delete inadequate Marshal check.
|
||||||
|
|
||||||
|
* Deferred file truncation: when writing the new content, truncate
|
||||||
|
the saved file to the data size after writing the data, instead of
|
||||||
|
truncating whole bytes before writing data.
|
||||||
|
|
||||||
|
* Deferred MD5 calculation: when comparing MD5 hash to check the
|
||||||
|
content modification, calculate MD5 hash of new data iif the
|
||||||
|
content length is differ from the old one.
|
||||||
|
|
||||||
|
* Compare content size with String#bytesize instead of String#size.
|
||||||
|
|
||||||
Tue Dec 20 21:00:30 2011 Tadayoshi Funaba <tadf@dotrb.org>
|
Tue Dec 20 21:00:30 2011 Tadayoshi Funaba <tadf@dotrb.org>
|
||||||
|
|
||||||
* ext/date/date_core.c: uses to_integer instead.
|
* ext/date/date_core.c: uses to_integer instead.
|
||||||
|
@ -402,11 +402,11 @@ class PStore
|
|||||||
# This seems to be a newly-created file.
|
# This seems to be a newly-created file.
|
||||||
table = {}
|
table = {}
|
||||||
checksum = empty_marshal_checksum
|
checksum = empty_marshal_checksum
|
||||||
size = empty_marshal_data.size
|
size = empty_marshal_data.bytesize
|
||||||
else
|
else
|
||||||
table = load(data)
|
table = load(data)
|
||||||
checksum = Digest::MD5.digest(data)
|
checksum = Digest::MD5.digest(data)
|
||||||
size = data.size
|
size = data.bytesize
|
||||||
if !table.is_a?(Hash)
|
if !table.is_a?(Hash)
|
||||||
raise Error, "PStore file seems to be corrupted."
|
raise Error, "PStore file seems to be corrupted."
|
||||||
end
|
end
|
||||||
@ -427,34 +427,10 @@ class PStore
|
|||||||
is_windows
|
is_windows
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check whether Marshal.dump supports the 'canonical' option. This option
|
|
||||||
# makes sure that Marshal.dump always dumps data structures in the same order.
|
|
||||||
# This is important because otherwise, the checksums that we generate may differ.
|
|
||||||
def marshal_dump_supports_canonical_option?
|
|
||||||
begin
|
|
||||||
Marshal.dump(nil, -1, true)
|
|
||||||
result = true
|
|
||||||
rescue
|
|
||||||
result = false
|
|
||||||
end
|
|
||||||
self.class.instance_method(:marshal_dump_supports_canonical_option?)
|
|
||||||
self.class.__send__(:define_method, :marshal_dump_supports_canonical_option?) do
|
|
||||||
result
|
|
||||||
end
|
|
||||||
result
|
|
||||||
end
|
|
||||||
|
|
||||||
def save_data(original_checksum, original_file_size, file)
|
def save_data(original_checksum, original_file_size, file)
|
||||||
# We only want to save the new data if the size or checksum has changed.
|
|
||||||
# This results in less filesystem calls, which is good for performance.
|
|
||||||
if marshal_dump_supports_canonical_option?
|
|
||||||
new_data = Marshal.dump(@table, -1, true)
|
|
||||||
else
|
|
||||||
new_data = dump(@table)
|
new_data = dump(@table)
|
||||||
end
|
|
||||||
new_checksum = Digest::MD5.digest(new_data)
|
|
||||||
|
|
||||||
if new_data.size != original_file_size || new_checksum != original_checksum
|
if new_data.bytesize != original_file_size || Digest::MD5.digest(new_data) != original_checksum
|
||||||
if @ultra_safe && !on_windows?
|
if @ultra_safe && !on_windows?
|
||||||
# Windows doesn't support atomic file renames.
|
# Windows doesn't support atomic file renames.
|
||||||
save_data_with_atomic_file_rename_strategy(new_data, file)
|
save_data_with_atomic_file_rename_strategy(new_data, file)
|
||||||
@ -484,8 +460,8 @@ class PStore
|
|||||||
|
|
||||||
def save_data_with_fast_strategy(data, file)
|
def save_data_with_fast_strategy(data, file)
|
||||||
file.rewind
|
file.rewind
|
||||||
file.truncate(0)
|
|
||||||
file.write(data)
|
file.write(data)
|
||||||
|
file.truncate(data.bytesize)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user