Skip to content

Commit

Permalink
Introduced MovableBidirectionalIterator
Browse files Browse the repository at this point in the history
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 contains `rewind()` which moves iterator to the first position.
  • Loading branch information
catap committed Apr 15, 2023
1 parent 9361932 commit b7946c9
Show file tree
Hide file tree
Showing 22 changed files with 894 additions and 79 deletions.
63 changes: 50 additions & 13 deletions drv/AVLTreeMap.drv
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package PACKAGE;

#if ! KEYS_REFERENCE
import it.unimi.dsi.fastutil.objects.AbstractObjectSortedSet;
import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator;
import it.unimi.dsi.fastutil.objects.ObjectMovableBidirectionalIterator;
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
import it.unimi.dsi.fastutil.objects.ObjectSortedSet;
#endif
Expand Down Expand Up @@ -1185,6 +1185,23 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
while(i-- != 0 && hasPrevious()) previousEntry();
return n - i - 1;
}

public void moveKey(final KEY_GENERIC_TYPE fromElement) {
if ((next = locateKey(fromElement)) != null) {
if (compare(next.key, fromElement) <= 0) {
prev = next;
next = next.next();
}
else prev = next.prev();
}
}

public void rewindKey() {
prev = null;
next = firstEntry;
curr = null;
index = 0;
}
}


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

private class EntryIterator extends TreeIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC> {
private class EntryIterator extends TreeIterator implements ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC>, ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC> {
EntryIterator() {}

EntryIterator(final KEY_GENERIC_TYPE k) {
Expand All @@ -1211,6 +1228,12 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL

@Override
public void add(MAP.Entry KEY_VALUE_GENERIC ok) { throw new UnsupportedOperationException(); }

@Override
public void move(final MAP.Entry KEY_VALUE_GENERIC fromElement) { moveKey(fromElement.ENTRY_GET_KEY()); }

@Override
public void rewind() { rewindKey(); }
}


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

@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() { return new EntryIterator(); }
public ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() { return new EntryIterator(); }

@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator(final MAP.Entry KEY_VALUE_GENERIC from) { return new EntryIterator(from.ENTRY_GET_KEY()); }
public ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator(final MAP.Entry KEY_VALUE_GENERIC from) { return new EntryIterator(from.ENTRY_GET_KEY()); }

@Override
SUPPRESS_WARNINGS_KEY_UNCHECKED
Expand Down Expand Up @@ -1297,21 +1320,27 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
* simply override the {@link java.util.ListIterator#next()}/{@link java.util.ListIterator#previous()} methods (and possibly
* their type-specific counterparts) so that they return keys instead of entries.
*/
private final class KeyIterator extends TreeIterator implements KEY_LIST_ITERATOR KEY_GENERIC {
private final class KeyIterator extends TreeIterator implements KEY_MOVE_BIDI_ITERATOR KEY_GENERIC, KEY_LIST_ITERATOR KEY_GENERIC {
public KeyIterator() {}
public KeyIterator(final KEY_GENERIC_TYPE k) { super(k); }
@Override
public KEY_GENERIC_TYPE NEXT_KEY() { return nextEntry().key; }
@Override
public KEY_GENERIC_TYPE PREV_KEY() { return previousEntry().key; }

@Override
public void move(final KEY_GENERIC_TYPE fromElement) { moveKey(fromElement); }

@Override
public void rewind() { rewindKey(); }
}

/** A keyset implementation using a more direct implementation for iterators. */
private class KeySet extends ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC.KeySet {
@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new KeyIterator(); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new KeyIterator(); }
@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new KeyIterator(from); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new KeyIterator(from); }
}

/** Returns a type-specific sorted set view of the keys contained in this map.
Expand Down Expand Up @@ -1443,9 +1472,9 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
public ObjectSortedSet<MAP.Entry KEY_VALUE_GENERIC> ENTRYSET() {
if (entries == null) entries = new AbstractObjectSortedSet<MAP.Entry KEY_VALUE_GENERIC>() {
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() { return new SubmapEntryIterator(); }
public ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator() { return new SubmapEntryIterator(); }
@Override
public ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator(final MAP.Entry KEY_VALUE_GENERIC from) { return new SubmapEntryIterator(from.ENTRY_GET_KEY()); }
public ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> iterator(final MAP.Entry KEY_VALUE_GENERIC from) { return new SubmapEntryIterator(from.ENTRY_GET_KEY()); }
@Override
public Comparator<? super MAP.Entry KEY_VALUE_GENERIC> comparator() { return AVL_TREE_MAP.this.ENTRYSET().comparator(); }
@Override
Expand Down Expand Up @@ -1504,9 +1533,9 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL

private class KeySet extends ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC.KeySet {
@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new SubmapKeyIterator(); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new SubmapKeyIterator(); }
@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SubmapKeyIterator(from); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SubmapKeyIterator(from); }
}

@Override
Expand Down Expand Up @@ -1708,14 +1737,18 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
}
}

private class SubmapEntryIterator extends SubmapIterator implements ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC> {
private class SubmapEntryIterator extends SubmapIterator implements ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC>, ObjectListIterator<MAP.Entry KEY_VALUE_GENERIC> {
SubmapEntryIterator() {}
SubmapEntryIterator(final KEY_GENERIC_TYPE k) { super(k); }

@Override
public MAP.Entry KEY_VALUE_GENERIC next() { return nextEntry(); }
@Override
public MAP.Entry KEY_VALUE_GENERIC previous() { return previousEntry(); }
@Override
public void move(final MAP.Entry KEY_VALUE_GENERIC from) { moveKey(from.ENTRY_GET_KEY()); }
@Override
public void rewind() { rewindKey(); }
}


Expand All @@ -1727,14 +1760,18 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
* type-specific counterparts) so that they return keys instead of
* entries.
*/
private final class SubmapKeyIterator extends SubmapIterator implements KEY_LIST_ITERATOR KEY_GENERIC {
private final class SubmapKeyIterator extends SubmapIterator implements KEY_MOVE_BIDI_ITERATOR KEY_GENERIC, KEY_LIST_ITERATOR KEY_GENERIC {
public SubmapKeyIterator() { super(); }
public SubmapKeyIterator(KEY_GENERIC_TYPE from) { super(from); }

@Override
public KEY_GENERIC_TYPE NEXT_KEY() { return nextEntry().key; }
@Override
public KEY_GENERIC_TYPE PREV_KEY() { return previousEntry().key; }
@Override
public void move(final KEY_GENERIC_TYPE from) { moveKey(from); }
@Override
public void rewind() { rewindKey(); }
};

/** An iterator on a subrange of values.
Expand Down
56 changes: 51 additions & 5 deletions drv/AVLTreeSet.drv
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ public class AVL_TREE_SET KEY_GENERIC extends ABSTRACT_SORTED_SET KEY_GENERIC im
* <p>This class can iterate in both directions on a threaded tree.
*/

private class SetIterator implements KEY_LIST_ITERATOR KEY_GENERIC {
private class SetIterator implements KEY_MOVE_BIDI_ITERATOR KEY_GENERIC, KEY_LIST_ITERATOR KEY_GENERIC {
/** The entry that will be returned by the next call to {@link java.util.ListIterator#previous()} (or {@code null} if no previous entry exists). */
Entry KEY_GENERIC prev;
/** The entry that will be returned by the next call to {@link java.util.ListIterator#next()} (or {@code null} if no next entry exists). */
Expand Down Expand Up @@ -1127,13 +1127,32 @@ public class AVL_TREE_SET KEY_GENERIC extends ABSTRACT_SORTED_SET KEY_GENERIC im
AVL_TREE_SET.this.remove(curr.key);
curr = null;
}

@Override
public void move(final KEY_GENERIC_TYPE fromElement) {
if ((next = locateKey(fromElement)) != null) {
if (compare(next.key, fromElement) <= 0) {
prev = next;
next = next.next();
}
else prev = next.prev();
}
}

@Override
public void rewind() {
prev = null;
next = firstEntry;
curr = null;
index = 0;
}
}

@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new SetIterator(); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new SetIterator(); }

@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SetIterator(from); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SetIterator(from); }

@Override
public KEY_COMPARATOR KEY_SUPER_GENERIC comparator() { return actualComparator; }
Expand Down Expand Up @@ -1241,10 +1260,10 @@ public class AVL_TREE_SET KEY_GENERIC extends ABSTRACT_SORTED_SET KEY_GENERIC im
public KEY_COMPARATOR KEY_SUPER_GENERIC comparator() { return actualComparator; }

@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new SubsetIterator(); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new SubsetIterator(); }

@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SubsetIterator(from); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(final KEY_GENERIC_TYPE from) { return new SubsetIterator(from); }

@Override
public SORTED_SET KEY_GENERIC headSet(final KEY_GENERIC_TYPE to) {
Expand Down Expand Up @@ -1360,6 +1379,33 @@ public class AVL_TREE_SET KEY_GENERIC extends ABSTRACT_SORTED_SET KEY_GENERIC im
next = next.next();
if (! top && next != null && AVL_TREE_SET.this.compare(next.key, to) >= 0) next = null;
}

@Override
public void move(final KEY_GENERIC_TYPE fromElement) {
next = firstEntry();

if (next != null) {
if (! bottom && compare(fromElement, next.key) < 0) prev = null;
else if (! top && compare(fromElement, (prev = lastEntry()).key) >= 0) next = null;
else {
next = locateKey(fromElement);

if (compare(next.key, fromElement) <= 0) {
prev = next;
next = next.next();
}
else prev = next.prev();
}
}
}

@Override
public void rewind() {
prev = null;
next = firstEntry();
curr = null;
index = 0;
}
}
}

Expand Down
22 changes: 14 additions & 8 deletions drv/AbstractSortedMap.drv
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import VALUE_PACKAGE.VALUE_ITERATOR;
#if KEYS_REFERENCE
import java.util.Comparator;
#else
import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator;
import it.unimi.dsi.fastutil.objects.ObjectMovableBidirectionalIterator;
#endif

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

@Override
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))); }
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))); }

@Override
public KEY_BIDI_ITERATOR KEY_GENERIC iterator() { return new KeySetIterator KEY_VALUE_GENERIC_DIAMOND(SORTED_MAPS.fastIterator(ABSTRACT_SORTED_MAP.this)); }
public KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator() { return new KeySetIterator KEY_VALUE_GENERIC_DIAMOND(SORTED_MAPS.fastIterator(ABSTRACT_SORTED_MAP.this)); }
}

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

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

public KeySetIterator(ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i) {
public KeySetIterator(ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i) {
this.i = i;
}

Expand All @@ -114,6 +114,12 @@ public abstract class ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP

@Override
public boolean hasPrevious() { return i.hasPrevious(); }

@Override
public void move(final KEY_GENERIC_TYPE fromElement) { i.move(new BasicEntry KEY_VALUE_GENERIC_DIAMOND(fromElement, VALUE_NULL)); }

@Override
public void rewind() { i.rewind(); }
}

/** {@inheritDoc}
Expand Down Expand Up @@ -154,9 +160,9 @@ public abstract class ABSTRACT_SORTED_MAP KEY_VALUE_GENERIC extends ABSTRACT_MAP
*/

protected static class ValuesIterator KEY_VALUE_GENERIC implements VALUE_ITERATOR VALUE_GENERIC {
protected final ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i;
protected final ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i;

public ValuesIterator(ObjectBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i) {
public ValuesIterator(ObjectMovableBidirectionalIterator<MAP.Entry KEY_VALUE_GENERIC> i) {
this.i = i;
}

Expand Down
5 changes: 4 additions & 1 deletion drv/AbstractSortedSet.drv
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ public abstract class ABSTRACT_SORTED_SET KEY_GENERIC extends ABSTRACT_SET KEY_G
protected ABSTRACT_SORTED_SET() {}

@Override
public abstract KEY_BIDI_ITERATOR KEY_GENERIC iterator();
public abstract KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator(KEY_GENERIC_TYPE fromElement);

@Override
public abstract KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator();
}
54 changes: 54 additions & 0 deletions drv/Iterators.drv
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,60 @@ public final class ITERATORS {
public static KEY_GENERIC KEY_BIDI_ITERATOR KEY_GENERIC unmodifiable(final KEY_BIDI_ITERATOR KEY_EXTENDS_GENERIC i) { return new UnmodifiableBidirectionalIterator KEY_GENERIC_DIAMOND(i); }


/** An unmodifiable wrapper class for bidirectional iterators. */

public static class UnmodifiableMovableBidirectionalIterator KEY_GENERIC implements KEY_MOVE_BIDI_ITERATOR KEY_GENERIC {
protected final KEY_MOVE_BIDI_ITERATOR KEY_EXTENDS_GENERIC i;

public UnmodifiableMovableBidirectionalIterator(final KEY_MOVE_BIDI_ITERATOR KEY_EXTENDS_GENERIC i) {
this.i = i;
}

@Override
public boolean hasNext() { return i.hasNext(); }

@Override
public boolean hasPrevious() { return i.hasPrevious(); }

@Override
public KEY_GENERIC_TYPE NEXT_KEY() { return i.NEXT_KEY(); }

@Override
public KEY_GENERIC_TYPE PREV_KEY() { return i.PREV_KEY(); }

#if KEYS_PRIMITIVE
@Override
public void forEachRemaining(final METHOD_ARG_KEY_CONSUMER action) {
i.forEachRemaining(action);
}
#endif

DEPRECATED_IF_KEYS_PRIMITIVE
@Override
public void forEachRemaining(final Consumer<? super KEY_GENERIC_CLASS> action) {
i.forEachRemaining(action);
}

@Override
public void move(final KEY_GENERIC_TYPE fromElement) {
((KEY_MOVE_BIDI_ITERATOR KEY_GENERIC)i).move(fromElement);
}

@Override
public void rewind() {
i.rewind();
}
}


/** Returns an unmodifiable movable bidirectional iterator backed by the specified bidirectional iterator.
*
* @param i the bidirectional iterator to be wrapped in an unmodifiable bidirectional iterator.
* @return an unmodifiable view of the specified bidirectional iterator.
*/
public static KEY_GENERIC KEY_MOVE_BIDI_ITERATOR KEY_GENERIC unmodifiable(final KEY_MOVE_BIDI_ITERATOR KEY_EXTENDS_GENERIC i) { return new UnmodifiableMovableBidirectionalIterator KEY_GENERIC_DIAMOND(i); }


/** An unmodifiable wrapper class for list iterators. */

public static class UnmodifiableListIterator KEY_GENERIC implements KEY_LIST_ITERATOR KEY_GENERIC {
Expand Down
Loading

0 comments on commit b7946c9

Please sign in to comment.