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.pack;
45
46 import java.io.IOException;
47 import java.util.Set;
48
49 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
50 import org.eclipse.jgit.errors.MissingObjectException;
51 import org.eclipse.jgit.lib.BitmapIndex;
52 import org.eclipse.jgit.lib.BitmapIndex.Bitmap;
53 import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
54 import org.eclipse.jgit.lib.Constants;
55 import org.eclipse.jgit.lib.NullProgressMonitor;
56 import org.eclipse.jgit.lib.ObjectId;
57 import org.eclipse.jgit.lib.ProgressMonitor;
58 import org.eclipse.jgit.revwalk.ObjectWalk;
59 import org.eclipse.jgit.revwalk.RevCommit;
60 import org.eclipse.jgit.revwalk.RevFlag;
61 import org.eclipse.jgit.revwalk.RevObject;
62 import org.eclipse.jgit.revwalk.RevWalk;
63 import org.eclipse.jgit.revwalk.filter.RevFilter;
64
65
66 final class PackWriterBitmapWalker {
67
68 private final ObjectWalk walker;
69
70 private final BitmapIndex bitmapIndex;
71
72 private final ProgressMonitor pm;
73
74 private long countOfBitmapIndexMisses;
75
76 PackWriterBitmapWalker(
77 ObjectWalk walker, BitmapIndex bitmapIndex, ProgressMonitor pm) {
78 this.walker = walker;
79 this.bitmapIndex = bitmapIndex;
80 this.pm = (pm == null) ? NullProgressMonitor.INSTANCE : pm;
81 }
82
83 long getCountOfBitmapIndexMisses() {
84 return countOfBitmapIndexMisses;
85 }
86
87 BitmapBuilder findObjects(Set<? extends ObjectId> start, BitmapBuilder seen, boolean ignoreMissingStart)
88 throws MissingObjectException, IncorrectObjectTypeException,
89 IOException {
90 final BitmapBuilder bitmapResult = bitmapIndex.newBitmapBuilder();
91
92 for (ObjectId obj : start) {
93 Bitmap bitmap = bitmapIndex.getBitmap(obj);
94 if (bitmap != null)
95 bitmapResult.or(bitmap);
96 }
97
98 boolean marked = false;
99 for (ObjectId obj : start) {
100 try {
101 if (!bitmapResult.contains(obj)) {
102 walker.markStart(walker.parseAny(obj));
103 marked = true;
104 }
105 } catch (MissingObjectException e) {
106 if (ignoreMissingStart)
107 continue;
108 throw e;
109 }
110 }
111
112 if (marked) {
113 if (seen == null) {
114 walker.setRevFilter(new AddToBitmapFilter(bitmapResult));
115 } else {
116 walker.setRevFilter(
117 new AddUnseenToBitmapFilter(seen, bitmapResult));
118 }
119
120 while (walker.next() != null) {
121
122
123
124
125
126
127
128
129
130 pm.update(1);
131 countOfBitmapIndexMisses++;
132 }
133
134 RevObject ro;
135 while ((ro = walker.nextObject()) != null) {
136 bitmapResult.addObject(ro, ro.getType());
137 pm.update(1);
138 }
139 }
140
141 return bitmapResult;
142 }
143
144 void reset() {
145 walker.reset();
146 }
147
148
149
150
151
152
153
154
155
156
157
158 static class AddToBitmapFilter extends RevFilter {
159 private final BitmapBuilder bitmap;
160
161 AddToBitmapFilter(BitmapBuilder bitmap) {
162 this.bitmap = bitmap;
163 }
164
165 @Override
166 public final boolean include(RevWalk walker, RevCommit cmit) {
167 Bitmap visitedBitmap;
168
169 if (bitmap.contains(cmit)) {
170
171 } else if ((visitedBitmap = bitmap.getBitmapIndex()
172 .getBitmap(cmit)) != null) {
173 bitmap.or(visitedBitmap);
174 } else {
175 bitmap.addObject(cmit, Constants.OBJ_COMMIT);
176 return true;
177 }
178
179 for (RevCommit p : cmit.getParents()) {
180 p.add(RevFlag.SEEN);
181 }
182 return false;
183 }
184
185 @Override
186 public final RevFilter clone() {
187 throw new UnsupportedOperationException();
188 }
189
190 @Override
191 public final boolean requiresCommitBody() {
192 return false;
193 }
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 static class AddUnseenToBitmapFilter extends RevFilter {
211 private final BitmapBuilder seen;
212 private final BitmapBuilder bitmap;
213
214 AddUnseenToBitmapFilter(BitmapBuilder seen, BitmapBuilder bitmapResult) {
215 this.seen = seen;
216 this.bitmap = bitmapResult;
217 }
218
219 @Override
220 public final boolean include(RevWalk walker, RevCommit cmit) {
221 Bitmap visitedBitmap;
222
223 if (seen.contains(cmit) || bitmap.contains(cmit)) {
224
225 } else if ((visitedBitmap = bitmap.getBitmapIndex()
226 .getBitmap(cmit)) != null) {
227 bitmap.or(visitedBitmap);
228 } else {
229 bitmap.addObject(cmit, Constants.OBJ_COMMIT);
230 return true;
231 }
232
233 for (RevCommit p : cmit.getParents()) {
234 p.add(RevFlag.SEEN);
235 }
236 return false;
237 }
238
239 @Override
240 public final RevFilter clone() {
241 throw new UnsupportedOperationException();
242 }
243
244 @Override
245 public final boolean requiresCommitBody() {
246 return false;
247 }
248 }
249 }