View Javadoc
1   /*
2    * Copyright (C) 2018, Google LLC. 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  
11  package org.eclipse.jgit.internal.storage.dfs;
12  
13  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT;
14  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC;
15  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST;
16  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_TXN;
17  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT;
18  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.RECEIVE;
19  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE;
20  import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
21  import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
22  import static org.junit.Assert.assertEquals;
23  
24  import java.util.Comparator;
25  import java.util.concurrent.atomic.AtomicInteger;
26  
27  import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
28  import org.junit.Before;
29  import org.junit.Test;
30  
31  public final class DfsPackDescriptionTest {
32  	private AtomicInteger counter;
33  
34  	@Before
35  	public void setUp() {
36  		counter = new AtomicInteger();
37  	}
38  
39  	@Test
40  	public void objectLookupComparatorEqual() throws Exception {
41  		DfsPackDescription a = create(RECEIVE);
42  		a.setFileSize(PACK, 1);
43  		a.setFileSize(INDEX, 1);
44  		a.setLastModified(1);
45  		a.setObjectCount(1);
46  		a.setMaxUpdateIndex(1);
47  
48  		DfsPackDescription b = create(INSERT);
49  		b.setFileSize(PACK, 1);
50  		b.setFileSize(INDEX, 2);
51  		b.setLastModified(1);
52  		b.setObjectCount(1);
53  		b.setMaxUpdateIndex(2);
54  
55  		assertComparesEqual(DfsPackDescription.objectLookupComparator(), a, b);
56  	}
57  
58  	@Test
59  	public void objectLookupComparatorPackSource() throws Exception {
60  		DfsPackDescription a = create(COMPACT);
61  		a.setFileSize(PACK, 2);
62  		a.setLastModified(1);
63  		a.setObjectCount(2);
64  
65  		DfsPackDescription b = create(GC);
66  		b.setFileSize(PACK, 1);
67  		b.setLastModified(2);
68  		b.setObjectCount(1);
69  
70  		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b);
71  	}
72  
73  	@Test
74  	public void objectLookupComparatorCustomPackSourceComparator()
75  			throws Exception {
76  		DfsPackDescription a = create(GC);
77  
78  		DfsPackDescription b = create(COMPACT);
79  
80  		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), b, a);
81  		assertComparesLessThan(
82  				DfsPackDescription.objectLookupComparator(
83  					new PackSource.ComparatorBuilder()
84  						.add(GC)
85  						.add(INSERT, RECEIVE, GC_REST, GC_TXN, UNREACHABLE_GARBAGE)
86  						.add(COMPACT)
87  						.build()),
88  				a, b);
89  	}
90  
91  	@Test
92  	public void objectLookupComparatorGcFileSize() throws Exception {
93  		// a is older and smaller.
94  		DfsPackDescription a = create(GC_REST);
95  		a.setFileSize(PACK, 100);
96  		a.setLastModified(1);
97  		a.setObjectCount(2);
98  
99  		// b is newer and larger.
100 		DfsPackDescription b = create(GC_REST);
101 		b.setFileSize(PACK, 200);
102 		b.setLastModified(2);
103 		b.setObjectCount(1);
104 
105 		// Since they have the same GC type, tiebreaker is size, and a comes first.
106 		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b);
107 	}
108 
109 	@Test
110 	public void objectLookupComparatorNonGcLastModified()
111 			throws Exception {
112 		// a is older and smaller.
113 		DfsPackDescription a = create(INSERT);
114 		a.setFileSize(PACK, 100);
115 		a.setLastModified(1);
116 		a.setObjectCount(2);
117 
118 		// b is newer and larger.
119 		DfsPackDescription b = create(INSERT);
120 		b.setFileSize(PACK, 200);
121 		b.setLastModified(2);
122 		b.setObjectCount(1);
123 
124 		// Since they have the same type but not GC, tiebreaker is last modified,
125 		// and b comes first.
126 		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), b, a);
127 	}
128 
129 	@Test
130 	public void objectLookupComparatorObjectCount() throws Exception {
131 		DfsPackDescription a = create(INSERT);
132 		a.setObjectCount(1);
133 
134 		DfsPackDescription b = create(INSERT);
135 		b.setObjectCount(2);
136 
137 		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b);
138 	}
139 
140 	@Test
141 	public void reftableComparatorEqual() throws Exception {
142 		DfsPackDescription a = create(INSERT);
143 		a.setFileSize(PACK, 100);
144 		a.setObjectCount(1);
145 
146 		DfsPackDescription b = create(INSERT);
147 		b.setFileSize(PACK, 200);
148 		a.setObjectCount(2);
149 
150 		assertComparesEqual(DfsPackDescription.reftableComparator(), a, b);
151 	}
152 
153 	@Test
154 	public void reftableComparatorPackSource() throws Exception {
155 		DfsPackDescription a = create(INSERT);
156 		a.setMaxUpdateIndex(1);
157 		a.setLastModified(1);
158 
159 		DfsPackDescription b = create(GC);
160 		b.setMaxUpdateIndex(2);
161 		b.setLastModified(2);
162 
163 		assertComparesLessThan(DfsPackDescription.reftableComparator(), b, a);
164 	}
165 
166 	@Test
167 	public void reftableComparatorMaxUpdateIndex() throws Exception {
168 		DfsPackDescription a = create(INSERT);
169 		a.setMaxUpdateIndex(1);
170 		a.setLastModified(2);
171 
172 		DfsPackDescription b = create(INSERT);
173 		b.setMaxUpdateIndex(2);
174 		b.setLastModified(1);
175 
176 		assertComparesLessThan(DfsPackDescription.reftableComparator(), a, b);
177 	}
178 
179 	@Test
180 	public void reftableComparatorLastModified() throws Exception {
181 		DfsPackDescription a = create(INSERT);
182 		a.setLastModified(1);
183 
184 		DfsPackDescription b = create(INSERT);
185 		b.setLastModified(2);
186 
187 		assertComparesLessThan(DfsPackDescription.reftableComparator(), a, b);
188 	}
189 
190 	@Test
191 	public void reuseComparatorEqual() throws Exception {
192 		DfsPackDescription a = create(RECEIVE);
193 		a.setFileSize(PACK, 1);
194 		a.setFileSize(INDEX, 1);
195 		a.setLastModified(1);
196 		a.setObjectCount(1);
197 		a.setMaxUpdateIndex(1);
198 
199 		DfsPackDescription b = create(INSERT);
200 		b.setFileSize(PACK, 2);
201 		b.setFileSize(INDEX, 2);
202 		b.setLastModified(2);
203 		b.setObjectCount(2);
204 		b.setMaxUpdateIndex(2);
205 
206 		assertComparesEqual(DfsPackDescription.reuseComparator(), a, b);
207 	}
208 
209 	@Test
210 	public void reuseComparatorGcPackSize() throws Exception {
211 		DfsPackDescription a = create(GC_REST);
212 		a.setFileSize(PACK, 1);
213 		a.setFileSize(INDEX, 1);
214 		a.setLastModified(2);
215 		a.setObjectCount(1);
216 		a.setMaxUpdateIndex(1);
217 
218 		DfsPackDescription b = create(GC_REST);
219 		b.setFileSize(PACK, 2);
220 		b.setFileSize(INDEX, 2);
221 		b.setLastModified(1);
222 		b.setObjectCount(2);
223 		b.setMaxUpdateIndex(2);
224 
225 		assertComparesLessThan(DfsPackDescription.reuseComparator(), b, a);
226 	}
227 
228 	private DfsPackDescription create(PackSource source) {
229 		return new DfsPackDescription(
230 				new DfsRepositoryDescription("repo"),
231 				"pack_" + counter.incrementAndGet(),
232 				source);
233 	}
234 
235 	private static <T> void assertComparesEqual(
236 			Comparator<T> comparator, T o1, T o2) {
237 		assertEquals(
238 				"first object must compare equal to itself",
239 				0, comparator.compare(o1, o1));
240 		assertEquals(
241 				"second object must compare equal to itself",
242 				0, comparator.compare(o2, o2));
243 		assertEquals(
244 				"first object must compare equal to second object",
245 				0, comparator.compare(o1, o2));
246 	}
247 
248 	private static <T> void assertComparesLessThan(
249 			Comparator<T> comparator, T o1, T o2) {
250 		assertEquals(
251 				"first object must compare equal to itself",
252 				0, comparator.compare(o1, o1));
253 		assertEquals(
254 				"second object must compare equal to itself",
255 				0, comparator.compare(o2, o2));
256 		assertEquals(
257 				"first object must compare less than second object",
258 				-1, comparator.compare(o1, o2));
259 	}
260 }