diff --git a/src/builder/java/speiger/src/builder/GlobalVariables.java b/src/builder/java/speiger/src/builder/GlobalVariables.java index 504db1d7..8fbfa4b5 100644 --- a/src/builder/java/speiger/src/builder/GlobalVariables.java +++ b/src/builder/java/speiger/src/builder/GlobalVariables.java @@ -284,6 +284,7 @@ public class GlobalVariables addFunctionValueMapper("MERGE", "merge"); addFunctionMapper("NEXT", "next"); addFunctionMapper("PREVIOUS", "previous"); + addFunctionMapper("REMOVE_SWAP", "swapRemove"); if(type.isObject()) addFunctionMapper("REMOVE_VALUE", "rem"); else addSimpleMapper("REMOVE_VALUE", "remove"); addFunctionMapper("REMOVE_KEY", "rem"); diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template b/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template index 5342873b..f0076c9e 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/AbstractList.template @@ -155,6 +155,14 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION } #endif + @Override + public boolean REMOVE_SWAP(KEY_TYPE e) { + int index = indexOf(e); + if(index == -1) return false; + swapRemove(index); + return true; + } + /** * Compares if the list are the same. */ @@ -347,8 +355,18 @@ public abstract class ABSTRACT_LIST KEY_GENERIC_TYPE extends ABSTRACT_COLLECTION @Override public KEY_TYPE REMOVE(int index) { checkRange(index); - size--; - return l.REMOVE(index + offset); + int temp = l.size(); + KEY_TYPE type = l.REMOVE(index + offset); + if(l.size() != temp) size--; + return type; + } + + public KEY_TYPE swapRemove(int index) { + checkRange(index); + int temp = l.size(); + KEY_TYPE type = l.swapRemove(index + offset); + if(l.size() != temp) size--; + return type; } @Override diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template b/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template index d25a53c8..3c8865c7 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/ArrayList.template @@ -760,6 +760,17 @@ public class ARRAY_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE return old; } + public KEY_TYPE swapRemove(int index) { + checkRange(index); + KEY_TYPE old = data[index]; + size--; + data[index] = data[size]; +#if TYPE_OBJECT + data[size] = null; +#endif + return old; + } + #if !TYPE_OBJECT /** * A Type-Specific implementation of remove. This implementation iterates over the elements until it finds the element that is searched for or it runs out of elements. diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/ImmutableList.template b/src/builder/resources/speiger/assets/collections/templates/lists/ImmutableList.template index 603b8178..cbf837b2 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/ImmutableList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/ImmutableList.template @@ -378,7 +378,8 @@ public class IMMUTABLE_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_T #endif @Override public KEY_TYPE REMOVE(int index) { throw new UnsupportedOperationException(); } - + @Override + public KEY_TYPE swapRemove(int index) { throw new UnsupportedOperationException(); } #if !TYPE_OBJECT @Override public boolean REMOVE_KEY(KEY_TYPE type) { throw new UnsupportedOperationException(); } diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/LinkedList.template b/src/builder/resources/speiger/assets/collections/templates/lists/LinkedList.template index 703a4c26..d3a4ca11 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/LinkedList.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/LinkedList.template @@ -569,6 +569,66 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE return false; } + @Override + public KEY_TYPE swapRemove(int index) { + checkRange(index); + Entry KEY_GENERIC_TYPE entry = getNode(index); + if(entry == null) return EMPTY_KEY_VALUE; + if(entry.next == null) return unlinkLast(entry); + Entry KEY_GENERIC_TYPE before = entry.prev; + KEY_TYPE result = unlink(entry); + if(before == null) { + Entry KEY_GENERIC_TYPE temp = last; + last = temp.prev; + last.next = null; + temp.next = first; + temp.prev = null; + first.prev = temp; + first = temp; + return result; + } + Entry KEY_GENERIC_TYPE temp = last; + last = temp.prev; + last.next = null; + temp.next = before.next; + temp.prev = before; + before.next = temp; + return result; + } + + @Override + public boolean REMOVE_SWAP(KEY_TYPE e) { + if(size == 0) return false; + for(Entry KEY_GENERIC_TYPE entry = last;entry.prev != null;entry = entry.prev) { + if(KEY_EQUALS(entry.value, e)) { + if(entry.next == null) { + unlinkLast(entry); + return true; + } + Entry KEY_GENERIC_TYPE before = entry.prev; + unlink(entry); + if(before == null) { + Entry KEY_GENERIC_TYPE temp = last; + last = temp.prev; + last.next = null; + temp.next = first; + temp.prev = null; + first.prev = temp; + first = temp; + return true; + } + Entry KEY_GENERIC_TYPE temp = last; + last = temp.prev; + last.next = null; + temp.next = before.next; + temp.prev = before; + before.next = temp; + return true; + } + } + return false; + } + #if TYPE_OBJECT @Override public boolean remove(Object e) { @@ -592,7 +652,8 @@ public class LINKED_LIST KEY_GENERIC_TYPE extends ABSTRACT_LIST KEY_GENERIC_TYPE @Override public KEY_TYPE REMOVE(int index) { checkRange(index); - return unlink(getNode(index)); + Entry KEY_GENERIC_TYPE entry = getNode(index); + return entry == null ? EMPTY_KEY_VALUE : unlink(entry); } @Override diff --git a/src/builder/resources/speiger/assets/collections/templates/lists/List.template b/src/builder/resources/speiger/assets/collections/templates/lists/List.template index 053ad1fb..026718b2 100644 --- a/src/builder/resources/speiger/assets/collections/templates/lists/List.template +++ b/src/builder/resources/speiger/assets/collections/templates/lists/List.template @@ -226,6 +226,22 @@ public interface LIST KEY_GENERIC_TYPE extends COLLECTION KEY_GENERIC_TYPE, List */ public void removeElements(int from, int to); + /** + * A Highly Optimized remove function that removes the desired element. + * But instead of shifting the elements to the left it moves the last element to the removed space. + * @param index the index of the element to be removed + * @return the element previously at the specified position + */ + public KEY_TYPE swapRemove(int index); + + /** + * A Highly Optimized remove function that removes the desired element. + * But instead of shifting the elements to the left it moves the last element to the removed space. + * @param e the element that should be removed + * @return true if the element was removed + */ + public boolean REMOVE_SWAP(KEY_TYPE e); + #if TYPE_OBJECT /** * A function to fast extract elements out of the list, this removes the elements that were fetched. diff --git a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template index 1690856a..a8f4eeaa 100644 --- a/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template +++ b/src/builder/resources/speiger/assets/collections/templates/utils/Lists.template @@ -200,6 +200,8 @@ public class LISTS @Override public KEY_TYPE REMOVE(int index) { throw new UnsupportedOperationException(); } @Override + public KEY_TYPE swapRemove(int index) { throw new UnsupportedOperationException(); } + @Override public void addElements(int from, KEY_TYPE[] a, int offset, int length) { throw new UnsupportedOperationException(); } @Override public KEY_TYPE[] getElements(int from, KEY_TYPE[] a, int offset, int length) { @@ -331,6 +333,12 @@ public class LISTS @Override public KEY_TYPE REMOVE(int index) { synchronized(mutex) { return l.REMOVE(index); } } + @Override + public KEY_TYPE swapRemove(int index) { synchronized(mutex) { return l.swapRemove(index); } } + + @Override + public boolean REMOVE_SWAP(KEY_TYPE e) { synchronized(mutex) { return l.REMOVE_SWAP(e); } } + @Override @Primitive public int indexOf(Object e) { synchronized(mutex) { return l.indexOf(e); } } @@ -444,6 +452,12 @@ public class LISTS @Override public KEY_TYPE REMOVE(int index) { throw new UnsupportedOperationException(); } + @Override + public KEY_TYPE swapRemove(int index) { throw new UnsupportedOperationException(); } + + @Override + public boolean REMOVE_SWAP(KEY_TYPE e) { throw new UnsupportedOperationException(); } + @Override @Primitive public int indexOf(Object e) { return l.indexOf(e); } @@ -537,6 +551,12 @@ public class LISTS @Override public KEY_TYPE REMOVE(int index) { throw new UnsupportedOperationException(); } + @Override + public KEY_TYPE swapRemove(int index) { throw new UnsupportedOperationException(); } + + @Override + public boolean REMOVE_SWAP(KEY_TYPE e) { throw new UnsupportedOperationException(); } + @Override public int indexOf(Object e) { return -1; }