NativeMultiHashMap unique key problem

I am using NMHM for this job : each entities has faction A, B, C, D … and each has Level. I would like to find the highest level of each faction.

Therefore I use parallel writer of NMHM throw into ForEach jobs so each entity could contribute to the NMHM on their own in parallel. The NMHM is of type <Faction, Level>

After that ForEach jobs, I would have something like :
A → 1 5 3 3 2 3 4 1 …
B → 3 7 5 3 6 4 4 3 …
C → 2 2 4 6 1 6 8 1 …

So Level values are grouped by different kind of keys. This let me have unlimited kind of factions and also each entity can delay comparing with “previous maximum” that would be common in a typical searching for min/max algorithm.

Then an another single thread Job.WithCode would get the reader of NMHM to find out the max level of each key.

The plan is to use GetKeyArray then iterate on GetValuesForKey and find max value on each. However I notice that GetKeyArray returns duplicate keys. (Like A A A … because its value pair would be A 1, A 5, A 3, A 3 …)

Then I found GetUniqueKeyArray which I assumed it would filter out duplicated keys, but it returns Tuple<NativeArray, int> which is not only a class type (can’t Burst?), but the key array still contains duplicates (but sorted so duplicates are next to each other). The int tell me amount of unique keys. I would like to know how would that integer count be useful to let me get truly unique keys?

The current solution is that I make a List that I add the key I have already worked on. If .Contains returns true then I am skipping that key. But I would like to know any more proper way than this. Thanks.

(The actual work is that one frame I got multiple inputs, and each input could “hit” at most one thing closest to it. Therefore I need to collect all the things mapped to each available input, then choose the most appropriate one.)

Hi @5argon

You can have parallel iterating with Interface IJobNativeMultiHashMapMergedSharedKeyIndices | Package Manager UI website.
It is better explained in this talk: How does IJobNativeMultiHashMapMergedSharedKeyIndices work?

Or:

var highest = -1;

if (HashMap.TryGetFirstValue(faction, out int level, out NativeMultiHashMapIterator<int> iterator))
{
    highest = level;

    while (HashMap.TryGetNextValue(out level, ref iterator))
     {
          if(level > highest)
             highest = level;
     }
}

Schedule it per faction. I use it for my network prototype. Getting 1 million iteration over 7 workers in ~1ms
Hope it helps.

4 Likes