in accord-core/src/main/java/accord/utils/RelationMultiMap.java [986:1086]
private static <P, K, V> boolean removeInternal(K[] oldKeys, V[] oldValues, int[] oldKeysToValues,
K[] removeKeys, V[] removeValues, int[] removeKeysToValues,
Comparator<K> keyComparator, Comparator<V> valueComparator,
P param, QuadFunction<P, K, V, V, V> removeAndSplitValues,
boolean withPartialMatches)
{
if (oldKeys.length == 0 || removeKeys.length == 0)
return false;
boolean removed = false;
int ok = 0, rk = 0;
while (ok < oldKeys.length && rk < removeKeys.length)
{
K okey = oldKeys[ok], rkey = removeKeys[rk];
int c = keyComparator.compare(okey, rkey);
if (c > 0)
{
++rk;
}
else if (c < 0)
{
if (removed)
{
for (int oi = startOffset(oldKeys, oldKeysToValues, ok), maxoi = endOffset(oldKeysToValues, ok) ; oi < maxoi ; ++oi)
removeAndSplitValues.apply(param, okey, oldValues[oldKeysToValues[oi]], null);
}
++ok;
}
else
{
int oi = startOffset(oldKeys, oldKeysToValues, ok), maxoi = endOffset(oldKeysToValues, ok);
int ri = startOffset(removeKeys, removeKeysToValues, rk), maxri = endOffset(removeKeysToValues, rk);
V oval = oldValues[oldKeysToValues[oi]];
V rval = removeValues[removeKeysToValues[ri]];
while (true)
{
c = valueComparator.compare(oval, rval);
if (c < 0)
{
if (removed)
removeAndSplitValues.apply(param, okey, oval, null);
if (++oi == maxoi) break;
oval = oldValues[oldKeysToValues[oi]];
}
else if (c > 0)
{
if (++ri == maxri) break;
rval = removeValues[removeKeysToValues[ri]];
}
else
{
if (!removed)
{
removed = true;
for (int tk = 0 ; tk < ok ; tk++)
{
K key = oldKeys[tk];
for (int ti = startOffset(oldKeys, oldKeysToValues, tk), maxti = endOffset(oldKeysToValues, tk) ; ti < maxti ; ++ti)
removeAndSplitValues.apply(param, key, oldValues[oldKeysToValues[ti]], null);
}
for (int ti = startOffset(oldKeys, oldKeysToValues, ok) ; ti < oi ; ++ti)
removeAndSplitValues.apply(param, okey, oldValues[oldKeysToValues[ti]], null);
}
oval = removeAndSplitValues.apply(param, okey, oval, rval);
if (oval == null)
{
if (++oi == maxoi) break;
oval = oldValues[oldKeysToValues[oi]];
}
if (!withPartialMatches)
{
if (++ri == maxri) break;
rval = removeValues[removeKeysToValues[ri]];
}
}
}
if (removed && oi < maxoi)
{
removeAndSplitValues.apply(param, okey, oval, null);
while (++oi < maxoi)
removeAndSplitValues.apply(param, okey, oldValues[oldKeysToValues[oi]], null);
}
++ok;
++rk;
}
}
if (!removed)
return false;
while (ok < oldKeys.length)
{
K key = oldKeys[ok];
for (int oi = startOffset(oldKeys, oldKeysToValues, ok), maxoi = endOffset(oldKeysToValues, ok) ; oi < maxoi ; ++oi)
removeAndSplitValues.apply(param, key, oldValues[oldKeysToValues[oi]], null);
++ok;
}
return true;
}