View Javadoc
1   /*
2    * Copyright (C) 2019, Thomas Wolf <thomas.wolf@paranor.ch> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.treewalk;
11  
12  import java.time.Instant;
13  import java.util.Comparator;
14  
15  /**
16   * Specialized comparator for {@link Instant}s. If either timestamp has a zero
17   * fraction, compares only seconds. If either timestamp has no time fraction
18   * smaller than a millisecond, compares only milliseconds. If either timestamp
19   * has no fraction smaller than a microsecond, compares only microseconds.
20   */
21  class InstantComparator implements Comparator<Instant> {
22  
23  	@Override
24  	public int compare(Instant a, Instant b) {
25  		return compare(a, b, false);
26  	}
27  
28  	/**
29  	 * Compares two {@link Instant}s to the lower resolution of the two
30  	 * instants. See {@link InstantComparator}.
31  	 *
32  	 * @param a
33  	 *            first {@link Instant} to compare
34  	 * @param b
35  	 *            second {@link Instant} to compare
36  	 * @param forceSecondsOnly
37  	 *            whether to omit all fraction comparison
38  	 * @return a value &lt; 0 if a &lt; b, a value &gt; 0 if a &gt; b, and 0 if
39  	 *         a == b
40  	 */
41  	public int compare(Instant a, Instant b, boolean forceSecondsOnly) {
42  		long aSeconds = a.getEpochSecond();
43  		long bSeconds = b.getEpochSecond();
44  		int result = Long.compare(aSeconds, bSeconds);
45  		if (result != 0) {
46  			return result;
47  		}
48  		int aSubSecond = a.getNano();
49  		int bSubSecond = b.getNano();
50  		if (forceSecondsOnly || (aSubSecond == 0)
51  				|| (bSubSecond == 0)) {
52  			// Don't check the subseconds part.
53  			return 0;
54  		} else if (aSubSecond != bSubSecond) {
55  			// If either has nothing smaller than a millisecond, compare only
56  			// milliseconds.
57  			int aSubMillis = aSubSecond % 1_000_000;
58  			int bSubMillis = bSubSecond % 1_000_000;
59  			if (aSubMillis == 0) {
60  				bSubSecond -= bSubMillis;
61  			} else if (bSubMillis == 0) {
62  				aSubSecond -= aSubMillis;
63  			} else {
64  				// Same again, but for microsecond resolution. NTFS has 100ns
65  				// resolution, but WindowsFileAttributes may provide only
66  				// microseconds (1000ns). Similar for some Unix file systems.
67  				int aSubMicros = aSubSecond % 1000;
68  				int bSubMicros = bSubSecond % 1000;
69  				if (aSubMicros == 0) {
70  					bSubSecond -= bSubMicros;
71  				} else if (bSubMicros == 0) {
72  					aSubSecond -= aSubMicros;
73  				}
74  			}
75  		}
76  		return Integer.compare(aSubSecond, bSubSecond);
77  	}
78  
79  }