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