On 2015-02-23 16:41, Claes Redestad wrote:
On 02/22/2015 10:16 PM, Xueming Shen wrote:
On 2/21/15 6:11 PM, Claes Redestad wrote:
Hi Sherman,
On 2015-02-21 19:49, Xueming Shen wrote:
Hi Claes,
This change basically undo the "fix" for 4759491 [1], for better
performance ...
my intent was never to break current behavior, but that mistake can
be rectified
without missing out on the startup benefit of laziness:
http://cr.openjdk.java.net/~redestad/jdk9/8073497/webrev.1/
The time/mtime getters now use the mtime field if it exists, while
the setters will
update both fields. Since getLastModified already fell back to
converting the
time field rather than null if mtime wasn't set, setting mtime to a
FileTime when
calling setTime seems consistent and a cheap way to preserve the
time precision.
I guess a range check to skip the FileTime creation in setTime if
the time is within
the DOS time bounds would be a valid optimization, since that will
typically
always be the case.
It's a reasonable solution. I would assume we probably need that
"range check" optimization
to avoid setting the "mtime" field in normal use scenario. ZOS now
outputs the more accurate
"mtime" to the zip file using "extend timestamp" if it's not null
(the entry gets bigger). The
assumption now is that we only output the extended timestamp if the
time stamps set
via the setXYZTime() explicitly.
ZOS.java
...
432 int elenEXTT = 0; // info-zip extended
timestamp
433 int flagEXTT = 0;
434 if (e.mtime != null) {
435 elenEXTT += 4;
436 flagEXTT |= EXTT_FLAG_LMT;
437 }
438 if (e.atime != null) {
439 elenEXTT += 4;
440 flagEXTT |= EXTT_FLAG_LAT;
441 }
442 if (e.ctime != null) {
443 elenEXTT += 4;
444 flagEXTT |= EXTT_FLAT_CT;
445 }
446 if (flagEXTT != 0)
447 elen += (elenEXTT + 5); // headid(2) + size(2) +
flag(1) + data
448 writeShort(elen);
...
Here's my attempt to resolve this:
We could preserve precision by shifting the remaining milliseconds into
the dostime field,
since the DOS time will only use the 4 lower bytes:
http://cr.openjdk.java.net/~redestad/jdk9/8073497/webrev.4/
After I went through more extensive testing and verification I realized
that narrowing
dostime to an int and breaking this remainder hack out into a separate
field would be
possible without affecting ZipEntry footprint; arguably cleaner, but if
this version is
acceptable I would prefer not to.
Going this way preserves precision across the entire input range of
setTime, thus all tests
I could find pass with this version; I've also expanded the
TestExtraTime test to test both
far ancient, far future and near future times to verify precision is
preserved.
I backpedaled on the getLastModifiedTime optimization to set the mtime
field that Peter
suggested since it would have the side-effect that the extra time field
would be written
after a call to this getter, which would be a bit too unexpected.
Thanks!
/Claes