diff --git a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/generic/util/datastruct/DynamicSortedTreeSet.java b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/generic/util/datastruct/DynamicSortedTreeSet.java index 460af003f3b..54a9ba55d15 100644 --- a/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/generic/util/datastruct/DynamicSortedTreeSet.java +++ b/Ghidra/Debug/ProposedUtils/src/main/java/ghidra/generic/util/datastruct/DynamicSortedTreeSet.java @@ -39,7 +39,7 @@ * * @param the type of the elements */ -public class DynamicSortedTreeSet extends AbstractSet implements List, Deque { +public class DynamicSortedTreeSet extends AbstractSet { private final transient TreeValueSortedMap.ValueSortedTreeMapKeySet keys; private final transient TreeValueSortedMap map; @@ -70,42 +70,6 @@ public boolean add(E e) { return map.put(e, e) == null; } - /** - * Inserts the element, ignoring index - * - * @param index ignore since the set is sorted - */ - @Override - public void add(int index, E element) { - add(element); - } - - /** - * Inserts all elements from the given collection, ignoring index - * - * @param index ignore since the set is sorted - */ - @Override - public boolean addAll(int index, Collection c) { - return addAll(c); - } - - /** - * Inserts the element, not necessarily first - */ - @Override - public void addFirst(E e) { - add(e); - } - - /** - * Inserts the element, not necessarily last - */ - @Override - public void addLast(E e) { - add(e); - } - @Override public void clear() { map.clear(); @@ -116,32 +80,10 @@ public boolean contains(Object o) { return map.containsKey(o); } - @Override - public Iterator descendingIterator() { - return keys.descendingIterator(); - } - - @Override - public E element() { - return keys.element(); - } - - @Override public E get(int index) { return keys.get(index); } - @Override - public E getFirst() { - return keys.getFirst(); - } - - @Override - public E getLast() { - return keys.getLast(); - } - - @Override public int indexOf(Object o) { return keys.indexOf(o); } @@ -156,92 +98,6 @@ public Iterator iterator() { return keys.iterator(); } - @Override - public int lastIndexOf(Object o) { - return keys.lastIndexOf(o); - } - - @Override - public ListIterator listIterator() { - return keys.listIterator(); - } - - @Override - public ListIterator listIterator(int index) { - return keys.listIterator(index); - } - - @Override - public boolean offer(E e) { - return add(e); - } - - /** - * Inserts the element, not necessarily first - */ - @Override - public boolean offerFirst(E e) { - return add(e); - } - - /** - * Inserts the element, not necessarily last - */ - @Override - public boolean offerLast(E e) { - return add(e); - } - - @Override - public E peek() { - return keys.peek(); - } - - @Override - public E peekFirst() { - return keys.peekFirst(); - } - - @Override - public E peekLast() { - return keys.peekLast(); - } - - @Override - public E poll() { - return keys.poll(); - } - - @Override - public E pollFirst() { - return keys.pollFirst(); - } - - @Override - public E pollLast() { - return keys.pollLast(); - } - - @Override - public E pop() { - return keys.pop(); - } - - @Override - public void push(E e) { - add(e); - } - - @Override - public E remove() { - return keys.remove(); - } - - @Override - public E remove(int index) { - return keys.remove(index); - } - @Override public boolean remove(Object o) { return keys.remove(o); @@ -252,46 +108,11 @@ public boolean removeAll(Collection c) { return keys.removeAll(c); } - @Override - public E removeFirst() { - return keys.removeFirst(); - } - - @Override - public boolean removeFirstOccurrence(Object o) { - return keys.removeFirstOccurrence(o); - } - - @Override - public E removeLast() { - return keys.removeLast(); - } - - @Override - public boolean removeLastOccurrence(Object o) { - return keys.removeLastOccurrence(o); - } - @Override public boolean retainAll(Collection c) { return keys.retainAll(c); } - /** - * Replace the element at the given index with the given element - * - *

- * Because the set is sorted, the index of the given element may not be the same as - * {@code index}. In fact, this is equivalent to removing the element at the given index, and - * then inserting the given element at its sorted position. - */ - @Override - public E set(int index, E element) { - E result = remove(index); - add(element); - return result; - } - @Override public int size() { return map.size(); @@ -302,14 +123,6 @@ public Spliterator spliterator() { return Spliterators.spliterator(this, Spliterator.ORDERED | Spliterator.DISTINCT); } - /** - * This operation is not supported - */ - @Override - public List subList(int fromIndex, int toIndex) { - throw new UnsupportedOperationException(); - } - /** * Notify the queue of a change to an element's cost. * diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/RestrictedValueSortedMap.java b/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/RestrictedValueSortedMap.java index e2ab0cf8a50..c38051dfff0 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/RestrictedValueSortedMap.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/RestrictedValueSortedMap.java @@ -15,10 +15,8 @@ */ package ghidra.generic.util.datastruct; -import java.lang.reflect.Array; import java.util.*; - -import ghidra.util.ReversedListIterator; +import java.util.Map.Entry; /** * A view of the value-sorted map for implementing @@ -251,6 +249,15 @@ public void add(V e) { * {@link RestrictedValueSortedMap} */ public class RestrictedValueSortedMapEntryList implements ValueSortedMapEntryList { + @Override + public List> toList() { + List> copy = new ArrayList<>(size()); + for (Entry ent : this) { + copy.add(ent); + } + return copy; + } + @Override public int size() { return restrictedSize(); @@ -280,77 +287,6 @@ public Iterator> iterator() { return new RestrictedEntryListIterator(); } - @Override - public Object[] toArray() { - Object[] result = new Object[size()]; - int i = 0; - for (Entry ent : this) { - result[i] = ent; - i++; - } - return result; - } - - @SuppressWarnings("unchecked") - @Override - public T[] toArray(T[] a) { - int size = size(); - if (a.length != size) { - a = (T[]) Array.newInstance(a.getClass().getComponentType(), size); - } - int i = 0; - for (Entry ent : this) { - a[i] = (T) ent; - i++; - } - return a; - } - - @Override - public boolean add(Entry e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsAll(Collection c) { - for (Object o : c) { - if (!contains(o)) { - return false; - } - } - return true; - } - - @Override - public boolean addAll(Collection> c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(int index, Collection> c) { - throw new UnsupportedOperationException(); - } - @Override public Entry get(int index) { if (index < 0) { @@ -363,189 +299,40 @@ public Entry get(int index) { return ent; } - @Override - public Entry set(int index, Entry element) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(int index, Entry element) { - throw new UnsupportedOperationException(); - } - - @Override - public Entry remove(int index) { - throw new UnsupportedOperationException(); - } - @Override public int indexOf(Object o) { return inBoundsOrNeg1(wrapped.entrySet().indexOf(o)); } - @Override - public int lastIndexOf(Object o) { - return inBoundsOrNeg1(wrapped.entrySet().lastIndexOf(o)); - } - - @Override - public ListIterator> listIterator() { - return new RestrictedEntryListIterator(); - } - @Override public ListIterator> listIterator(int index) { return new RestrictedEntryListIterator(index); } - @Override - public List> subList(int fromIndex, int toIndex) { - throw new UnsupportedOperationException(); - } - - @Override - public void addFirst(Entry e) { - throw new UnsupportedOperationException(); - } - - @Override - public void addLast(Entry e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offerFirst(Entry e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offerLast(Entry e) { - throw new UnsupportedOperationException(); - } - - @Override - public Entry removeFirst() { - throw new UnsupportedOperationException(); - } - - @Override - public Entry removeLast() { - throw new UnsupportedOperationException(); - } - - @Override - public Entry pollFirst() { - throw new UnsupportedOperationException(); - } - - @Override - public Entry pollLast() { - throw new UnsupportedOperationException(); - } - - @Override - public Entry getFirst() { - Entry ent = peekFirst(); - if (ent == null) { - throw new NoSuchElementException(); - } - return ent; - } - - @Override - public Entry getLast() { - Entry ent = peekLast(); - if (ent == null) { - throw new NoSuchElementException(); - } - return ent; - } - - @Override - public Entry peekFirst() { - Entry ent; - if (!hasFrom) { - ent = wrapped.entrySet().getFirst(); - } - else if (fromInclusive) { - ent = wrapped.ceilingEntryByValue(fromValue); - } - else { - ent = wrapped.higherEntryByValue(fromValue); - } - return inBoundsOrNull(ent); - } - - @Override - public Entry peekLast() { - Entry ent; - if (!hasTo) { - ent = wrapped.entrySet().getLast(); - } - else if (toInclusive) { - ent = wrapped.floorEntryByValue(toValue); - } - else { - ent = wrapped.lowerEntryByValue(toValue); - } - return inBoundsOrNull(ent); - } - - @Override - public boolean removeFirstOccurrence(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeLastOccurrence(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offer(Entry e) { - throw new UnsupportedOperationException(); - } - - @Override - public Entry remove() { - throw new UnsupportedOperationException(); - } - @Override public Entry poll() { throw new UnsupportedOperationException(); } @Override - public Entry element() { - return getFirst(); - } - - @Override - public Entry peek() { - return peekFirst(); - } - - @Override - public void push(Entry e) { - throw new UnsupportedOperationException(); - } - - @Override - public Entry pop() { + public boolean remove(Object o) { throw new UnsupportedOperationException(); } - - @Override - public Iterator> descendingIterator() { - return new ReversedListIterator<>(new RestrictedEntryListIterator(restrictedSize())); - } } /** * A list view suitable for {@link ValueSortedMap#keySet()} of {@link RestrictedValueSortedMap} */ public class RestrictedValueSortedMapKeyList implements ValueSortedMapKeyList { + @Override + public List toList() { + List copy = new ArrayList<>(size()); + for (K k : this) { + copy.add(k); + } + return copy; + } + @Override public int size() { return restrictedSize(); @@ -566,77 +353,6 @@ public Iterator iterator() { return new RestrictedKeyListIterator(); } - @Override - public Object[] toArray() { - Object[] result = new Object[size()]; - int i = 0; - for (K key : this) { - result[i] = key; - i++; - } - return result; - } - - @SuppressWarnings("unchecked") - @Override - public T[] toArray(T[] a) { - int size = size(); - if (a.length != size) { - a = (T[]) Array.newInstance(a.getClass().getComponentType(), size); - } - int i = 0; - for (K key : this) { - a[i] = (T) key; - i++; - } - return a; - } - - @Override - public boolean add(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsAll(Collection c) { - for (Object o : c) { - if (!contains(o)) { - return false; - } - } - return true; - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(int index, Collection c) { - throw new UnsupportedOperationException(); - } - @Override public K get(int index) { if (index < 0) { @@ -649,177 +365,40 @@ public K get(int index) { return ent.getKey(); } - @Override - public K set(int index, K element) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(int index, K element) { - throw new UnsupportedOperationException(); - } - - @Override - public K remove(int index) { - throw new UnsupportedOperationException(); - } - @Override public int indexOf(Object o) { return inBoundsOrNeg1(wrapped.keySet().indexOf(o)); } - @Override - public int lastIndexOf(Object o) { - return inBoundsOrNeg1(wrapped.keySet().lastIndexOf(o)); - } - - @Override - public ListIterator listIterator() { - return new RestrictedKeyListIterator(); - } - @Override public ListIterator listIterator(int index) { return new RestrictedKeyListIterator(index); } - @Override - public List subList(int fromIndex, int toIndex) { - throw new UnsupportedOperationException(); - } - - @Override - public void addFirst(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public void addLast(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offerFirst(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offerLast(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public K removeFirst() { - throw new UnsupportedOperationException(); - } - - @Override - public K removeLast() { - throw new UnsupportedOperationException(); - } - - @Override - public K pollFirst() { - throw new UnsupportedOperationException(); - } - - @Override - public K pollLast() { - throw new UnsupportedOperationException(); - } - - @Override - public K getFirst() { - Entry ent = entrySet().peekFirst(); - if (ent == null) { - throw new NoSuchElementException(); - } - return ent.getKey(); - } - - @Override - public K getLast() { - Entry ent = entrySet().peekLast(); - if (ent == null) { - throw new NoSuchElementException(); - } - return ent.getKey(); - } - - @Override - public K peekFirst() { - Entry ent = entrySet().peekFirst(); - if (ent == null) { - return null; - } - return ent.getKey(); - } - - @Override - public K peekLast() { - Entry ent = entrySet().peekLast(); - if (ent == null) { - return null; - } - return ent.getKey(); - } - - @Override - public boolean removeFirstOccurrence(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeLastOccurrence(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offer(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public K remove() { - throw new UnsupportedOperationException(); - } - @Override public K poll() { throw new UnsupportedOperationException(); } @Override - public K element() { - return getFirst(); - } - - @Override - public K peek() { - return peekFirst(); - } - - @Override - public void push(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public K pop() { + public boolean remove(Object o) { throw new UnsupportedOperationException(); } - - @Override - public Iterator descendingIterator() { - return new ReversedListIterator<>(new RestrictedKeyListIterator(restrictedSize())); - } } /** * A list view suitable for {@link ValueSortedMap#values()} of {@link RestrictedValueSortedMap} */ public class RestrictedSortedList implements SortedList { + @Override + public List toList() { + List copy = new ArrayList<>(size()); + for (V v : this) { + copy.add(v); + } + return copy; + } + @Override public int size() { return restrictedSize(); @@ -840,77 +419,6 @@ public Iterator iterator() { return new RestrictedValueListIterator(); } - @Override - public Object[] toArray() { - Object[] result = new Object[size()]; - int i = 0; - for (V val : this) { - result[i] = val; - i++; - } - return result; - } - - @SuppressWarnings("unchecked") - @Override - public T[] toArray(T[] a) { - int size = size(); - if (a.length != size) { - a = (T[]) Array.newInstance(a.getClass().getComponentType(), size); - } - int i = 0; - for (V val : this) { - a[i] = (T) val; - i++; - } - return a; - } - - @Override - public boolean add(V e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean containsAll(Collection c) { - for (Object o : c) { - if (!contains(o)) { - return false; - } - } - return true; - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(int index, Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean removeAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean retainAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void clear() { - throw new UnsupportedOperationException(); - } - @Override public V get(int index) { if (index < 0) { @@ -923,43 +431,23 @@ public V get(int index) { return ent.getValue(); } - @Override - public V set(int index, V element) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(int index, V element) { - throw new UnsupportedOperationException(); - } - - @Override - public V remove(int index) { - throw new UnsupportedOperationException(); - } - @Override public int indexOf(Object o) { return inBoundsOrNeg1(wrapped.values().indexOf(o)); } @Override - public int lastIndexOf(Object o) { - return inBoundsOrNeg1(wrapped.values().lastIndexOf(o)); - } - - @Override - public ListIterator listIterator() { - return new RestrictedValueListIterator(); + public ListIterator listIterator(int index) { + return new RestrictedValueListIterator(index); } @Override - public ListIterator listIterator(int index) { - return new RestrictedValueListIterator(index); + public V poll() { + throw new UnsupportedOperationException(); } @Override - public List subList(int fromIndex, int toIndex) { + public boolean remove(Object o) { throw new UnsupportedOperationException(); } @@ -1155,11 +643,6 @@ public V remove(Object key) { throw new UnsupportedOperationException(); } - @Override - public void putAll(Map m) { - throw new UnsupportedOperationException(); - } - @Override public void clear() { throw new UnsupportedOperationException(); diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/SortedList.java b/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/SortedList.java index 3dd9e5bda34..d194ab394ea 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/SortedList.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/SortedList.java @@ -15,7 +15,7 @@ */ package ghidra.generic.util.datastruct; -import java.util.List; +import ghidra.generic.util.datastruct.ValueSortedMap.LesserList; /** * An interface for sorted lists @@ -28,7 +28,7 @@ * * @param the type of elements in this list */ -public interface SortedList extends List { +public interface SortedList extends LesserList { /** * Returns the greatest index in this list whose element is strictly less than the specified * element diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/TreeValueSortedMap.java b/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/TreeValueSortedMap.java index 60014d396e9..e13beb338de 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/TreeValueSortedMap.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/TreeValueSortedMap.java @@ -19,8 +19,6 @@ import org.apache.commons.collections4.comparators.ComparableComparator; -import ghidra.util.ReversedListIterator; - /** * A tree-based implementation of a value-sorted map * @@ -655,48 +653,17 @@ protected class ValueSortedTreeMapEntrySet extends AbstractSet> private ValueSortedTreeMapEntrySet() { } - /** - * Inserts (by copy) the entry into the owning map - */ @Override - public boolean add(Entry e) { - return put(e.getKey(), e.getValue()) == null; + public List> toList() { + return new ArrayList<>(this); } /** - * Inserts (by copy) the entry into the owning map, ignoring index - * - * @param index ignored since order is determined by the entry's value - */ - @Override - public void add(int index, Entry element) { - add(element); - } - - /** - * Inserts (by copy) all entries in the collection, ignoring index - * - * @param index ignored since order is determined by the entries' values - */ - @Override - public boolean addAll(int index, Collection> c) { - return addAll(c); - } - - /** - * Inserts (by copy) the entry at its sorted position, not necessarily first - */ - @Override - public void addFirst(Entry e) { - put(e.getKey(), e.getValue()); - } - - /** - * Inserts (by copy) the entry at its sorted position, not necessarily last + * Inserts (by copy) the entry into the owning map */ @Override - public void addLast(Entry e) { - put(e.getKey(), e.getValue()); + public boolean add(Entry e) { + return put(e.getKey(), e.getValue()) == null; } @Override @@ -720,39 +687,11 @@ public boolean contains(Object o) { } } - @Override - public Iterator> descendingIterator() { - return new ReversedListIterator<>(new EntryListIterator(tail.next)); // i.e., null - } - - @Override - public Entry element() { - return getFirst(); - } - @Override public Entry get(int index) { return root.getByIndex(index); } - @Override - public Entry getFirst() { - Entry ret = peekFirst(); - if (ret == null) { - throw new NoSuchElementException(); - } - return ret; - } - - @Override - public Entry getLast() { - Entry ret = peekLast(); - if (ret == null) { - throw new NoSuchElementException(); - } - return ret; - } - @Override public int indexOf(Object o) { if (o == null) { @@ -773,21 +712,6 @@ public boolean isEmpty() { return root == null; } - @Override - public Iterator> iterator() { - return listIterator(); - } - - @Override - public int lastIndexOf(Object o) { - return indexOf(o); - } - - @Override - public ListIterator> listIterator() { - return new EntryListIterator(head); - } - @Override public ListIterator> listIterator(int index) { if (root == null) { @@ -797,48 +721,12 @@ public ListIterator> listIterator(int index) { } @Override - public boolean offer(Entry e) { - return put(e.getKey(), e.getValue()) == null; - } - - /** - * Inserts (by copy) the entry at its sorted position, not necessarily first - */ - @Override - public boolean offerFirst(Entry e) { - return put(e.getKey(), e.getValue()) == null; - } - - /** - * Inserts (by copy) the entry at its sorted position, not necessarily last - */ - @Override - public boolean offerLast(Entry e) { - return put(e.getKey(), e.getValue()) == null; - } - - @Override - public Entry peek() { - return peekFirst(); - } - - @Override - public Entry peekFirst() { - return head; - } - - @Override - public Entry peekLast() { - return tail; + public Iterator> iterator() { + return new EntryListIterator(head); } @Override public Entry poll() { - return pollFirst(); - } - - @Override - public Entry pollFirst() { if (head == null) { return null; } @@ -848,40 +736,6 @@ public Entry pollFirst() { return result; } - @Override - public Entry pollLast() { - if (tail == null) { - return tail; - } - Node result = tail; - tail.remove(); - nodeMap.remove(result.key); - return result; - } - - @Override - public Entry pop() { - return removeFirst(); - } - - @Override - public void push(Entry e) { - put(e.getKey(), e.getValue()); - } - - @Override - public Entry remove() { - return removeFirst(); - } - - @Override - public Entry remove(int index) { - Node n = root.getByIndex(index); - n.remove(); - nodeMap.remove(n.key); - return n; - } - @Override public boolean remove(Object o) { try { @@ -905,60 +759,10 @@ public boolean remove(Object o) { } } - @Override - public Entry removeFirst() { - Entry ret = pollFirst(); - if (ret == null) { - throw new NoSuchElementException(); - } - return ret; - } - - @Override - public boolean removeFirstOccurrence(Object o) { - return remove(o); - } - - @Override - public Entry removeLast() { - Entry ret = pollLast(); - if (ret == null) { - throw new NoSuchElementException(); - } - return ret; - } - - @Override - public boolean removeLastOccurrence(Object o) { - return remove(o); - } - - /** - * Modify the entry (key and value) at index - * - * Because the map is sorted by value, the index of the given entry may not remain the same - * after it is modified. In fact, this is equivalent to removing the entry at the given - * index, and then inserting the given entry at its sorted position. - */ - @Override - public Entry set(int index, Entry element) { - Entry result = remove(index); - add(element); - return result; - } - @Override public int size() { return nodeMap.size(); } - - /** - * This operation is not supported - */ - @Override - public List> subList(int fromIndex, int toIndex) { - throw new UnsupportedOperationException(); - } } /** @@ -976,33 +780,8 @@ private ValueSortedTreeMapKeySet() { } @Override - public void add(int index, K element) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean add(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(int index, Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void addFirst(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public void addLast(K e) { - throw new UnsupportedOperationException(); + public List toList() { + return new ArrayList<>(this); } @Override @@ -1015,31 +794,11 @@ public boolean contains(Object o) { return nodeMap.containsKey(o); } - @Override - public Iterator descendingIterator() { - return new ReversedListIterator<>(new KeyListIterator(tail.next)); // i.e., null - } - - @Override - public K element() { - return getFirst(); - } - @Override public K get(int index) { return entrySet.get(index).getKey(); } - @Override - public K getFirst() { - return entrySet.getFirst().getKey(); - } - - @Override - public K getLast() { - return entrySet.getLast().getKey(); - } - @Override public int indexOf(Object o) { Node n = nodeMap.get(o); @@ -1054,149 +813,37 @@ public boolean isEmpty() { return root == null; } - @Override - public Iterator iterator() { - return listIterator(); - } - - @Override - public int lastIndexOf(Object o) { - return indexOf(o); - } - - @Override - public ListIterator listIterator() { - return new KeyListIterator(head); - } - @Override public ListIterator listIterator(int index) { - return new KeyListIterator(root.getByIndex(index)); - } - - @Override - public boolean offer(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offerFirst(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offerLast(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public K peek() { - return peekFirst(); - } - - @Override - public K peekFirst() { - Entry n = entrySet.peekFirst(); - if (n == null) { - return null; + if (root == null) { + return Collections.emptyListIterator(); } - return n.getKey(); + return new KeyListIterator(root.getByIndex(index)); } @Override - public K peekLast() { - Entry n = entrySet.peekLast(); - if (n == null) { - return null; - } - return n.getKey(); + public Iterator iterator() { + return new KeyListIterator(head); } @Override public K poll() { - return pollFirst(); - } - - @Override - public K pollFirst() { - Entry n = entrySet.pollFirst(); + Entry n = entrySet.poll(); if (n == null) { return null; } return n.getKey(); } - @Override - public K pollLast() { - Entry n = entrySet.pollLast(); - if (n == null) { - return null; - } - return n.getKey(); - } - - @Override - public K pop() { - return removeFirst(); - } - - @Override - public void push(K e) { - throw new UnsupportedOperationException(); - } - - @Override - public K remove() { - return removeFirst(); - } - - @Override - public K remove(int index) { - return entrySet.remove(index).getKey(); - } - @Override public boolean remove(Object o) { return TreeValueSortedMap.this.remove(o) != null; } - @Override - public K removeFirst() { - return entrySet.removeFirst().getKey(); - } - - @Override - public boolean removeFirstOccurrence(Object o) { - return TreeValueSortedMap.this.remove(o) != null; - } - - @Override - public K removeLast() { - return entrySet.removeLast().getKey(); - } - - @Override - public boolean removeLastOccurrence(Object o) { - return TreeValueSortedMap.this.remove(o) != null; - } - - @Override - public K set(int index, K element) { - throw new UnsupportedOperationException(); - } - @Override public int size() { return nodeMap.size(); } - - /** - * This operation is not supported - */ - @Override - public List subList(int fromIndex, int toIndex) { - throw new UnsupportedOperationException(); - } } /** @@ -1209,38 +856,13 @@ public List subList(int fromIndex, int toIndex) { * Generally, only the removal mutation methods are supported, all others are not supported. */ protected class ValueSortedTreeMapValues extends AbstractCollection - implements SortedList, Deque { + implements SortedList { private ValueSortedTreeMapValues() { } @Override - public void add(int index, V element) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean add(V e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(int index, Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public void addFirst(V e) { - throw new UnsupportedOperationException(); - } - - @Override - public void addLast(V e) { - throw new UnsupportedOperationException(); + public List toList() { + return new ArrayList<>(this); } @Override @@ -1260,31 +882,11 @@ public boolean contains(Object o) { } } - @Override - public Iterator descendingIterator() { - return new ReversedListIterator<>(new ValueListIterator(tail.next)); // i.e., null - } - - @Override - public V element() { - return getFirst(); - } - @Override public V get(int index) { return entrySet.get(index).getValue(); } - @Override - public V getFirst() { - return entrySet.getFirst().getValue(); - } - - @Override - public V getLast() { - return entrySet.getLast().getValue(); - } - @Override public int indexOf(Object o) { try { @@ -1345,130 +947,27 @@ public boolean isEmpty() { return root == null; } - @Override - public Iterator iterator() { - return listIterator(); - } - - @Override - public int lastIndexOf(Object o) { - try { - @SuppressWarnings("unchecked") - V val = (V) o; - Node n = root.searchValue(val, SearchMode.LAST); - if (n == null) { - return -1; - } - return n.computeIndex(); - } - catch (ClassCastException e) { - return -1; - } - } - - @Override - public ListIterator listIterator() { - return new ValueListIterator(head); - } - @Override public ListIterator listIterator(int index) { return new ValueListIterator(root.getByIndex(index)); } @Override - public boolean offer(V e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offerFirst(V e) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean offerLast(V e) { - throw new UnsupportedOperationException(); - } - - @Override - public V peek() { - return peekFirst(); - } - - @Override - public V peekFirst() { - Entry n = entrySet.peekFirst(); - if (n == null) { - return null; - } - return n.getValue(); - } - - @Override - public V peekLast() { - Entry n = entrySet.peekLast(); - if (n == null) { - return null; - } - return n.getValue(); + public Iterator iterator() { + return new ValueListIterator(head); } @Override public V poll() { - return pollFirst(); - } - - @Override - public V pollFirst() { - Entry n = entrySet.pollFirst(); - if (n == null) { - return null; - } - return n.getValue(); - } - - @Override - public V pollLast() { - Entry n = entrySet.pollLast(); + Entry n = entrySet.poll(); if (n == null) { return null; } return n.getValue(); } - @Override - public V pop() { - return removeFirst(); - } - - @Override - public void push(V e) { - throw new UnsupportedOperationException(); - } - - @Override - public V remove() { - return removeFirst(); - } - - @Override - public V remove(int index) { - return entrySet.remove(index).getValue(); - } - @Override public boolean remove(Object o) { - return removeFirstOccurrence(o); - } - - @Override - public V removeFirst() { - return entrySet.removeFirst().getValue(); - } - - @Override - public boolean removeFirstOccurrence(Object o) { try { @SuppressWarnings("unchecked") V val = (V) o; @@ -1485,46 +984,10 @@ public boolean removeFirstOccurrence(Object o) { } } - @Override - public V removeLast() { - return entrySet.removeLast().getValue(); - } - - @Override - public boolean removeLastOccurrence(Object o) { - try { - @SuppressWarnings("unchecked") - V val = (V) o; - Node n = root.searchValue(val, SearchMode.LAST); - if (n == null) { - return false; - } - n.remove(); - nodeMap.remove(n.key); - return true; - } - catch (ClassCastException e) { - return false; - } - } - - @Override - public V set(int index, V element) { - throw new UnsupportedOperationException(); - } - @Override public int size() { return nodeMap.size(); } - - /** - * This operation is not supported - */ - @Override - public List subList(int fromIndex, int toIndex) { - throw new UnsupportedOperationException(); - } } // The user-provided comparator diff --git a/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/ValueSortedMap.java b/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/ValueSortedMap.java index f44e13ffd5d..44a7e53fab9 100644 --- a/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/ValueSortedMap.java +++ b/Ghidra/Framework/Generic/src/main/java/ghidra/generic/util/datastruct/ValueSortedMap.java @@ -16,6 +16,7 @@ package ghidra.generic.util.datastruct; import java.util.*; +import java.util.Map.Entry; /** * A map that is sorted by value. @@ -24,34 +25,92 @@ * This is an extension of {@link Map} where entries are sorted by value, rather than by key. Such a * map may be useful as a priority queue where the cost of an entry may change over time. As such, * the collections returned by {@link #entrySet()}, {@link #keySet()}, and {@link #values()} all - * extend {@link Deque}. The order of the entries will be updated on any call to {@link Map#put(Object, Object)}, - * or a call to {@link Collection#add(Object)} on the entry set. Additionally, if the - * values are mutable objects, whose order may change, there is an {@link #update(Object)} method, - * which notifies the map that the given key may need to be repositioned. The associated collections - * also extend the {@link List} interface, providing fairly efficient implementations of - * {@link List#get(int)} and {@link List#indexOf(Object)}. Sequential access is best performed via - * {@link Collection#iterator()}, since this will use a linked list. + * extend {@link Deque}. The order of the entries will be updated on any call to + * {@link Map#put(Object, Object)}, or a call to {@link Collection#add(Object)} on the entry set. + * Additionally, if the values are mutable objects, whose order may change, there is an + * {@link #update(Object)} method, which notifies the map that the given key may need to be + * repositioned. The associated collections also extend the {@link List} interface, providing fairly + * efficient implementations of {@link List#get(int)} and {@link List#indexOf(Object)}. Sequential + * access is best performed via {@link Collection#iterator()}, since this will use a linked list. * * @param the type of the keys * @param the type of the values */ -public interface ValueSortedMap extends Map { - public interface ValueSortedMapEntryList - extends Set>, List>, Deque> { - @Override - default Spliterator> spliterator() { - return Spliterators.spliterator(this, Spliterator.ORDERED | Spliterator.DISTINCT); +public interface ValueSortedMap { + /** + * An interface with a subset of methods from {@link List}. + * + *

+ * We've opted to implement this instead of {@link List} so that newer JDKs do not impose new + * requirements on our implementations. + * + * @param the type of element + */ + public interface LesserList extends Iterable { + boolean isEmpty(); + + int size(); + + /** + * Get the element at the given index + * + * @param i the index + * @return the element + */ + E get(int i); + + /** + * Copy this to a new list + * + * @return the list + */ + List toList(); + + ListIterator listIterator(int index); + + /** + * Get the index of a given element + * + *

+ * Returns the index of the element, or -1 if not found + * + * @param o the object + * @return the index or -1 + */ + int indexOf(Object o); + + boolean contains(Object o); + + /** + * Get and remove the first element + * + * @return the first element, or null if empty + */ + E poll(); + + boolean remove(Object o); + + default boolean removeAll(Collection col) { + boolean result = false; + for (Object e : col) { + result |= remove(e); + } + return result; } } - public interface ValueSortedMapKeyList extends Set, List, Deque { - @Override - default Spliterator spliterator() { - return Spliterators.spliterator(this, Spliterator.ORDERED | Spliterator.DISTINCT); - } + public interface ValueSortedMapEntryList extends LesserList> { + } + + public interface ValueSortedMapKeyList extends LesserList { } - @Override + V put(K key, V value); + + V get(Object key); + + V remove(K key); + ValueSortedMapEntryList entrySet(); /** @@ -123,7 +182,6 @@ ValueSortedMap subMapByValue(V fromValue, boolean fromInclusive, V toValue */ ValueSortedMap tailMapByValue(V fromValue, boolean inclusive); - @Override ValueSortedMapKeyList keySet(); /** @@ -138,6 +196,15 @@ ValueSortedMap subMapByValue(V fromValue, boolean fromInclusive, V toValue */ boolean update(K key); - @Override SortedList values(); + + boolean isEmpty(); + + boolean containsKey(Object key); + + boolean containsValue(Object value); + + int size(); + + void clear(); } diff --git a/Ghidra/Framework/Generic/src/test/java/ghidra/generic/util/datastruct/TreeValueSortedMapTest.java b/Ghidra/Framework/Generic/src/test/java/ghidra/generic/util/datastruct/TreeValueSortedMapTest.java index de091290feb..4a7a7741564 100644 --- a/Ghidra/Framework/Generic/src/test/java/ghidra/generic/util/datastruct/TreeValueSortedMapTest.java +++ b/Ghidra/Framework/Generic/src/test/java/ghidra/generic/util/datastruct/TreeValueSortedMapTest.java @@ -24,9 +24,6 @@ import org.apache.commons.lang3.ArrayUtils; import org.junit.Test; -import ghidra.generic.util.datastruct.TreeValueSortedMap; -import ghidra.generic.util.datastruct.ValueSortedMap; - public class TreeValueSortedMapTest { @Test public void testNaturalOrder() { @@ -34,8 +31,8 @@ public void testNaturalOrder() { queue.put("2nd", 2); queue.put("1st", 1); queue.put("3rd", 3); - List ordered = new ArrayList<>(queue.keySet()); - assertEquals(Arrays.asList(new String[] { "1st", "2nd", "3rd" }), ordered); + List ordered = queue.keySet().toList(); + assertEquals(List.of("1st", "2nd", "3rd"), ordered); } @Test @@ -45,8 +42,8 @@ public void testExplicitOrdered() { queue.put("2nd", 2); queue.put("1st", 1); queue.put("3rd", 3); - List ordered = new ArrayList<>(queue.keySet()); - assertEquals(Arrays.asList(new String[] { "3rd", "2nd", "1st" }), ordered); + List ordered = queue.keySet().toList(); + assertEquals(List.of("3rd", "2nd", "1st"), ordered); } @Test @@ -256,27 +253,16 @@ public void testValueIndices() { } checkConsistent(queue); assertEquals(0, queue.values().indexOf(0)); - assertEquals(1, queue.values().lastIndexOf(0)); assertEquals(2, queue.values().indexOf(1)); - assertEquals(4, queue.values().lastIndexOf(1)); assertEquals(5, queue.values().indexOf(2)); - assertEquals(5, queue.values().lastIndexOf(2)); assertEquals(6, queue.values().indexOf(3)); - assertEquals(6, queue.values().lastIndexOf(3)); assertEquals(7, queue.values().indexOf(4)); - assertEquals(8, queue.values().lastIndexOf(4)); assertEquals(9, queue.values().indexOf(5)); - assertEquals(10, queue.values().lastIndexOf(5)); assertEquals(11, queue.values().indexOf(6)); - assertEquals(19, queue.values().lastIndexOf(6)); assertEquals(-1, queue.values().indexOf(7)); - assertEquals(-1, queue.values().lastIndexOf(7)); assertEquals(20, queue.values().indexOf(8)); - assertEquals(21, queue.values().lastIndexOf(8)); assertEquals(-1, queue.values().indexOf(9)); - assertEquals(-1, queue.values().lastIndexOf(9)); assertEquals(22, queue.values().indexOf(10)); - assertEquals(22, queue.values().lastIndexOf(10)); } }