View Javadoc
1   /*
2    * Copyright (C) 2018, Google LLC.
3    * and other copyright owners as documented in the project's IP log.
4    *
5    * This program and the accompanying materials are made available
6    * under the terms of the Eclipse Distribution License v1.0 which
7    * accompanies this distribution, is reproduced below, and is
8    * available at http://www.eclipse.org/org/documents/edl-v10.php
9    *
10   * All rights reserved.
11   *
12   * Redistribution and use in source and binary forms, with or
13   * without modification, are permitted provided that the following
14   * conditions are met:
15   *
16   * - Redistributions of source code must retain the above copyright
17   *   notice, this list of conditions and the following disclaimer.
18   *
19   * - Redistributions in binary form must reproduce the above
20   *   copyright notice, this list of conditions and the following
21   *   disclaimer in the documentation and/or other materials provided
22   *   with the distribution.
23   *
24   * - Neither the name of the Eclipse Foundation, Inc. nor the
25   *   names of its contributors may be used to endorse or promote
26   *   products derived from this software without specific prior
27   *   written permission.
28   *
29   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
30   * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
31   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
32   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42   */
43  
44  package org.eclipse.jgit.internal.storage.dfs;
45  
46  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.COMPACT;
47  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC;
48  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_REST;
49  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.GC_TXN;
50  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.INSERT;
51  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.RECEIVE;
52  import static org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE;
53  import static org.eclipse.jgit.internal.storage.pack.PackExt.INDEX;
54  import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
55  import static org.junit.Assert.assertEquals;
56  
57  import java.util.Comparator;
58  import java.util.concurrent.atomic.AtomicInteger;
59  
60  import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
61  import org.junit.Before;
62  import org.junit.Test;
63  
64  public final class DfsPackDescriptionTest {
65  	private AtomicInteger counter;
66  
67  	@Before
68  	public void setUp() {
69  		counter = new AtomicInteger();
70  	}
71  
72  	@Test
73  	public void objectLookupComparatorEqual() throws Exception {
74  		DfsPackDescription a = create(RECEIVE);
75  		a.setFileSize(PACK, 1);
76  		a.setFileSize(INDEX, 1);
77  		a.setLastModified(1);
78  		a.setObjectCount(1);
79  		a.setMaxUpdateIndex(1);
80  
81  		DfsPackDescription b = create(INSERT);
82  		b.setFileSize(PACK, 1);
83  		b.setFileSize(INDEX, 2);
84  		b.setLastModified(1);
85  		b.setObjectCount(1);
86  		b.setMaxUpdateIndex(2);
87  
88  		assertComparesEqual(DfsPackDescription.objectLookupComparator(), a, b);
89  	}
90  
91  	@Test
92  	public void objectLookupComparatorPackSource() throws Exception {
93  		DfsPackDescription a = create(COMPACT);
94  		a.setFileSize(PACK, 2);
95  		a.setLastModified(1);
96  		a.setObjectCount(2);
97  
98  		DfsPackDescription b = create(GC);
99  		b.setFileSize(PACK, 1);
100 		b.setLastModified(2);
101 		b.setObjectCount(1);
102 
103 		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b);
104 	}
105 
106 	@Test
107 	public void objectLookupComparatorCustomPackSourceComparator()
108 			throws Exception {
109 		DfsPackDescription a = create(GC);
110 
111 		DfsPackDescription b = create(COMPACT);
112 
113 		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), b, a);
114 		assertComparesLessThan(
115 				DfsPackDescription.objectLookupComparator(
116 					new PackSource.ComparatorBuilder()
117 						.add(GC)
118 						.add(INSERT, RECEIVE, GC_REST, GC_TXN, UNREACHABLE_GARBAGE)
119 						.add(COMPACT)
120 						.build()),
121 				a, b);
122 	}
123 
124 	@Test
125 	public void objectLookupComparatorGcFileSize() throws Exception {
126 		// a is older and smaller.
127 		DfsPackDescription a = create(GC_REST);
128 		a.setFileSize(PACK, 100);
129 		a.setLastModified(1);
130 		a.setObjectCount(2);
131 
132 		// b is newer and larger.
133 		DfsPackDescription b = create(GC_REST);
134 		b.setFileSize(PACK, 200);
135 		b.setLastModified(2);
136 		b.setObjectCount(1);
137 
138 		// Since they have the same GC type, tiebreaker is size, and a comes first.
139 		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b);
140 	}
141 
142 	@Test
143 	public void objectLookupComparatorNonGcLastModified()
144 			throws Exception {
145 		// a is older and smaller.
146 		DfsPackDescription a = create(INSERT);
147 		a.setFileSize(PACK, 100);
148 		a.setLastModified(1);
149 		a.setObjectCount(2);
150 
151 		// b is newer and larger.
152 		DfsPackDescription b = create(INSERT);
153 		b.setFileSize(PACK, 200);
154 		b.setLastModified(2);
155 		b.setObjectCount(1);
156 
157 		// Since they have the same type but not GC, tiebreaker is last modified,
158 		// and b comes first.
159 		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), b, a);
160 	}
161 
162 	@Test
163 	public void objectLookupComparatorObjectCount() throws Exception {
164 		DfsPackDescription a = create(INSERT);
165 		a.setObjectCount(1);
166 
167 		DfsPackDescription b = create(INSERT);
168 		b.setObjectCount(2);
169 
170 		assertComparesLessThan(DfsPackDescription.objectLookupComparator(), a, b);
171 	}
172 
173 	@Test
174 	public void reftableComparatorEqual() throws Exception {
175 		DfsPackDescription a = create(INSERT);
176 		a.setFileSize(PACK, 100);
177 		a.setObjectCount(1);
178 
179 		DfsPackDescription b = create(INSERT);
180 		b.setFileSize(PACK, 200);
181 		a.setObjectCount(2);
182 
183 		assertComparesEqual(DfsPackDescription.reftableComparator(), a, b);
184 	}
185 
186 	@Test
187 	public void reftableComparatorPackSource() throws Exception {
188 		DfsPackDescription a = create(INSERT);
189 		a.setMaxUpdateIndex(1);
190 		a.setLastModified(1);
191 
192 		DfsPackDescription b = create(GC);
193 		b.setMaxUpdateIndex(2);
194 		b.setLastModified(2);
195 
196 		assertComparesLessThan(DfsPackDescription.reftableComparator(), b, a);
197 	}
198 
199 	@Test
200 	public void reftableComparatorMaxUpdateIndex() throws Exception {
201 		DfsPackDescription a = create(INSERT);
202 		a.setMaxUpdateIndex(1);
203 		a.setLastModified(2);
204 
205 		DfsPackDescription b = create(INSERT);
206 		b.setMaxUpdateIndex(2);
207 		b.setLastModified(1);
208 
209 		assertComparesLessThan(DfsPackDescription.reftableComparator(), a, b);
210 	}
211 
212 	@Test
213 	public void reftableComparatorLastModified() throws Exception {
214 		DfsPackDescription a = create(INSERT);
215 		a.setLastModified(1);
216 
217 		DfsPackDescription b = create(INSERT);
218 		b.setLastModified(2);
219 
220 		assertComparesLessThan(DfsPackDescription.reftableComparator(), a, b);
221 	}
222 
223 	@Test
224 	public void reuseComparatorEqual() throws Exception {
225 		DfsPackDescription a = create(RECEIVE);
226 		a.setFileSize(PACK, 1);
227 		a.setFileSize(INDEX, 1);
228 		a.setLastModified(1);
229 		a.setObjectCount(1);
230 		a.setMaxUpdateIndex(1);
231 
232 		DfsPackDescription b = create(INSERT);
233 		b.setFileSize(PACK, 2);
234 		b.setFileSize(INDEX, 2);
235 		b.setLastModified(2);
236 		b.setObjectCount(2);
237 		b.setMaxUpdateIndex(2);
238 
239 		assertComparesEqual(DfsPackDescription.reuseComparator(), a, b);
240 	}
241 
242 	@Test
243 	public void reuseComparatorGcPackSize() throws Exception {
244 		DfsPackDescription a = create(GC_REST);
245 		a.setFileSize(PACK, 1);
246 		a.setFileSize(INDEX, 1);
247 		a.setLastModified(2);
248 		a.setObjectCount(1);
249 		a.setMaxUpdateIndex(1);
250 
251 		DfsPackDescription b = create(GC_REST);
252 		b.setFileSize(PACK, 2);
253 		b.setFileSize(INDEX, 2);
254 		b.setLastModified(1);
255 		b.setObjectCount(2);
256 		b.setMaxUpdateIndex(2);
257 
258 		assertComparesLessThan(DfsPackDescription.reuseComparator(), b, a);
259 	}
260 
261 	private DfsPackDescription create(PackSource source) {
262 		return new DfsPackDescription(
263 				new DfsRepositoryDescription("repo"),
264 				"pack_" + counter.incrementAndGet(),
265 				source);
266 	}
267 
268 	private static <T> void assertComparesEqual(
269 			Comparator<T> comparator, T o1, T o2) {
270 		assertEquals(
271 				"first object must compare equal to itself",
272 				0, comparator.compare(o1, o1));
273 		assertEquals(
274 				"second object must compare equal to itself",
275 				0, comparator.compare(o2, o2));
276 		assertEquals(
277 				"first object must compare equal to second object",
278 				0, comparator.compare(o1, o2));
279 	}
280 
281 	private static <T> void assertComparesLessThan(
282 			Comparator<T> comparator, T o1, T o2) {
283 		assertEquals(
284 				"first object must compare equal to itself",
285 				0, comparator.compare(o1, o1));
286 		assertEquals(
287 				"second object must compare equal to itself",
288 				0, comparator.compare(o2, o2));
289 		assertEquals(
290 				"first object must compare less than second object",
291 				-1, comparator.compare(o1, o2));
292 	}
293 }