1
2
3
4
5
6
7
8
9
10
11
12 package org.eclipse.jgit.revwalk;
13
14 import java.io.IOException;
15
16 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
17 import org.eclipse.jgit.errors.MissingObjectException;
18 import org.eclipse.jgit.errors.StopWalkException;
19 import org.eclipse.jgit.lib.ObjectId;
20 import org.eclipse.jgit.revwalk.filter.RevFilter;
21
22
23
24
25
26
27
28
29
30
31 class PendingGenerator extends Generator {
32 private static final int PARSED = RevWalk.PARSED;
33
34 private static final int SEEN = RevWalk.SEEN;
35
36 private static final int UNINTERESTING = RevWalk.UNINTERESTING;
37
38
39
40
41
42
43
44
45
46 static final int OVER_SCAN = 5 + 1;
47
48
49 private static final RevCommit INIT_LAST;
50
51 static {
52 INIT_LAST = new RevCommit(ObjectId.zeroId());
53 INIT_LAST.commitTime = Integer.MAX_VALUE;
54 }
55
56 private final RevWalk walker;
57
58 private final DateRevQueue pending;
59
60 private final RevFilter filter;
61
62 private final int output;
63
64
65 private RevCommit last = INIT_LAST;
66
67
68
69
70
71
72
73 private int overScan = OVER_SCAN;
74
75 boolean canDispose;
76
77 PendingGenerator(final RevWalk w, final DateRevQueue p,
78 final RevFilter f, final int out) {
79 super(w.isFirstParent());
80 walker = w;
81 pending = p;
82 filter = f;
83 output = out;
84 canDispose = true;
85 }
86
87 @Override
88 int outputType() {
89 return output | SORT_COMMIT_TIME_DESC;
90 }
91
92 @Override
93 RevCommit next() throws MissingObjectException,
94 IncorrectObjectTypeException, IOException {
95 try {
96 for (;;) {
97 final RevCommit c = pending.next();
98 if (c == null) {
99 return null;
100 }
101
102 final boolean produce;
103 if ((c.flags & UNINTERESTING) != 0)
104 produce = false;
105 else {
106 if (filter.requiresCommitBody())
107 c.parseBody(walker);
108 produce = filter.include(walker, c);
109 }
110
111 for (int i = 0; i < c.parents.length; i++) {
112 RevCommit p = c.parents[i];
113
114
115 if (firstParent && i > 0 && (c.flags & UNINTERESTING) == 0) {
116 continue;
117 }
118 if ((p.flags & SEEN) != 0)
119 continue;
120 if ((p.flags & PARSED) == 0)
121 p.parseHeaders(walker);
122 p.flags |= SEEN;
123 pending.add(p);
124 }
125 walker.carryFlagsImpl(c);
126
127 if ((c.flags & UNINTERESTING) != 0) {
128 if (pending.everbodyHasFlag(UNINTERESTING)) {
129 final RevCommit n = pending.peek();
130 if (n != null && n.commitTime >= last.commitTime) {
131
132
133
134
135
136 overScan = OVER_SCAN;
137 } else if (--overScan == 0)
138 throw StopWalkException.INSTANCE;
139 } else {
140 overScan = OVER_SCAN;
141 }
142 if (canDispose)
143 c.disposeBody();
144 continue;
145 }
146
147 if (produce)
148 return last = c;
149 else if (canDispose)
150 c.disposeBody();
151 }
152 } catch (StopWalkException swe) {
153 pending.clear();
154 return null;
155 }
156 }
157 }