Skip to content

Commit 0c99df9

Browse files
committed
MidxIterator: Add reset method
We need to iterate twice over the input collection while building the midx. We are creating a new iterator per iteration. This works fine until we add single-pack midx to the merge, because it requires the ctx (DfsReader) to create the iterator. Offer a reset method in the MidxIterator. Then we can reuse the iterator the two iterations, we do not need ctx and building the merger is easier. Change-Id: Iddfcfb304763de2997afd7e8b45a11996a6a6964
1 parent 40e6368 commit 0c99df9

File tree

5 files changed

+140
-22
lines changed

5 files changed

+140
-22
lines changed

org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/midx/MidxIteratorsTest.java

Lines changed: 93 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ public void fromPackIndexIterator_basicIteration() {
3131
PackIndex index1 = indexOf(object("000001", 500),
3232
object("000003", 3000), object("000005", 1500));
3333

34-
MidxIterator it = MidxIterators.fromPackIndexIterator("index1",
35-
index1.iterator());
34+
MidxIterator it = MidxIterators.fromPackIndexIterator("index1", index1);
3635
assertNextEntry(it, "000001", 0, 500);
3736
assertNextEntry(it, "000003", 0, 3000);
3837
assertNextEntry(it, "000005", 0, 1500);
@@ -44,8 +43,7 @@ public void fromPackIndexIterator_peek() {
4443
PackIndex index1 = indexOf(object("000001", 500),
4544
object("000003", 3000), object("000005", 1500));
4645

47-
MidxIterator it = MidxIterators.fromPackIndexIterator("index1",
48-
index1.iterator());
46+
MidxIterator it = MidxIterators.fromPackIndexIterator("index1", index1);
4947
assertPeekEntry(it, "000001", 0, 500);
5048
assertPeekEntry(it, "000001", 0, 500);
5149
assertNextEntry(it, "000001", 0, 500);
@@ -60,20 +58,35 @@ public void fromPackIndexIterator_peek() {
6058
assertFalse(it.hasNext());
6159
}
6260

61+
@Test
62+
public void fromPackIndexIterator_reset() {
63+
PackIndex index1 = indexOf(object("000001", 500),
64+
object("000003", 3000), object("000005", 1500));
65+
66+
MidxIterator it = MidxIterators.fromPackIndexIterator("index1", index1);
67+
while (it.hasNext()) {
68+
it.next();
69+
}
70+
it.reset();
71+
assertNextEntry(it, "000001", 0, 500);
72+
assertNextEntry(it, "000003", 0, 3000);
73+
74+
it.reset();
75+
assertPeekEntry(it, "000001", 0, 500);
76+
}
77+
6378
@Test
6479
public void fromPackIndexIterator_getPackNames() {
6580
PackIndex index1 = indexOf(object("000001", 500),
6681
object("000003", 1500), object("000005", 3000));
67-
MidxIterator it = MidxIterators.fromPackIndexIterator("index1",
68-
index1.iterator());
82+
MidxIterator it = MidxIterators.fromPackIndexIterator("index1", index1);
6983
assertEquals(List.of("index1"), it.getPackNames());
7084
}
7185

7286
@Test
7387
public void fromPackIndexIterator_empty() {
74-
PackIndex index1 = indexOf();
7588
MidxIterator it = MidxIterators.fromPackIndexIterator("index1",
76-
index1.iterator());
89+
indexOf());
7790
assertFalse(it.hasNext());
7891
}
7992

@@ -104,10 +117,8 @@ public void join_basicIteration_packIndexIterators() {
104117
object("000003", 1500), object("000004", 3000));
105118

106119
List<MidxIterator> packIts = List.of(
107-
MidxIterators.fromPackIndexIterator("index1",
108-
idxOne.iterator()),
109-
MidxIterators.fromPackIndexIterator("index2",
110-
idxTwo.iterator()));
120+
MidxIterators.fromPackIndexIterator("index1", idxOne),
121+
MidxIterators.fromPackIndexIterator("index2", idxTwo));
111122
MidxIterator it = MidxIterators.join(packIts);
112123
assertNextEntry(it, "000001", 0, 500);
113124
assertNextEntry(it, "000002", 1, 500);
@@ -165,6 +176,29 @@ public void join_peek() {
165176
assertFalse(it.hasNext());
166177
}
167178

179+
@Test
180+
public void join_reset() {
181+
FakeMidxIterator itOne = FakeMidxIterator.from("itOne", 2,
182+
List.of(new IndexEntry("000001", 0, 500),
183+
new IndexEntry("000003", 1, 1500)));
184+
185+
FakeMidxIterator itTwo = FakeMidxIterator.from("itTwo", 2,
186+
List.of(new IndexEntry("000002", 0, 500),
187+
new IndexEntry("000004", 1, 1500)));
188+
189+
MidxIterator it = MidxIterators.join(List.of(itOne, itTwo));
190+
while (it.hasNext()) {
191+
it.next();
192+
}
193+
194+
it.reset();
195+
assertNextEntry(it, "000001", 0, 500);
196+
assertNextEntry(it, "000002", 2, 500);
197+
198+
it.reset();
199+
assertPeekEntry(it, "000001", 0, 500);
200+
}
201+
168202
@Test
169203
public void join_getPackNames() {
170204
FakeMidxIterator itOne = FakeMidxIterator.from("itOne", 2,
@@ -236,6 +270,49 @@ public void dedup_peek() {
236270
assertFalse(it.hasNext());
237271
}
238272

273+
@Test
274+
public void dedup_reset() {
275+
FakeMidxIterator itOne = FakeMidxIterator.from("itOne", 2,
276+
List.of(new IndexEntry("000001", 0, 500),
277+
new IndexEntry("000001", 1, 600),
278+
new IndexEntry("000003", 0, 1500),
279+
new IndexEntry("000003", 1, 1501),
280+
new IndexEntry("000005", 0, 200),
281+
new IndexEntry("000005", 1, 201)));
282+
283+
MidxIterator it = MidxIterators.dedup(itOne);
284+
while (it.hasNext()) {
285+
it.next();
286+
}
287+
it.reset();
288+
assertNextEntry(it, "000001", 0, 500);
289+
assertNextEntry(it, "000003", 0, 1500);
290+
291+
it.reset();
292+
assertPeekEntry(it, "000001", 0, 500);
293+
}
294+
295+
@Test
296+
public void dedup_reset_sameElement() {
297+
FakeMidxIterator itOne = FakeMidxIterator.from("itOne", 2,
298+
List.of(new IndexEntry("000001", 0, 500),
299+
new IndexEntry("000001", 1, 600),
300+
new IndexEntry("000001", 2, 1500),
301+
new IndexEntry("000001", 3, 1501),
302+
new IndexEntry("000001", 4, 200),
303+
new IndexEntry("000001", 5, 201)));
304+
305+
MidxIterator it = MidxIterators.dedup(itOne);
306+
while (it.hasNext()) {
307+
it.next();
308+
}
309+
it.reset();
310+
assertNextEntry(it, "000001", 0, 500);
311+
312+
it.reset();
313+
assertPeekEntry(it, "000001", 0, 500);
314+
}
315+
239316
@Test
240317
public void dedup_getPackNames() {
241318
FakeMidxIterator itOne = FakeMidxIterator.from("itOne", 4,
@@ -322,6 +399,10 @@ public MultiPackIndex.MutableEntry next() {
322399
return entries.get(position++).asMutableEntry();
323400
}
324401

402+
@Override
403+
public void reset() {
404+
position = 0;
405+
}
325406
}
326407

327408
record IndexEntry(String shortOid, int packId, int offset) {

org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MidxIterators.java

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ public final class MidxIterators {
2929
*
3030
* @param packName
3131
* pack name this iterator is going over
32-
* @param idxIt
33-
* iterator over a PackIndex
32+
* @param idx
33+
* a PackIndex
3434
* @return a midx iterator that returns the objects of the pack index in the
3535
* original iterator order
3636
*/
3737
public static MidxIterator fromPackIndexIterator(String packName,
38-
Iterator<PackIndex.MutableEntry> idxIt) {
39-
return new MidxIteratorOverPackIndex(packName, idxIt);
38+
PackIndex idx) {
39+
return new MidxIteratorOverPackIndex(packName, idx);
4040
}
4141

4242
/**
@@ -80,17 +80,19 @@ private static class MidxIteratorOverPackIndex implements MidxIterator {
8080

8181
private final List<String> packNames;
8282

83-
private final Iterator<PackIndex.MutableEntry> idxIt;
83+
private final PackIndex idx;
84+
85+
private Iterator<PackIndex.MutableEntry> idxIt;
8486

8587
private boolean peeked;
8688

87-
private final MutableEntry entry;
89+
private final MutableEntry entry = new MutableEntry();
8890

8991
MidxIteratorOverPackIndex(String packName,
90-
Iterator<PackIndex.MutableEntry> idxIt) {
92+
PackIndex idx) {
9193
this.packNames = List.of(packName);
92-
this.idxIt = idxIt;
93-
this.entry = new MutableEntry();
94+
this.idx = idx;
95+
this.idxIt = idx.iterator();
9496
}
9597

9698
@Override
@@ -132,6 +134,13 @@ private void readNext() {
132134
idx.copyOidTo(entry.oid);
133135
entry.packOffset.setValues(0, idx.getOffset());
134136
}
137+
138+
@Override
139+
public void reset() {
140+
this.idxIt = idx.iterator();
141+
this.entry.clear();
142+
peeked = false;
143+
}
135144
}
136145

137146
private static class JoinMidxIterator implements MidxIterator {
@@ -205,6 +214,12 @@ private int best() {
205214

206215
return winnerPos;
207216
}
217+
218+
@Override
219+
public void reset() {
220+
indexIterators.stream().forEach(MidxIterator::reset);
221+
local.clear();
222+
}
208223
}
209224

210225
private static class DedupMidxIterator implements MidxIterator {
@@ -264,5 +279,12 @@ private void readNext() {
264279
}
265280
}
266281
}
282+
283+
@Override
284+
public void reset() {
285+
lastOid.clear();
286+
src.reset();
287+
readNext();
288+
}
267289
}
268290
}

org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndex.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ interface MidxIterator extends Iterator<MutableEntry> {
162162
* @return pack names
163163
*/
164164
List<String> getPackNames();
165+
166+
/**
167+
* Restart the iteration from the beginning
168+
*/
169+
void reset();
165170
}
166171

167172
/**
@@ -278,6 +283,11 @@ public long getOffset() {
278283
return packOffset.getOffset();
279284
}
280285

286+
public void clear() {
287+
oid.clear();
288+
packOffset.setValues(0, 0);
289+
}
290+
281291
@Override
282292
public String toString() {
283293
return String.format("%s,%s", oid.name(), packOffset);

org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/MultiPackIndexV1.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,11 @@ public MutableEntry peek() {
392392
public List<String> getPackNames() {
393393
return Arrays.asList(midx.getPackNames());
394394
}
395+
396+
@Override
397+
public void reset() {
398+
position = 0;
399+
}
395400
}
396401

397402
private static class ReverseIndex {

org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/midx/PackIndexMerger.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ int getPackCount() {
158158
MidxIterator bySha1Iterator() {
159159
List<MidxIterator> list = packs.entrySet().stream()
160160
.map(e -> MidxIterators.fromPackIndexIterator(e.getKey(),
161-
e.getValue().iterator()))
161+
e.getValue()))
162162
.toList();
163163
return MidxIterators.dedup(MidxIterators.join(list));
164164
}

0 commit comments

Comments
 (0)