private static boolean removeInternal()

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;
    }