Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduced MovableBidirectionalIterator #283

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 78 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,30 @@ 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) {
prev = null;
curr = prev;
if ((next = locateKey(fromElement)) != null) {
if (compare(next.key, fromElement) <= 0) {
prev = next;
next = next.next();
}
else prev = next.prev();
}
}

public void beginKey() {
next = firstEntry;
prev = next.prev();
curr = prev;
}

public void endKey() {
next = lastEntry;
prev = next.prev();
curr = prev;
}
}


Expand All @@ -1193,7 +1217,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 +1235,15 @@ 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 begin() { beginKey(); }

@Override
public void end() { endKey(); }
}


Expand All @@ -1227,10 +1260,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 +1330,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 begin() { beginKey(); }
@Override
public void end() { endKey(); }
}

/** 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 +1482,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 +1543,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 @@ -1706,16 +1745,36 @@ public class AVL_TREE_MAP KEY_VALUE_GENERIC extends ABSTRACT_SORTED_MAP KEY_VAL
next = next.next();
if (! top && next != null && AVL_TREE_MAP.this.compare(next.key, to) >= 0) next = null;
}

@Override
public void beginKey() {
next = firstEntry();
prev = next.prev();
curr = prev;
}

@Override
public void endKey() {
next = lastEntry();
prev = next.prev();
curr = prev;
}
}

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 begin() { beginKey(); }
@Override
public void end() { endKey(); }
}


Expand All @@ -1727,14 +1786,20 @@ 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 begin() { beginKey(); }
@Override
public void end() { endKey(); }
};

/** An iterator on a subrange of values.
Expand Down
72 changes: 67 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,40 @@ 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) {
prev = null;
curr = prev;
if ((next = locateKey(fromElement)) != null) {
if (compare(next.key, fromElement) <= 0) {
prev = next;
next = next.next();
}
else prev = next.prev();
}
}

@Override
public void begin() {
prev = null;
next = firstEntry;
curr = null;
}

@Override
public void end() {
next = lastEntry;
prev = next.prev();
curr = prev;
}
}

@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 +1268,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 +1387,41 @@ 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) {
prev = null;
curr = prev;
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 begin() {
prev = null;
next = firstEntry();
curr = null;
}

@Override
public void end() {
next = lastEntry();
prev = next.prev();
curr = prev;
}
}
}

Expand Down
25 changes: 17 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,15 @@ 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 begin() { i.begin(); }

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

/** {@inheritDoc}
Expand Down Expand Up @@ -154,9 +163,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);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So now what happens to people who implemented a subclass of IntAbstractSortedSet but are returning a standard bidirectional iterator?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I may move everything into KEY_BIDI_ITERATOR if you think it is safe.


@Override
public abstract KEY_MOVE_BIDI_ITERATOR KEY_GENERIC iterator();
}
Loading