1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.internal.storage.dfs;
12
13 import static org.eclipse.jgit.internal.storage.pack.PackExt.PACK;
14 import static org.eclipse.jgit.internal.storage.pack.PackExt.REFTABLE;
15
16 import java.util.Arrays;
17 import java.util.Comparator;
18
19 import org.eclipse.jgit.annotations.NonNull;
20 import org.eclipse.jgit.internal.storage.dfs.DfsObjDatabase.PackSource;
21 import org.eclipse.jgit.internal.storage.pack.PackExt;
22 import org.eclipse.jgit.internal.storage.reftable.ReftableWriter;
23 import org.eclipse.jgit.storage.pack.PackStatistics;
24
25
26
27
28
29
30
31
32
33 public class DfsPackDescription {
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public static Comparator<DfsPackDescription> objectLookupComparator() {
48 return objectLookupComparator(PackSource.DEFAULT_COMPARATOR);
49 }
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 public static Comparator<DfsPackDescription> objectLookupComparator(
65 Comparator<PackSource> packSourceComparator) {
66 return Comparator.comparing(
67 DfsPackDescription::getPackSource, packSourceComparator)
68 .thenComparing((a, b) -> {
69 PackSource as = a.getPackSource();
70 PackSource bs = b.getPackSource();
71
72
73
74
75
76 if (as == bs && isGC(as)) {
77 int cmp = Long.signum(a.getFileSize(PACK) - b.getFileSize(PACK));
78 if (cmp != 0) {
79 return cmp;
80 }
81 }
82
83
84 int cmp = Long.signum(b.getLastModified() - a.getLastModified());
85 if (cmp != 0) {
86 return cmp;
87 }
88
89
90
91
92 return Long.signum(a.getObjectCount() - b.getObjectCount());
93 });
94 }
95
96 static Comparator<DfsPackDescription> reftableComparator() {
97 return (a, b) -> {
98
99 int c = PackSource.DEFAULT_COMPARATOR.reversed()
100 .compare(a.getPackSource(), b.getPackSource());
101 if (c != 0) {
102 return c;
103 }
104
105
106 c = Long.signum(a.getMaxUpdateIndex() - b.getMaxUpdateIndex());
107 if (c != 0) {
108 return c;
109 }
110
111
112 return Long.signum(a.getLastModified() - b.getLastModified());
113 };
114 }
115
116 static Comparator<DfsPackDescription> reuseComparator() {
117 return (a, b) -> {
118 PackSource as = a.getPackSource();
119 PackSource bs = b.getPackSource();
120
121 if (as == bs && DfsPackDescription.isGC(as)) {
122
123
124
125 return Long.signum(b.getFileSize(PACK) - a.getFileSize(PACK));
126 }
127
128
129
130 return 0;
131 };
132 }
133
134 private final DfsRepositoryDescription repoDesc;
135 private final String packName;
136 private PackSource packSource;
137 private long lastModified;
138 private long[] sizeMap;
139 private int[] blockSizeMap;
140 private long objectCount;
141 private long deltaCount;
142 private long minUpdateIndex;
143 private long maxUpdateIndex;
144
145 private PackStatistics packStats;
146 private ReftableWriter.Stats refStats;
147 private int extensions;
148 private int indexVersion;
149 private long estimatedPackSize;
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 public DfsPackDescription(DfsRepositoryDescription repoDesc, String name,
169 @NonNull PackSource packSource) {
170 this.repoDesc = repoDesc;
171 int dot = name.lastIndexOf('.');
172 this.packName = (dot < 0) ? name : name.substring(0, dot);
173 this.packSource = packSource;
174
175 int extCnt = PackExt.values().length;
176 sizeMap = new long[extCnt];
177 blockSizeMap = new int[extCnt];
178 }
179
180
181
182
183
184
185 public DfsRepositoryDescription getRepositoryDescription() {
186 return repoDesc;
187 }
188
189
190
191
192
193
194
195 public void addFileExt(PackExt ext) {
196 extensions |= ext.getBit();
197 }
198
199
200
201
202
203
204
205
206 public boolean hasFileExt(PackExt ext) {
207 return (extensions & ext.getBit()) != 0;
208 }
209
210
211
212
213
214
215
216
217 public String getFileName(PackExt ext) {
218 return packName + '.' + ext.getExtension();
219 }
220
221
222
223
224
225
226
227
228 public DfsStreamKey getStreamKey(PackExt ext) {
229 return DfsStreamKey.of(getRepositoryDescription(), getFileName(ext),
230 ext);
231 }
232
233
234
235
236
237
238 @NonNull
239 public PackSource getPackSource() {
240 return packSource;
241 }
242
243
244
245
246
247
248
249
250 public DfsPackDescription setPackSource(@NonNull PackSource source) {
251 packSource = source;
252 return this;
253 }
254
255
256
257
258
259
260 public long getLastModified() {
261 return lastModified;
262 }
263
264
265
266
267
268
269
270
271 public DfsPackDescription setLastModified(long timeMillis) {
272 lastModified = timeMillis;
273 return this;
274 }
275
276
277
278
279
280
281 public long getMinUpdateIndex() {
282 return minUpdateIndex;
283 }
284
285
286
287
288
289
290
291
292 public DfsPackDescription setMinUpdateIndex(long min) {
293 minUpdateIndex = min;
294 return this;
295 }
296
297
298
299
300
301
302 public long getMaxUpdateIndex() {
303 return maxUpdateIndex;
304 }
305
306
307
308
309
310
311
312
313 public DfsPackDescription setMaxUpdateIndex(long max) {
314 maxUpdateIndex = max;
315 return this;
316 }
317
318
319
320
321
322
323
324
325
326
327
328 public DfsPackDescription setFileSize(PackExt ext, long bytes) {
329 int i = ext.getPosition();
330 if (i >= sizeMap.length) {
331 sizeMap = Arrays.copyOf(sizeMap, i + 1);
332 }
333 sizeMap[i] = Math.max(0, bytes);
334 return this;
335 }
336
337
338
339
340
341
342
343
344 public long getFileSize(PackExt ext) {
345 int i = ext.getPosition();
346 return i < sizeMap.length ? sizeMap[i] : 0;
347 }
348
349
350
351
352
353
354
355
356
357 public int getBlockSize(PackExt ext) {
358 int i = ext.getPosition();
359 return i < blockSizeMap.length ? blockSizeMap[i] : 0;
360 }
361
362
363
364
365
366
367
368
369
370
371
372 public DfsPackDescription setBlockSize(PackExt ext, int blockSize) {
373 int i = ext.getPosition();
374 if (i >= blockSizeMap.length) {
375 blockSizeMap = Arrays.copyOf(blockSizeMap, i + 1);
376 }
377 blockSizeMap[i] = Math.max(0, blockSize);
378 return this;
379 }
380
381
382
383
384
385
386
387
388
389 public DfsPackDescription setEstimatedPackSize(long estimatedPackSize) {
390 this.estimatedPackSize = Math.max(0, estimatedPackSize);
391 return this;
392 }
393
394
395
396
397
398
399
400 public long getEstimatedPackSize() {
401 return estimatedPackSize;
402 }
403
404
405
406
407
408
409 public long getObjectCount() {
410 return objectCount;
411 }
412
413
414
415
416
417
418
419
420 public DfsPackDescription setObjectCount(long cnt) {
421 objectCount = Math.max(0, cnt);
422 return this;
423 }
424
425
426
427
428
429
430 public long getDeltaCount() {
431 return deltaCount;
432 }
433
434
435
436
437
438
439
440
441 public DfsPackDescription setDeltaCount(long cnt) {
442 deltaCount = Math.max(0, cnt);
443 return this;
444 }
445
446
447
448
449
450
451
452
453
454 public PackStatistics getPackStats() {
455 return packStats;
456 }
457
458 DfsPackDescription setPackStats(PackStatistics stats) {
459 this.packStats = stats;
460 setFileSize(PACK, stats.getTotalBytes());
461 setObjectCount(stats.getTotalObjects());
462 setDeltaCount(stats.getTotalDeltas());
463 return this;
464 }
465
466
467
468
469
470
471 public ReftableWriter.Stats getReftableStats() {
472 return refStats;
473 }
474
475 void setReftableStats(ReftableWriter.Stats stats) {
476 this.refStats = stats;
477 setMinUpdateIndex(stats.minUpdateIndex());
478 setMaxUpdateIndex(stats.maxUpdateIndex());
479 setFileSize(REFTABLE, stats.totalBytes());
480 setBlockSize(REFTABLE, stats.refBlockSize());
481 }
482
483
484
485
486
487
488 public DfsPackDescription clearPackStats() {
489 packStats = null;
490 refStats = null;
491 return this;
492 }
493
494
495
496
497
498
499 public int getIndexVersion() {
500 return indexVersion;
501 }
502
503
504
505
506
507
508
509
510 public DfsPackDescription setIndexVersion(int version) {
511 indexVersion = version;
512 return this;
513 }
514
515
516 @Override
517 public int hashCode() {
518 return packName.hashCode();
519 }
520
521
522 @Override
523 public boolean equals(Object b) {
524 if (b instanceof DfsPackDescription) {
525 DfsPackDescription desc = (DfsPackDescription) b;
526 return packName.equals(desc.packName) &&
527 getRepositoryDescription().equals(desc.getRepositoryDescription());
528 }
529 return false;
530 }
531
532 static boolean isGC(PackSource s) {
533 switch (s) {
534 case GC:
535 case GC_REST:
536 case GC_TXN:
537 return true;
538 default:
539 return false;
540 }
541 }
542
543
544 @Override
545 public String toString() {
546 return getFileName(PackExt.PACK);
547 }
548 }