1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.internal.storage.pack;
12
13
14
15
16 class DeltaIndexScanner {
17 final int[] table;
18
19
20
21
22
23 final long[] entries;
24
25 final int[] next;
26
27 final int tableMask;
28
29 private int entryCnt;
30
31 DeltaIndexScanner(byte[] raw, int len) {
32
33
34
35 len -= (len % DeltaIndex.BLKSZ);
36
37 final int worstCaseBlockCnt = len / DeltaIndex.BLKSZ;
38 if (worstCaseBlockCnt < 1) {
39 table = new int[] {};
40 tableMask = 0;
41
42 entries = new long[] {};
43 next = new int[] {};
44
45 } else {
46 table = new int[tableSize(worstCaseBlockCnt)];
47 tableMask = table.length - 1;
48
49
50
51
52 entries = new long[1 + worstCaseBlockCnt];
53 next = new int[entries.length];
54
55 scan(raw, len);
56 }
57 }
58
59 private void scan(byte[] raw, int end) {
60
61
62
63
64
65 int lastHash = 0;
66 int ptr = end - DeltaIndex.BLKSZ;
67 do {
68 final int key = DeltaIndex.hashBlock(raw, ptr);
69 final int tIdx = key & tableMask;
70
71 final int head = table[tIdx];
72 if (head != 0 && lastHash == key) {
73
74
75
76
77 entries[head] = (((long) key) << 32) | ptr;
78 } else {
79 final int eIdx = ++entryCnt;
80 entries[eIdx] = (((long) key) << 32) | ptr;
81 next[eIdx] = head;
82 table[tIdx] = eIdx;
83 }
84
85 lastHash = key;
86 ptr -= DeltaIndex.BLKSZ;
87 } while (0 <= ptr);
88 }
89
90 private static int tableSize(int worstCaseBlockCnt) {
91 int shift = 32 - Integer.numberOfLeadingZeros(worstCaseBlockCnt);
92 int sz = 1 << (shift - 1);
93 if (sz < worstCaseBlockCnt)
94 sz <<= 1;
95 return sz;
96 }
97 }