in accord-core/src/main/java/accord/utils/RelationMultiMap.java [193:252]
public T build()
{
if (totalCount == 0)
return none();
finishKey();
V[] uniqueValues = cachedValues.get(totalCount);
System.arraycopy(keysToValues, 0, uniqueValues, 0, totalCount);
Arrays.sort(uniqueValues, 0, totalCount, adapter.valueComparator());
int valueCount = 1;
for (int i = 1 ; i < totalCount ; ++i)
{
if (!uniqueValues[valueCount - 1].equals(uniqueValues[i]))
uniqueValues[valueCount++] = uniqueValues[i];
}
V[] values = cachedValues.complete(uniqueValues, valueCount);
cachedValues.discard(uniqueValues, totalCount);
int[] sortedKeyIndexes;
K[] sortedKeys;
if (hasOrderedKeys)
{
sortedKeyIndexes = null;
sortedKeys = cachedKeys.completeAndDiscard(keys, keyCount);
}
else
{
sortedKeyIndexes = new int[keyCount];
sortedKeys = Arrays.copyOf(keys, keyCount);
Arrays.sort(sortedKeys, adapter.keyComparator());
for (int i = 1 ; i < keyCount ; ++i)
{
if (sortedKeys[i-1].equals(sortedKeys[i]))
throw new IllegalArgumentException("Key " + sortedKeys[i] + " has been visited more than once ("
+ Arrays.toString(Arrays.copyOf(keys, keyCount)) + ")");
}
for (int i = 0 ; i < keyCount ; ++i)
sortedKeyIndexes[Arrays.binarySearch(sortedKeys, keys[i], adapter.keyComparator())] = i;
cachedKeys.forceDiscard(keys, keyCount);
}
int[] result = new int[keyCount + totalCount];
int offset = keyCount;
for (int ki = 0 ; ki < keyCount ; ++ki)
{
int k = sortedKeyIndexes == null ? ki : sortedKeyIndexes[ki];
int from = k == 0 ? 0 : keyLimits[k - 1];
int to = keyLimits[k];
offset = (int)SortedArrays.foldlIntersection(adapter.valueComparator(), values, 0, valueCount, keysToValues, from, to, (key, p, v, li, ri) -> {
result[(int)v] = li;
return v + 1;
}, 0, offset, -1);
result[ki] = offset;
}
return build(sortedKeys, values, result);
}