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