in core/src/main/java/com/jetbrains/youtrackdb/internal/common/collection/MultiValue.java [561:713]
public static Object remove(Object iObject, Object iToRemove, final boolean iAllOccurrences) {
if (iObject != null) {
if (iObject instanceof MultiCollectionIterator<?>) {
final Collection<Object> list = new LinkedList<Object>();
for (var o : ((MultiCollectionIterator<?>) iObject)) {
list.add(o);
}
iObject = list;
}
if (iToRemove instanceof MultiCollectionIterator<?>) {
// TRANSFORM IN SET ONCE TO OPTIMIZE LOOPS DURING REMOVE
final Set<Object> set = new HashSet<Object>();
for (var o : ((MultiCollectionIterator<?>) iToRemove)) {
set.add(o);
}
iToRemove = set;
}
if (iObject instanceof Collection<?> || iObject instanceof DataContainer<?>) {
// COLLECTION - ?
final DataContainer<Object> coll;
if (iObject instanceof Collection<?>) {
final var collection = (Collection<Object>) iObject;
coll =
new DataContainer<Object>() {
@Override
public void add(Object value) {
collection.add(value);
}
@Override
public boolean remove(Object value) {
return collection.remove(value);
}
@Override
public Iterator<Object> iterator() {
return collection.iterator();
}
@Override
public int size() {
return collection.size();
}
@Override
public boolean isSizeable() {
return true;
}
};
} else {
coll = (DataContainer<Object>) iObject;
}
if (iToRemove instanceof Collection<?>) {
// COLLECTION - COLLECTION
for (var o : (Collection<Object>) iToRemove) {
if (isMultiValue(o)) {
remove(coll, o, iAllOccurrences);
} else {
removeFromOCollection(iObject, coll, o, iAllOccurrences);
}
}
} else if (iToRemove != null && iToRemove.getClass().isArray()) {
// ARRAY - COLLECTION
for (var i = 0; i < Array.getLength(iToRemove); ++i) {
var o = Array.get(iToRemove, i);
if (isMultiValue(o)) {
remove(coll, o, iAllOccurrences);
} else {
removeFromOCollection(iObject, coll, o, iAllOccurrences);
}
}
} else if (iToRemove instanceof Map<?, ?>) {
// MAP
for (var entry : ((Map<Object, Object>) iToRemove).entrySet()) {
coll.remove(entry.getKey());
}
} else if (iToRemove instanceof Iterator<?>) {
// ITERATOR
if (iToRemove instanceof MultiCollectionIterator<?>) {
((MultiCollectionIterator<?>) iToRemove).reset();
}
if (iAllOccurrences) {
if (iObject instanceof DataContainer) {
throw new IllegalStateException(
"Mutable collection cannot be used to remove all occurrences.");
}
final Collection<Object> collection = (Collection) iObject;
var it = (MultiCollectionIterator<?>) iToRemove;
batchRemove(collection, it);
} else {
var it = (Iterator<?>) iToRemove;
if (it.hasNext()) {
final var itemToRemove = it.next();
coll.remove(itemToRemove);
}
}
} else {
removeFromOCollection(iObject, coll, iToRemove, iAllOccurrences);
}
} else if (iObject.getClass().isArray()) {
// ARRAY - ?
final Object[] copy;
if (iToRemove instanceof Collection<?>) {
// ARRAY - COLLECTION
final var sourceTot = Array.getLength(iObject);
final var tot = sourceTot - ((Collection<Object>) iToRemove).size();
copy = new Object[tot];
var k = 0;
for (var i = 0; i < sourceTot; ++i) {
var o = Array.get(iObject, i);
if (o != null) {
var found = false;
for (var toRemove : (Collection<Object>) iToRemove) {
if (o.equals(toRemove)) {
// SKIP
found = true;
break;
}
}
if (!found) {
copy[k++] = o;
}
}
}
} else if (iToRemove != null && iToRemove.getClass().isArray()) {
throw new UnsupportedOperationException("Cannot execute remove() against an array");
} else {
throw new UnsupportedOperationException("Cannot execute remove() against an array");
}
return copy;
} else if (iObject instanceof Map) {
((Map) iObject).remove(iToRemove);
} else {
throw new IllegalArgumentException("Object " + iObject + " is not a multi value");
}
}
return iObject;
}