Use Instant for smudge time in DirCache and DirCacheEntry

Change-Id: I98050a51baf4726c5717ef62ce7f026173666bdf
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Matthias Sohn 2019-07-18 03:36:18 +02:00
parent 95e8264cc8
commit d8d9427277
3 changed files with 39 additions and 11 deletions

View File

@ -15,6 +15,12 @@
<message_argument value="getLastModifiedInstant()"/>
</message_arguments>
</filter>
<filter id="1142947843">
<message_arguments>
<message_argument value="5.1.9"/>
<message_argument value="mightBeRacilyClean(Instant)"/>
</message_arguments>
</filter>
<filter id="1142947843">
<message_arguments>
<message_argument value="5.1.9"/>

View File

@ -58,6 +58,7 @@
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.text.MessageFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
@ -497,9 +498,7 @@ else if (ver != 2)
throw new CorruptObjectException(JGitText.get().DIRCHasTooManyEntries);
snapshot = FileSnapshot.save(liveFile);
// TODO (ms) combine smudge_s and smudge_ns into Duration
int smudge_s = (int) (snapshot.lastModifiedInstant().getEpochSecond());
int smudge_ns = snapshot.lastModifiedInstant().getNano();
Instant smudge = snapshot.lastModifiedInstant();
// Load the individual file entries.
//
@ -508,8 +507,9 @@ else if (ver != 2)
sortedEntries = new DirCacheEntry[entryCnt];
final MutableInteger infoAt = new MutableInteger();
for (int i = 0; i < entryCnt; i++)
sortedEntries[i] = new DirCacheEntry(infos, infoAt, in, md, smudge_s, smudge_ns);
for (int i = 0; i < entryCnt; i++) {
sortedEntries[i] = new DirCacheEntry(infos, infoAt, in, md, smudge);
}
// After the file entries are index extensions, and then a footer.
//

View File

@ -145,10 +145,9 @@ public class DirCacheEntry {
/** Flags which are never stored to disk. */
private byte inCoreFlags;
// TODO (ms): use Instant to combine smudge_s and smudge_ns
DirCacheEntry(final byte[] sharedInfo, final MutableInteger infoAt,
final InputStream in, final MessageDigest md, final int smudge_s,
final int smudge_ns) throws IOException {
final InputStream in, final MessageDigest md, final Instant smudge)
throws IOException {
info = sharedInfo;
infoOffset = infoAt.value;
@ -217,8 +216,9 @@ public class DirCacheEntry {
md.update(nullpad, 0, padLen);
}
if (mightBeRacilyClean(smudge_s, smudge_ns))
if (mightBeRacilyClean(smudge)) {
smudgeRacilyClean();
}
}
/**
@ -346,8 +346,29 @@ void write(OutputStream os) throws IOException {
* @param smudge_ns
* nanoseconds component of the index's last modified time.
* @return true if extra careful checks should be used.
* @deprecated use {@link #mightBeRacilyClean(Instant)} instead
*/
@Deprecated
public final boolean mightBeRacilyClean(int smudge_s, int smudge_ns) {
return mightBeRacilyClean(Instant.ofEpochSecond(smudge_s, smudge_ns));
}
/**
* Is it possible for this entry to be accidentally assumed clean?
* <p>
* The "racy git" problem happens when a work file can be updated faster
* than the filesystem records file modification timestamps. It is possible
* for an application to edit a work file, update the index, then edit it
* again before the filesystem will give the work file a new modification
* timestamp. This method tests to see if file was written out at the same
* time as the index.
*
* @param smudge
* index's last modified time.
* @return true if extra careful checks should be used.
* @since 5.1.9
*/
public final boolean mightBeRacilyClean(Instant smudge) {
// If the index has a modification time then it came from disk
// and was not generated from scratch in memory. In such cases
// the entry is 'racily clean' if the entry's cached modification
@ -357,8 +378,9 @@ public final boolean mightBeRacilyClean(int smudge_s, int smudge_ns) {
//
final int base = infoOffset + P_MTIME;
final int mtime = NB.decodeInt32(info, base);
if (smudge_s == mtime)
return smudge_ns <= NB.decodeInt32(info, base + 4);
if (smudge.getEpochSecond() == mtime) {
return smudge.getNano() <= NB.decodeInt32(info, base + 4);
}
return false;
}