Skip to content

Commit 5e1c9da

Browse files
committed
Introduced MovableBidirectionalIterator
This is a memory optimization for the case when a user required to modify iterator by moving it to a desire position. This works the same way as `iteraotr(fromElement)` but doesn't create a new iterator that decreases memory footprint at an algorithms which makes a lot of jumps. So, user simple calls `move(fromElement)`. It also introduces `begin()` which moves iterator to the first position, and `end()` which moves iterator to the last element.
1 parent 9361932 commit 5e1c9da

19 files changed

+852
-79
lines changed

drv/AVLTreeMap.drv

+78-13
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package PACKAGE;
1818

1919
#if ! KEYS_REFERENCE
2020
import it.unimi.dsi.fastutil.objects.AbstractObjectSortedSet;
21-
import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator;
21+
import it.unimi.dsi.fastutil.objects.ObjectMovableBidirectionalIterator;
2222
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
2323
import it.unimi.dsi.fastutil.objects.ObjectSortedSet;
2424
#endif
@@ -1185,6 +1185,30 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
11851185
while(i-- != 0 && hasPrevious()) previousEntry();
11861186
return n - i - 1;
11871187
}
1188+
1189+
public void moveKey(final KEY_GENERIC_TYPE fromElement) {
1190+
prev = null;
1191+
curr = prev;
1192+
if ((next = locateKey(fromElement)) != null) {
1193+
if (compare(next.key, fromElement) <= 0) {
1194+
prev = next;
1195+
next = next.next();
1196+
}
1197+
else prev = next.prev();
1198+
}
1199+
}
1200+
1201+
public void beginKey() {
1202+
next = firstEntry;
1203+
prev = next.prev();
1204+
curr = prev;
1205+
}
1206+
1207+
public void endKey() {
1208+
next = lastEntry;
1209+
prev = next.prev();
1210+
curr = prev;
1211+
}
11881212
}
11891213

11901214

@@ -1193,7 +1217,7 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
11931217
* <p>This class can iterate in both directions on a threaded tree.
11941218
*/
11951219

1196-
private class EntryIterator extends TreeIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC> {
1220+
private class EntryIterator extends TreeIterator implements ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC>, ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC> {
11971221
EntryIterator() {}
11981222

11991223
EntryIterator(final KEY_GENERIC_TYPE k) {
@@ -1211,6 +1235,15 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
12111235

12121236
@Override
12131237
public void add(MAP.Entry KEY_VALUE_GENERIC ok) { throw new UnsupportedOperationException(); }
1238+
1239+
@Override
1240+
public void move(final MAP.Entry KEY_VALUE_GENERIC fromElement) { moveKey(fromElement.ENTRY_GET_KEY()); }
1241+
1242+
@Override
1243+
public void begin() { beginKey(); }
1244+
1245+
@Override
1246+
public void end() { endKey(); }
12141247
}
12151248

12161249

@@ -1227,10 +1260,10 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
12271260
public Comparator<? super MAP.Entry KEY_VALUE_GENERIC> comparator() { return comparator; }
12281261

12291262
@Override
1230-
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() { return new EntryIterator(); }
1263+
public ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() { return new EntryIterator(); }
12311264

12321265
@Override
1233-
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator(final MAP.Entry KEY_VALUE_GENERIC from) { return new EntryIterator(from.ENTRY_GET_KEY()); }
1266+
public ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator(final MAP.Entry KEY_VALUE_GENERIC from) { return new EntryIterator(from.ENTRY_GET_KEY()); }
12341267

12351268
@Override
12361269
SUPPRESS_WARNINGS_KEY_UNCHECKED
@@ -1297,21 +1330,27 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
12971330
* simply override the {@link java.util.ListIterator#next()}/{@link java.util.ListIterator#previous()} methods (and possibly
12981331
* their type-specific counterparts) so that they return keys instead of entries.
12991332
*/
1300-
private final class KeyIterator extends TreeIterator implements KEY_LIST_ITERATOR KEY_GENERIC {
1333+
private final class KeyIterator extends TreeIterator implements KEY_MOVE_BIDI_ITERATOR KEY_GENERIC, KEY_LIST_ITERATOR KEY_GENERIC {
13011334
public KeyIterator() {}
13021335
public KeyIterator(final KEY_GENERIC_TYPE k) { super(k); }
13031336
@Override
13041337
public KEY_GENERIC_TYPE NEXT_KEY() { return nextEntry().key; }
13051338
@Override
13061339
public KEY_GENERIC_TYPE PREV_KEY() { return previousEntry().key; }
1340+
@Override
1341+
public void move(final KEY_GENERIC_TYPE fromElement) { moveKey(fromElement); }
1342+
@Override
1343+
public void begin() { beginKey(); }
1344+
@Override
1345+
public void end() { endKey(); }
13071346
}
13081347

13091348
/** A keyset implementation using a more direct implementation for iterators. */
13101349
private class KeySet extends ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC.KeySet {
13111350
@Override
1312-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new KeyIterator(); }
1351+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new KeyIterator(); }
13131352
@Override
1314-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new KeyIterator(from); }
1353+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new KeyIterator(from); }
13151354
}
13161355

13171356
/** Returns a type-specific sorted set view of the keys contained in this map.
@@ -1443,9 +1482,9 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
14431482
public ObjectSortedSet<MAP.Entry KEY_VALUE_GENERIC> ENTRYSET() {
14441483
if (entries == null) entries = new AbstractObjectSortedSet<MAP.Entry KEY_VALUE_GENERIC>() {
14451484
@Override
1446-
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() { return new SubmapEntryIterator(); }
1485+
public ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() { return new SubmapEntryIterator(); }
14471486
@Override
1448-
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator(final MAP.Entry KEY_VALUE_GENERIC from) { return new SubmapEntryIterator(from.ENTRY_GET_KEY()); }
1487+
public ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator(final MAP.Entry KEY_VALUE_GENERIC from) { return new SubmapEntryIterator(from.ENTRY_GET_KEY()); }
14491488
@Override
14501489
public Comparator<? super MAP.Entry KEY_VALUE_GENERIC> comparator() { return AVL_TREE_MAP.this.ENTRYSET().comparator(); }
14511490
@Override
@@ -1504,9 +1543,9 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
15041543

15051544
private class KeySet extends ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC.KeySet {
15061545
@Override
1507-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new SubmapKeyIterator(); }
1546+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new SubmapKeyIterator(); }
15081547
@Override
1509-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SubmapKeyIterator(from); }
1548+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SubmapKeyIterator(from); }
15101549
}
15111550

15121551
@Override
@@ -1706,16 +1745,36 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
17061745
next = next.next();
17071746
if (! top && next != null && AVL_TREE_MAP.this.compare(next.key, to) >= 0) next = null;
17081747
}
1748+
1749+
@Override
1750+
public void beginKey() {
1751+
next = firstEntry();
1752+
prev = next.prev();
1753+
curr = prev;
1754+
}
1755+
1756+
@Override
1757+
public void endKey() {
1758+
next = lastEntry();
1759+
prev = next.prev();
1760+
curr = prev;
1761+
}
17091762
}
17101763

1711-
private class SubmapEntryIterator extends SubmapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC> {
1764+
private class SubmapEntryIterator extends SubmapIterator implements ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC>, ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC> {
17121765
SubmapEntryIterator() {}
17131766
SubmapEntryIterator(final KEY_GENERIC_TYPE k) { super(k); }
17141767

17151768
@Override
17161769
public MAP.Entry KEY_VALUE_GENERIC next() { return nextEntry(); }
17171770
@Override
17181771
public MAP.Entry KEY_VALUE_GENERIC previous() { return previousEntry(); }
1772+
@Override
1773+
public void move(final MAP.Entry KEY_VALUE_GENERIC from) { moveKey(from.ENTRY_GET_KEY()); }
1774+
@Override
1775+
public void begin() { beginKey(); }
1776+
@Override
1777+
public void end() { endKey(); }
17191778
}
17201779

17211780

@@ -1727,14 +1786,20 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
17271786
* type-specific counterparts) so that they return keys instead of
17281787
* entries.
17291788
*/
1730-
private final class SubmapKeyIterator extends SubmapIterator implements KEY_LIST_ITERATOR KEY_GENERIC {
1789+
private final class SubmapKeyIterator extends SubmapIterator implements KEY_MOVE_BIDI_ITERATOR KEY_GENERIC, KEY_LIST_ITERATOR KEY_GENERIC {
17311790
public SubmapKeyIterator() { super(); }
17321791
public SubmapKeyIterator(KEY_GENERIC_TYPE from) { super(from); }
17331792

17341793
@Override
17351794
public KEY_GENERIC_TYPE NEXT_KEY() { return nextEntry().key; }
17361795
@Override
17371796
public KEY_GENERIC_TYPE PREV_KEY() { return previousEntry().key; }
1797+
@Override
1798+
public void move(final KEY_GENERIC_TYPE from) { moveKey(from); }
1799+
@Override
1800+
public void begin() { beginKey(); }
1801+
@Override
1802+
public void end() { endKey(); }
17381803
};
17391804

17401805
/** An iterator on a subrange of values.

drv/AVLTreeSet.drv

+67-5
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ public class AVL_TREE_SET KEY_GENERIC extends ABSTRACT_SORTED_SET KEY_GENERIC im
10551055
* <p>This class can iterate in both directions on a threaded tree.
10561056
*/
10571057

1058-
private class SetIterator implements KEY_LIST_ITERATOR KEY_GENERIC {
1058+
private class SetIterator implements KEY_MOVE_BIDI_ITERATOR KEY_GENERIC, KEY_LIST_ITERATOR KEY_GENERIC {
10591059
/** The entry that will be returned by the next call to {@link java.util.ListIterator#previous()} (or {@code null} if no previous entry exists). */
10601060
Entry KEY_GENERIC prev;
10611061
/** The entry that will be returned by the next call to {@link java.util.ListIterator#next()} (or {@code null} if no next entry exists). */
@@ -1127,13 +1127,40 @@ public class AVL_TREE_SET KEY_GENERIC extends ABSTRACT_SORTED_SET KEY_GENERIC im
11271127
AVL_TREE_SET.this.remove(curr.key);
11281128
curr = null;
11291129
}
1130+
1131+
@Override
1132+
public void move(final KEY_GENERIC_TYPE fromElement) {
1133+
prev = null;
1134+
curr = prev;
1135+
if ((next = locateKey(fromElement)) != null) {
1136+
if (compare(next.key, fromElement) <= 0) {
1137+
prev = next;
1138+
next = next.next();
1139+
}
1140+
else prev = next.prev();
1141+
}
1142+
}
1143+
1144+
@Override
1145+
public void begin() {
1146+
prev = null;
1147+
next = firstEntry;
1148+
curr = null;
1149+
}
1150+
1151+
@Override
1152+
public void end() {
1153+
next = lastEntry;
1154+
prev = next.prev();
1155+
curr = prev;
1156+
}
11301157
}
11311158

11321159
@Override
1133-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new SetIterator(); }
1160+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new SetIterator(); }
11341161

11351162
@Override
1136-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SetIterator(from); }
1163+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SetIterator(from); }
11371164

11381165
@Override
11391166
public KEY_COMPARATOR KEY_SUPER_GENERIC comparator() { return actualComparator; }
@@ -1241,10 +1268,10 @@ public class AVL_TREE_SET KEY_GENERIC extends ABSTRACT_SORTED_SET KEY_GENERIC im
12411268
public KEY_COMPARATOR KEY_SUPER_GENERIC comparator() { return actualComparator; }
12421269

12431270
@Override
1244-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new SubsetIterator(); }
1271+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new SubsetIterator(); }
12451272

12461273
@Override
1247-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SubsetIterator(from); }
1274+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SubsetIterator(from); }
12481275

12491276
@Override
12501277
public SORTED_SET KEY_GENERIC headSet(final KEY_GENERIC_TYPE to) {
@@ -1360,6 +1387,41 @@ public class AVL_TREE_SET KEY_GENERIC extends ABSTRACT_SORTED_SET KEY_GENERIC im
13601387
next = next.next();
13611388
if (! top && next != null && AVL_TREE_SET.this.compare(next.key, to) >= 0) next = null;
13621389
}
1390+
1391+
@Override
1392+
public void move(final KEY_GENERIC_TYPE fromElement) {
1393+
prev = null;
1394+
curr = prev;
1395+
next = firstEntry();
1396+
1397+
if (next != null) {
1398+
if (! bottom && compare(fromElement, next.key) < 0) prev = null;
1399+
else if (! top && compare(fromElement, (prev = lastEntry()).key) >= 0) next = null;
1400+
else {
1401+
next = locateKey(fromElement);
1402+
1403+
if (compare(next.key, fromElement) <= 0) {
1404+
prev = next;
1405+
next = next.next();
1406+
}
1407+
else prev = next.prev();
1408+
}
1409+
}
1410+
}
1411+
1412+
@Override
1413+
public void begin() {
1414+
prev = null;
1415+
next = firstEntry();
1416+
curr = null;
1417+
}
1418+
1419+
@Override
1420+
public void end() {
1421+
next = lastEntry();
1422+
prev = next.prev();
1423+
curr = prev;
1424+
}
13631425
}
13641426
}
13651427

drv/AbstractSortedMap.drv

+17-8
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import VALUE_PACKAGE.VALUE_ITERATOR;
2626
#if KEYS_REFERENCE
2727
import java.util.Comparator;
2828
#else
29-
import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator;
29+
import it.unimi.dsi.fastutil.objects.ObjectMovableBidirectionalIterator;
3030
#endif
3131

3232
/** An abstract class providing basic methods for sorted maps implementing a type-specific interface. */
@@ -84,10 +84,10 @@ public abstract class ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP
8484
public SORTED_SET KEY_GENERIC subSet(final KEY_GENERIC_TYPE from, final KEY_GENERIC_TYPE to) { return subMap(from, to).keySet(); }
8585

8686
@Override
87-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new KeySetIterator KEY_VALUE_GENERIC_DIAMOND(ENTRYSET().iterator(new BasicEntry KEY_VALUE_GENERIC_DIAMOND(from, VALUE_NULL))); }
87+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new KeySetIterator KEY_VALUE_GENERIC_DIAMOND(ENTRYSET().iterator(new BasicEntry KEY_VALUE_GENERIC_DIAMOND(from, VALUE_NULL))); }
8888

8989
@Override
90-
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new KeySetIterator KEY_VALUE_GENERIC_DIAMOND(SORTED_MAPS.fastIterator(ABSTRACT_SORTED_MAP.this)); }
90+
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new KeySetIterator KEY_VALUE_GENERIC_DIAMOND(SORTED_MAPS.fastIterator(ABSTRACT_SORTED_MAP.this)); }
9191
}
9292

9393
/** A wrapper exhibiting a map iterator as an iterator on keys.
@@ -96,10 +96,10 @@ public abstract class ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP
9696
* class using the corresponding iterator on entries.
9797
*/
9898

99-
protected static class KeySetIterator KEY_VALUE_GENERIC implements KEY_BIDI_ITERATOR KEY_GENERIC {
100-
protected final ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i;
99+
protected static class KeySetIterator KEY_VALUE_GENERIC implements KEY_MOVE_BIDI_ITERATOR KEY_GENERIC {
100+
protected final ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i;
101101

102-
public KeySetIterator(ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i) {
102+
public KeySetIterator(ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i) {
103103
this.i = i;
104104
}
105105

@@ -114,6 +114,15 @@ public abstract class ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP
114114

115115
@Override
116116
public boolean hasPrevious() { return i.hasPrevious(); }
117+
118+
@Override
119+
public void move(final KEY_GENERIC_TYPE fromElement) { i.move(new BasicEntry KEY_VALUE_GENERIC_DIAMOND(fromElement, VALUE_NULL)); }
120+
121+
@Override
122+
public void begin() { i.begin(); }
123+
124+
@Override
125+
public void end() { i.end(); }
117126
}
118127

119128
/** {@inheritDoc}
@@ -154,9 +163,9 @@ public abstract class ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP
154163
*/
155164

156165
protected static class ValuesIterator KEY_VALUE_GENERIC implements VALUE_ITERATOR VALUE_GENERIC {
157-
protected final ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i;
166+
protected final ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i;
158167

159-
public ValuesIterator(ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i) {
168+
public ValuesIterator(ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i) {
160169
this.i = i;
161170
}
162171

drv/AbstractSortedSet.drv

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,8 @@ public abstract class ABSTRACT_SORTED_SET KEY_GENERIC extends ABSTRACT_SET KEY_G
2424
protected ABSTRACT_SORTED_SET() {}
2525

2626
@Override
27-
public abstract KEY_BIDI_ITERATOR KEY_GENERIC iterator();
27+
public abstract KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(KEY_GENERIC_TYPE fromElement);
28+
29+
@Override
30+
public abstract KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator();
2831
}

0 commit comments

Comments
 (0)