Search Unity

[Solved] Is it me or does NativeMultiHashMap insert its values in a really weird way?

Discussion in 'Scripting' started by Yoreki, Aug 10, 2019.

  1. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Hi all, right now i'm really confused and hope somebody knows what's going on.
    I have a lookup table of type int[256][], which contains entries of type int[16] (Marching Cubes algorithm, not relevant to the question tho). In order to parallelize the workload i'm using jobs, which required me to convert the lookup table to a native collection type in order to use it. Since it's a jagged array, the only type i found to fit was NativeMultiHashMap. Using the original index as key and the 16 ints as values i got it to work, somewhat.

    The problem is that the order of the values is important, as these eventually relate to vertices, making up triangles, and most of us probably know that triangles dont like being looked at from the wrong side. They get all shy and stuff. Anyways, a typical entry looks something like this:
    Code (CSharp):
    1. {0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
    The -1's basically fill up entries that are not used, so as a rule of thumb they should always be at the end.

    I'm using the following code to convert my int[256][] lookup table into a NativeMultiHashMap:
    Code (CSharp):
    1.     public static NativeMultiHashMap<int, int> nativeTriMap;
    2.  
    3.     public static void ConvertLookupTablesToNativeCollections()
    4.     {
    5.         nativeTriMap = new NativeMultiHashMap<int, int>(256, Allocator.Persistent);
    6.         for (int i = 0; i < triTable.Length; i++) // triTable being the original int[256][] lookup table
    7.         {
    8.             for (int j = 0; j < 16; j++)
    9.             {
    10.                 nativeTriMap.Add(i, triTable[i][j]);
    11.             }
    12.         }
    13.     }
    So i'm inserting each single value in the right order with its first index as key.

    As i said, it technically works. However, when my meshes were missing vertices i tracked the problem down and ended up printing all of the key/value pair in the NativeMultiHashMap with this result (~250 long):
    Entry 0: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 1: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 8, 0,
    Entry 2: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 1, 0,
    Entry 3: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 8, 9, 3, 8, 1,
    Entry 4: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 2, 1,
    Entry 5: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 2, 1, 3, 8, 0,
    Entry 6: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 2, 0, 10, 2, 9,
    Entry 7: -1, -1, -1, -1, -1, -1, -1, 8, 9, 10, 8, 10, 2, 3, 8, 2,
    Entry 8: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 11, 3,
    Entry 9: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 11, 8, 2, 11, 0,
    Entry 10: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 3, 2, 0, 9, 1,
    Entry 11: -1, -1, -1, -1, -1, -1, -1, 11, 8, 9, 11, 9, 1, 2, 11, 1,
    Entry 12: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 10, 11, 1, 10, 3,
    Entry 13: -1, -1, -1, -1, -1, -1, -1, 10, 11, 8, 10, 8, 0, 1, 10, 0,
    Entry 14: -1, -1, -1, -1, -1, -1, -1, 9, 10, 11, 9, 11, 3, 0, 9, 3,
    Entry 15: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 8, 10, 10, 8, 9,
    Entry 16: 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 17: 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 18: 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 19: 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1,
    Entry 20: 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 21: 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1,
    Entry 22: 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,
    Entry 23: 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1,
    Entry 24: 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 25: 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1,
    Entry 26: 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1,
    Entry 27: 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1,
    Entry 28: 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1,
    Entry 29: 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1,
    Entry 30: 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1,
    Entry 31: 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1,
    Entry 32: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 9,
    Entry 33: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 8, 0, 4, 5, 9,
    Entry 34: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 5, 1, 4, 5, 0,
    Entry 35: -1, -1, -1, -1, -1, -1, -1, 5, 1, 3, 5, 3, 8, 4, 5, 8,
    Entry 36: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 9, 10, 2, 1,
    Entry 37: -1, -1, -1, -1, -1, -1, -1, 5, 9, 4, 10, 2, 1, 8, 0, 3,
    Entry 38: -1, -1, -1, -1, -1, -1, -1, 2, 0, 4, 2, 4, 5, 10, 2, 5,
    Entry 39: -1, -1, -1, -1, 8, 4, 3, 4, 5, 3, 5, 2, 3, 5, 10, 2,
    Entry 40: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 3, 2, 4, 5, 9,
    Entry 41: -1, -1, -1, -1, -1, -1, -1, 5, 9, 4, 11, 8, 0, 2, 11, 0,
    Entry 42: -1, -1, -1, -1, -1, -1, -1, 11, 3, 2, 5, 1, 0, 4, 5, 0,
    Entry 43: -1, -1, -1, -1, 5, 8, 4, 11, 8, 2, 8, 5, 2, 5, 1, 2,
    Entry 44: -1, -1, -1, -1, -1, -1, -1, 4, 5, 9, 3, 1, 10, 11, 3, 10,
    Entry 45: -1, -1, -1, -1, 10, 11, 8, 1, 10, 8, 1, 8, 0, 5, 9, 4,
    Entry 46: -1, -1, -1, -1, 3, 0, 11, 10, 11, 5, 11, 0, 5, 0, 4, 5,
    Entry 47: -1, -1, -1, -1, -1, -1, -1, 11, 8, 10, 10, 8, 5, 8, 4, 5,
    Entry 48: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 7, 5, 8, 7, 9,
    Entry 49: -1, -1, -1, -1, -1, -1, -1, 3, 7, 5, 3, 5, 9, 0, 3, 9,
    Entry 50: -1, -1, -1, -1, -1, -1, -1, 7, 5, 1, 7, 1, 0, 8, 7, 0,
    Entry 51: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 5, 3, 3, 5, 1,
    Entry 52: -1, -1, -1, -1, -1, -1, -1, 2, 1, 10, 7, 5, 9, 8, 7, 9,
    Entry 53: -1, -1, -1, -1, 3, 7, 5, 0, 3, 5, 0, 5, 9, 2, 1, 10,
    Entry 54: -1, -1, -1, -1, 2, 5, 10, 7, 5, 8, 5, 2, 8, 2, 0, 8,
    Entry 55: -1, -1, -1, -1, -1, -1, -1, 7, 5, 3, 3, 5, 2, 5, 10, 2,
    Entry 56: -1, -1, -1, -1, -1, -1, -1, 2, 11, 3, 9, 8, 7, 5, 9, 7,
    Entry 57: -1, -1, -1, -1, 11, 7, 2, 0, 2, 9, 2, 7, 9, 7, 5, 9,
    Entry 58: -1, -1, -1, -1, 7, 5, 1, 8, 7, 1, 8, 1, 0, 11, 3, 2,
    Entry 59: -1, -1, -1, -1, -1, -1, -1, 5, 1, 7, 7, 1, 11, 1, 2, 11,
    Entry 60: -1, -1, -1, -1, 11, 3, 10, 3, 1, 10, 7, 5, 8, 8, 5, 9,
    Entry 61: -1, 0, 10, 11, 10, 0, 1, 0, 11, 7, 9, 0, 5, 0, 7, 5,
    Entry 62: -1, 0, 7, 5, 7, 0, 8, 0, 5, 10, 3, 0, 11, 0, 10, 11,
    Entry 63: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 11, 7, 5, 10, 11,
    Entry 64: 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 65: 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 66: 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 67: 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,
    Entry 68: 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 69: 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1,
    Entry 70: 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1,
    Entry 71: 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1,
    Entry 72: 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 73: 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,
    Entry 74: 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1,
    Entry 75: 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1,
    Entry 76: 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1,
    Entry 77: 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1,
    Entry 78: 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1,
    Entry 79: 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1,
    Entry 80: 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 81: 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1,
    Entry 82: 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1,
    Entry 83: 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1,
    Entry 84: 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1,
    Entry 85: 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1,
    Entry 86: 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1,
    Entry 87: 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1,
    Entry 88: 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1,
    Entry 89: 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1,
    Entry 90: 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1,
    Entry 91: 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1,
    Entry 92: 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1,
    Entry 93: 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1,
    Entry 94: 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1,
    Entry 95: 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1,
    Entry 96: 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 97: 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1,
    Entry 98: 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1,
    Entry 99: 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1,
    Entry 100: 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1,
    Entry 101: 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1,
    Entry 102: 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 103: 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1,
    Entry 104: 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1,
    Entry 105: 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1,
    Entry 106: 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1,
    Entry 107: 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1,
    Entry 108: 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1,
    Entry 109: 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1,
    Entry 110: 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1,
    Entry 111: 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 112: 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1,
    Entry 113: 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1,
    Entry 114: 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1,
    Entry 115: 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1,
    Entry 116: 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1,
    Entry 117: 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1,
    Entry 118: 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1,
    Entry 119: 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 120: 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1,
    Entry 121: 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1,
    Entry 122: 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1,
    Entry 123: 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1,
    Entry 124: 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1,
    Entry 125: 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 126: 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1,
    Entry 127: 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    Entry 128: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 6, 7,
    Entry 129: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 7, 11, 8, 0, 3,
    Entry 130: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 7, 11, 9, 1, 0,
    Entry 131: -1, -1, -1, -1, -1, -1, -1, 6, 7, 11, 1, 3, 8, 9, 1, 8,
    Entry 132: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 11, 6, 2, 1, 10,
    Entry 133: -1, -1, -1, -1, -1, -1, -1, 7, 11, 6, 8, 0, 3, 10, 2, 1,
    Entry 134: -1, -1, -1, -1, -1, -1, -1, 7, 11, 6, 9, 10, 2, 0, 9, 2,
    Entry 135: -1, -1, -1, -1, 8, 9, 10, 3, 8, 10, 3, 10, 2, 7, 11, 6,
    Entry 136: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 2, 6, 3, 2, 7,
    Entry 137: -1, -1, -1, -1, -1, -1, -1, 0, 2, 6, 0, 6, 7, 8, 0, 7,
    Entry 138: -1, -1, -1, -1, -1, -1, -1, 9, 1, 0, 7, 3, 2, 6, 7, 2,
    Entry 139: -1, -1, -1, -1, 6, 7, 8, 8, 9, 1, 6, 8, 1, 2, 6, 1,
    Entry 140: -1, -1, -1, -1, -1, -1, -1, 7, 3, 1, 7, 1, 10, 6, 7, 10,
    Entry 141: -1, -1, -1, -1, 8, 0, 1, 7, 8, 1, 10, 7, 1, 6, 7, 10,
    Entry 142: -1, -1, -1, -1, 7, 10, 6, 9, 10, 0, 10, 7, 0, 7, 3, 0,
    Entry 143: -1, -1, -1, -1, -1, -1, -1, 9, 10, 8, 8, 10, 7, 10, 6, 7,
    Entry 144: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 8, 11, 4, 8, 6,
    Entry 145: -1, -1, -1, -1, -1, -1, -1, 6, 4, 0, 6, 0, 3, 11, 6, 3,
    Entry 146: -1, -1, -1, -1, -1, -1, -1, 1, 0, 9, 6, 4, 8, 11, 6, 8,
    Entry 147: -1, -1, -1, -1, 6, 3, 11, 1, 3, 9, 3, 6, 9, 6, 4, 9,
    Entry 148: -1, -1, -1, -1, -1, -1, -1, 1, 10, 2, 8, 11, 6, 4, 8, 6,
    Entry 149: -1, -1, -1, -1, 6, 4, 0, 11, 6, 0, 11, 0, 3, 10, 2, 1,
    Entry 150: -1, -1, -1, -1, 9, 10, 2, 9, 2, 0, 11, 6, 4, 8, 11, 4,
    Entry 151: -1, 3, 6, 4, 6, 3, 11, 3, 4, 9, 2, 3, 10, 3, 9, 10,
    Entry 152: -1, -1, -1, -1, -1, -1, -1, 2, 6, 4, 2, 4, 8, 3, 2, 8,
    Entry 153: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, 6, 4, 2, 4, 0,
    Entry 154: -1, -1, -1, -1, 8, 3, 4, 6, 4, 2, 4, 3, 2, 0, 9, 1,
    Entry 155: -1, -1, -1, -1, -1, -1, -1, 6, 4, 2, 2, 4, 1, 4, 9, 1,
    Entry 156: -1, -1, -1, -1, 1, 10, 6, 6, 4, 8, 1, 6, 8, 3, 1, 8,
    Entry 157: -1, -1, -1, -1, -1, -1, -1, 4, 0, 6, 6, 0, 10, 0, 1, 10,
    Entry 158: -1, 3, 9, 10, 9, 3, 0, 3, 10, 6, 8, 3, 4, 3, 6, 4,
    Entry 159: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 10, 6, 4, 9, 10,
    Entry 160: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 6, 7, 5, 9, 4,
    Entry 161: -1, -1, -1, -1, -1, -1, -1, 6, 7, 11, 5, 9, 4, 3, 8, 0,
    Entry 162: -1, -1, -1, -1, -1, -1, -1, 11, 6, 7, 0, 4, 5, 1, 0, 5,
    Entry 163: -1, -1, -1, -1, 5, 1, 3, 4, 5, 3, 4, 3, 8, 6, 7, 11,
    Entry 164: -1, -1, -1, -1, -1, -1, -1, 11, 6, 7, 2, 1, 10, 4, 5, 9,
    Entry 165: -1, -1, -1, -1, 5, 9, 4, 3, 8, 0, 10, 2, 1, 7, 11, 6,
    Entry 166: -1, -1, -1, -1, 2, 0, 4, 10, 2, 4, 10, 4, 5, 11, 6, 7,
    Entry 167: -1, 6, 7, 11, 2, 5, 10, 5, 2, 3, 4, 5, 3, 8, 4, 3,
    Entry 168: -1, -1, -1, -1, -1, -1, -1, 9, 4, 5, 2, 6, 7, 3, 2, 7,
    Entry 169: -1, -1, -1, -1, 7, 8, 6, 2, 6, 0, 6, 8, 0, 4, 5, 9,
    Entry 170: -1, -1, -1, -1, 0, 4, 5, 0, 5, 1, 6, 7, 3, 2, 6, 3,
    Entry 171: -1, 8, 5, 1, 5, 8, 4, 8, 1, 2, 7, 8, 6, 8, 2, 6,
    Entry 172: -1, -1, -1, -1, 7, 3, 1, 6, 7, 1, 6, 1, 10, 4, 5, 9,
    Entry 173: -1, 4, 5, 9, 0, 7, 8, 7, 0, 1, 6, 7, 1, 10, 6, 1,
    Entry 174: -1, 10, 7, 3, 7, 10, 6, 10, 3, 0, 5, 10, 4, 10, 0, 4,
    Entry 175: -1, -1, -1, -1, 10, 8, 4, 10, 4, 5, 8, 10, 7, 10, 6, 7,
    Entry 176: -1, -1, -1, -1, -1, -1, -1, 9, 8, 11, 9, 11, 6, 5, 9, 6,
    Entry 177: -1, -1, -1, -1, 5, 9, 0, 6, 5, 0, 3, 6, 0, 11, 6, 3,
    Entry 178: -1, -1, -1, -1, 11, 6, 5, 5, 1, 0, 11, 5, 0, 8, 11, 0,
    Entry 179: -1, -1, -1, -1, -1, -1, -1, 1, 3, 5, 5, 3, 6, 3, 11, 6,
    Entry 180: -1, -1, -1, -1, 6, 5, 11, 8, 11, 9, 11, 5, 9, 10, 2, 1,
    Entry 181: -1, 10, 2, 1, 9, 6, 5, 6, 9, 0, 11, 6, 0, 3, 11, 0,
    Entry 182: -1, 5, 2, 0, 2, 5, 10, 5, 0, 8, 6, 5, 11, 5, 8, 11,
    Entry 183: -1, -1, -1, -1, 3, 5, 10, 3, 10, 2, 5, 3, 6, 3, 11, 6,
    Entry 184: -1, -1, -1, -1, 2, 8, 3, 2, 6, 5, 8, 2, 5, 9, 8, 5,
    Entry 185: -1, -1, -1, -1, -1, -1, -1, 2, 6, 0, 0, 6, 9, 6, 5, 9,
    Entry 186: -1, 8, 2, 6, 2, 8, 3, 8, 6, 5, 0, 8, 1, 8, 5, 1,
    Entry 187: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 1, 2, 6, 5, 1,
    Entry 188: -1, 6, 9, 8, 9, 6, 5, 6, 8, 3, 10, 6, 1, 6, 3, 1,
    Entry 189: -1, -1, -1, -1, 0, 6, 5, 0, 5, 9, 6, 0, 10, 0, 1, 10,
    Entry 190: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 6, 5, 8, 3, 0,
    Entry 191: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 6, 5, 10,
    Entry 192: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 5, 7, 10, 5, 11,
    Entry 193: -1, -1, -1, -1, -1, -1, -1, 0, 3, 8, 5, 7, 11, 10, 5, 11,
    Entry 194: -1, -1, -1, -1, -1, -1, -1, 0, 9, 1, 11, 10, 5, 7, 11, 5,
    Entry 195: -1, -1, -1, -1, 1, 3, 8, 1, 8, 9, 7, 11, 10, 5, 7, 10,
    Entry 196: -1, -1, -1, -1, -1, -1, -1, 1, 5, 7, 1, 7, 11, 2, 1, 11,
    Entry 197: -1, -1, -1, -1, 11, 2, 7, 5, 7, 1, 7, 2, 1, 3, 8, 0,
    Entry 198: -1, -1, -1, -1, 7, 11, 2, 2, 0, 9, 7, 2, 9, 5, 7, 9,
    Entry 199: -1, 2, 8, 9, 8, 2, 3, 2, 9, 5, 11, 2, 7, 2, 5, 7,
    Entry 200: -1, -1, -1, -1, -1, -1, -1, 5, 7, 3, 5, 3, 2, 10, 5, 2,
    Entry 201: -1, -1, -1, -1, 5, 2, 10, 5, 7, 8, 2, 5, 8, 0, 2, 8,
    Entry 202: -1, -1, -1, -1, 2, 10, 3, 7, 3, 5, 3, 10, 5, 1, 0, 9,
    Entry 203: -1, 2, 5, 7, 5, 2, 10, 2, 7, 8, 1, 2, 9, 2, 8, 9,
    Entry 204: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 7, 3, 5, 3, 1,
    Entry 205: -1, -1, -1, -1, -1, -1, -1, 5, 7, 1, 1, 7, 0, 7, 8, 0,
    Entry 206: -1, -1, -1, -1, -1, -1, -1, 7, 3, 5, 5, 3, 9, 3, 0, 9,
    Entry 207: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 9, 5, 7, 8, 9,
    Entry 208: -1, -1, -1, -1, -1, -1, -1, 8, 11, 10, 8, 10, 5, 4, 8, 5,
    Entry 209: -1, -1, -1, -1, 0, 3, 11, 11, 10, 5, 0, 11, 5, 4, 0, 5,
    Entry 210: -1, -1, -1, -1, 5, 4, 10, 11, 10, 8, 10, 4, 8, 9, 1, 0,
    Entry 211: -1, 4, 1, 3, 1, 4, 9, 4, 3, 11, 5, 4, 10, 4, 11, 10,
    Entry 212: -1, -1, -1, -1, 8, 5, 4, 8, 11, 2, 5, 8, 2, 1, 5, 2,
    Entry 213: -1, 11, 1, 5, 1, 11, 2, 11, 5, 4, 3, 11, 0, 11, 4, 0,
    Entry 214: -1, 5, 8, 11, 8, 5, 4, 5, 11, 2, 9, 5, 0, 5, 2, 0,
    Entry 215: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 11, 2, 5, 4, 9,
    Entry 216: -1, -1, -1, -1, 4, 8, 3, 5, 4, 3, 2, 5, 3, 10, 5, 2,
    Entry 217: -1, -1, -1, -1, -1, -1, -1, 0, 2, 4, 4, 2, 5, 2, 10, 5,
    Entry 218: -1, 9, 1, 0, 8, 5, 4, 5, 8, 3, 10, 5, 3, 2, 10, 3,
    Entry 219: -1, -1, -1, -1, 2, 4, 9, 2, 9, 1, 4, 2, 5, 2, 10, 5,
    Entry 220: -1, -1, -1, -1, -1, -1, -1, 1, 5, 3, 3, 5, 8, 5, 4, 8,
    Entry 221: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 0, 1, 5, 4, 0,
    Entry 222: -1, -1, -1, -1, 5, 3, 0, 5, 0, 9, 3, 5, 8, 5, 4, 8,
    Entry 223: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 4, 9,
    Entry 224: -1, -1, -1, -1, -1, -1, -1, 11, 10, 9, 11, 9, 4, 7, 11, 4,
    Entry 225: -1, -1, -1, -1, 11, 10, 9, 7, 11, 9, 7, 9, 4, 3, 8, 0,
    Entry 226: -1, -1, -1, -1, 11, 4, 7, 0, 4, 1, 4, 11, 1, 11, 10, 1,
    Entry 227: -1, 4, 11, 10, 11, 4, 7, 4, 10, 1, 8, 4, 3, 4, 1, 3,
    Entry 228: -1, -1, -1, -1, 2, 1, 9, 11, 2, 9, 4, 11, 9, 7, 11, 4,
    Entry 229: -1, 3, 8, 0, 1, 11, 2, 11, 1, 9, 7, 11, 9, 4, 7, 9,
    Entry 230: -1, -1, -1, -1, -1, -1, -1, 0, 4, 2, 2, 4, 11, 4, 7, 11,
    Entry 231: -1, -1, -1, -1, 4, 2, 3, 4, 3, 8, 2, 4, 11, 4, 7, 11,
    Entry 232: -1, -1, -1, -1, 9, 4, 7, 7, 3, 2, 9, 7, 2, 10, 9, 2,
    Entry 233: -1, 7, 0, 2, 0, 7, 8, 7, 2, 10, 4, 7, 9, 7, 10, 9,
    Entry 234: -1, 10, 0, 4, 0, 10, 1, 10, 4, 7, 2, 10, 3, 10, 7, 3,
    Entry 235: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 7, 8, 2, 10, 1,
    Entry 236: -1, -1, -1, -1, -1, -1, -1, 3, 1, 7, 7, 1, 4, 1, 9, 4,
    Entry 237: -1, -1, -1, -1, 1, 7, 8, 1, 8, 0, 7, 1, 4, 1, 9, 4,
    Entry 238: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 4, 7, 3, 0, 4,
    Entry 239: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, 8, 4,
    Entry 240: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, 11, 10, 8, 10, 9,
    Entry 241: -1, -1, -1, -1, -1, -1, -1, 10, 9, 11, 11, 9, 3, 9, 0, 3,
    Entry 242: -1<message truncated>​
    For those not wanting to open it: the order flips at specific positions from -1's-first to (meaningful) numbers-first and back.
    The order seems to flip precisely after 16, then again 16, then 32, 64 and 128 entries. And since this seems like a really predictable pattern, i'd say if the table didnt end, it'd flip at 256 again.

    So right now i'm confused as to why this happens. Assuming it's not a bug, why would one implement it that way? Other than utterly annoying people working with NativeMultiHashMaps i cant really see any benefits in regards to performance or anything, by flipping the order of insertion between LiFo and FiFo (Last/First in, First out).

    Other than satisfying my curiosity for this weird phenomenon, i would obviously like to fix the problem (as in have all values in the right order). The best i could come up with right now is to rewrite my conversion method to manually flip the order at 0,16,... to counteract the weird change of insertion order that occurs. Needless to say, this feels like a very dirty, hardcoded solution and doesnt help in understanding the problem at all.

    I'm using Windows 10 and Unity 2019.1.8f1, in case that matters.

    Thanks in advance!
     
    Last edited: Aug 10, 2019
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Well... since it's a HashMap, order isn't guaranteed. It's the nature of any hashing algorithm... they're order agnostic.

    I don't know what the hashing algorithm that is used to associate the key to its value set. But playing with inputs it appears to be a modulus of the length of the array combined with something else. This leads me to believe it creates an internal array that is some multiple of the length, and hashes its entries into that.

    Note it's not necessarily flipping it. For example here is what I get when I insert a sequence of number from 0->L*W into a NativeMultiHashMap of length L, and each key set is of width W based on this code:
    Code (csharp):
    1.  
    2. var arr = new NativeMultiHashMap<int, int>(10, Allocator.Temp);
    3. const int width = 7;
    4. const int height = 10;
    5.  
    6. for(int i = 0; i < height; i++)
    7. {
    8.     for(int j = 0; j < width; j++)
    9.     {
    10.         arr.Add(i, (i * width) + j);
    11.     }
    12. }
    13.  
    14. for(int i = 0; i < 10; i++)
    15. {
    16.     string sval = string.Empty;
    17.     foreach(var j in arr.GetValuesForKey(i))
    18.     {
    19.         sval += j + ", ";
    20.     }
    21.     Debug.Log(sval);
    22. }
    23.  
    24. arr.Dispose();
    25.  
    I get:
    hashmap.png
    Note it's not exactly looping it back and forth.

    ...

    But yeah... sorry, HashMap's don't guarantee order.

    HashMaps are like HashSets or Dictionary's. The hashing makes for O(1) lookups and retrievals. At the sacrifice of order.
     
    Yoreki and Antypodish like this.
  3. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    It's you :)

    The docs: "As a note, a HashMap does not make any guarantees of order or sorting."

    Your requirements: "the order of the values is important"

    As an aside, IIRC the order of items in a hashtable is intentionally sacrificed for speedy access -- which is also kind of implied since the position of an item in the table is defined by a hash function, not the order in which you add them..

    It looks as if you'd need an additional array to store the order, and then use that as an indirection to access the hashmap.
     
    Last edited: Aug 10, 2019
    Yoreki likes this.
  4. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Thank you very much for your fast replies!
    I was not entirely sure anymore if order was preserved or not in a hashmap, but reconsidering what hashing is supposed to do, it makes sense that it is not. I guess i got heavily confused by what seems to be a flipping of order every 2^x entries, in my example.

    Since NativeMultiHashMap is, to my knowledge, the only native container type that allows to indirectly store and access arrays of arrays, i guess i'll have to flatten the original table to a simple NativeArray<int> and look up the next 16 entries from index (i*16). If anybody has a better idea feel free to post it, otherwise this can be considered as fully answered.
     
  5. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    The rules for insertions of the values in the value-array seems to be affected when capacity grows, which is apparently just doubling the initial capacity once the capacity is used up and more space is needed.

    When that happens, the new available space is shared for the insertion of values for multiple keys. It's most-likely managed in one contiguous block of memory, not in separate blocks of memory.

    In your example, it is less obvious because you use an initial capacity of 256 and add 16 values per key, so there's a common denominator.

    Lord's example is more interesting though: Initial capacity is 10, but he adds 7 values per key.

    If you take a closer look at his results, the collection starts to use up the available capacity by adding the values for a given key in order. Once you exceed the current capacity, size of the container increases.

    During that process, the values for the second key seem to move to the end of now available memory, and the free capacity is now between the values for the existing keys. What happens next, is that the insertion does not work forwards for key #2, but now works in the opposite direction for key #2 and new keys, and probably still forwards for #1.

    This ensures that you can use (share) new capacity (the same partial block of free memory) for at least 2 keys, so that you don't need to acquire separate blocks for every single key.

    So the unreliable ordering of the value-arrays is not due to it being a hashXYZ (which primarily affects the order of the key-set, because the keys are hashed, not the associated values), but rather a result of the attempt to use less memory, more efficiently and more effectively.
    They could as well just allocate more and more memory, and evenly space the value-arrays in that new block of memory. But this could leave much of the memory unused, it's got a larger memory footprint.

    It's quite easy to visualize how the memory is filled when you add all values for one key, then all values for another (like your examples do)... But it'll be even more interesting how that collection behaves when you insert the values for existing keys randomly.
     
    Last edited: Aug 10, 2019
    Yoreki and lordofduct like this.