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