1
2
3
4
5
6
7
8
9
10
11 package org.eclipse.jgit.revwalk;
12
13 import java.io.IOException;
14 import java.util.Arrays;
15
16 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
17 import org.eclipse.jgit.errors.MissingObjectException;
18 import org.eclipse.jgit.internal.revwalk.AddToBitmapFilter;
19 import org.eclipse.jgit.internal.revwalk.AddToBitmapWithCacheFilter;
20 import org.eclipse.jgit.internal.revwalk.AddUnseenToBitmapFilter;
21 import org.eclipse.jgit.lib.AnyObjectId;
22 import org.eclipse.jgit.lib.BitmapIndex;
23 import org.eclipse.jgit.lib.BitmapIndex.Bitmap;
24 import org.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
25 import org.eclipse.jgit.lib.NullProgressMonitor;
26 import org.eclipse.jgit.lib.ObjectId;
27 import org.eclipse.jgit.lib.ProgressMonitor;
28 import org.eclipse.jgit.revwalk.filter.ObjectFilter;
29
30
31
32
33
34
35 public final class BitmapWalker {
36
37 private final ObjectWalk walker;
38
39 private final BitmapIndex bitmapIndex;
40
41 private final ProgressMonitor pm;
42
43 private long countOfBitmapIndexMisses;
44
45
46 private AnyObjectId prevCommit;
47
48 private Bitmap prevBitmap;
49
50
51
52
53
54
55
56
57 public BitmapWalker(
58 ObjectWalk walker, BitmapIndex bitmapIndex, ProgressMonitor pm) {
59 this.walker = walker;
60 this.bitmapIndex = bitmapIndex;
61 this.pm = (pm == null) ? NullProgressMonitor.INSTANCE : pm;
62 }
63
64
65
66
67
68
69
70
71 public void setPrevCommit(AnyObjectId prevCommit) {
72 this.prevCommit = prevCommit;
73 }
74
75
76
77
78
79
80
81
82 public void setPrevBitmap(Bitmap prevBitmap) {
83 this.prevBitmap = prevBitmap;
84 }
85
86
87
88
89
90
91
92
93 public long getCountOfBitmapIndexMisses() {
94 return countOfBitmapIndexMisses;
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 public BitmapBuilder findObjects(Iterable<? extends ObjectId> start, BitmapBuilder seen,
124 boolean ignoreMissing)
125 throws MissingObjectException, IncorrectObjectTypeException,
126 IOException {
127 if (!ignoreMissing) {
128 return findObjectsWalk(start, seen, false);
129 }
130
131 try {
132 return findObjectsWalk(start, seen, true);
133 } catch (MissingObjectException ignore) {
134
135
136 }
137
138 final BitmapBuilder result = bitmapIndex.newBitmapBuilder();
139 for (ObjectId obj : start) {
140 Bitmap bitmap = bitmapIndex.getBitmap(obj);
141 if (bitmap != null) {
142 result.or(bitmap);
143 }
144 }
145
146 for (ObjectId obj : start) {
147 if (result.contains(obj)) {
148 continue;
149 }
150 try {
151 result.or(findObjectsWalk(Arrays.asList(obj), result, false));
152 } catch (MissingObjectException ignore) {
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 }
168 }
169 return result;
170 }
171
172 private BitmapBuilder findObjectsWalk(Iterable<? extends ObjectId> start, BitmapBuilder seen,
173 boolean ignoreMissingStart)
174 throws MissingObjectException, IncorrectObjectTypeException,
175 IOException {
176 walker.reset();
177 final BitmapBuilder bitmapResult = bitmapIndex.newBitmapBuilder();
178
179 for (ObjectId obj : start) {
180 Bitmap bitmap = bitmapIndex.getBitmap(obj);
181 if (bitmap != null)
182 bitmapResult.or(bitmap);
183 }
184
185 boolean marked = false;
186 for (ObjectId obj : start) {
187 try {
188 if (!bitmapResult.contains(obj)) {
189 walker.markStart(walker.parseAny(obj));
190 marked = true;
191 }
192 } catch (MissingObjectException e) {
193 if (ignoreMissingStart)
194 continue;
195 throw e;
196 }
197 }
198
199 if (marked) {
200 if (prevCommit != null) {
201 walker.setRevFilter(new AddToBitmapWithCacheFilter(prevCommit,
202 prevBitmap, bitmapResult));
203 } else if (seen == null) {
204 walker.setRevFilter(new AddToBitmapFilter(bitmapResult));
205 } else {
206 walker.setRevFilter(
207 new AddUnseenToBitmapFilter(seen, bitmapResult));
208 }
209 walker.setObjectFilter(new BitmapObjectFilter(bitmapResult));
210
211 while (walker.next() != null) {
212
213
214
215
216
217
218
219
220
221 pm.update(1);
222 countOfBitmapIndexMisses++;
223 }
224
225 RevObject ro;
226 while ((ro = walker.nextObject()) != null) {
227 bitmapResult.addObject(ro, ro.getType());
228 pm.update(1);
229 }
230 }
231
232 return bitmapResult;
233 }
234
235
236
237
238 static class BitmapObjectFilter extends ObjectFilter {
239 private final BitmapBuilder bitmap;
240
241 BitmapObjectFilter(BitmapBuilder bitmap) {
242 this.bitmap = bitmap;
243 }
244
245 @Override
246 public final boolean include(ObjectWalk walker, AnyObjectId objid)
247 throws MissingObjectException, IncorrectObjectTypeException,
248 IOException {
249 return !bitmap.contains(objid);
250 }
251 }
252 }