1 module mutils.container.hash_map_simd; 2 3 version (X86_64) : 4 5 import mutils.container.hash_set_simd; 6 7 struct HashMap(KeyTypeE, T) { 8 alias Key = KeyTypeE; 9 alias Value = T; 10 11 HashSet!(Key, defaultHashFunc, Value) set; 12 13 void add(Key k, T v) { 14 size_t index = set.getIndex(k); 15 if (index == set.getIndexEmptyValue) { 16 set.add(k, v); 17 } else { 18 size_t group = index / 8; 19 size_t elIndex = index % 8; 20 set.groups[group].values[elIndex] = v; 21 } 22 } 23 24 void clear() { 25 set.clear(); 26 } 27 28 void reset() { 29 set.reset(); 30 } 31 32 size_t length() { 33 return set.length; 34 } 35 36 bool tryRemove(Key k) { 37 return set.tryRemove(k); 38 } 39 40 void remove(Key k) { 41 set.remove(k); 42 } 43 44 bool isIn(Key k) { 45 size_t index = set.getIndex(k); 46 return index != set.getIndexEmptyValue; 47 } 48 49 ref T get(Key k) { 50 size_t index = set.getIndex(k); 51 assert(index != set.getIndexEmptyValue); 52 size_t group = index / 8; 53 size_t elIndex = index % 8; 54 return set.groups[group].values[elIndex]; 55 56 } 57 58 T getDefault(Key k, T defaultValue) { 59 size_t index = set.getIndex(k); 60 if (index == set.getIndexEmptyValue) { 61 return defaultValue; 62 } else { 63 size_t group = index / 8; 64 size_t elIndex = index % 8; 65 return set.groups[group].values[elIndex]; 66 } 67 } 68 69 ref T getDefault(Key k, ref T defaultValue) { 70 size_t index = set.getIndex(k); 71 if (index == set.getIndexEmptyValue) { 72 return defaultValue; 73 } else { 74 size_t group = index / 8; 75 size_t elIndex = index % 8; 76 return set.groups[group].values[elIndex]; 77 } 78 } 79 80 ref T getInsertDefault(Key k, T defaultValue) { 81 size_t index = set.getIndex(k); 82 if (index == set.getIndexEmptyValue) { 83 set.add(k, defaultValue); 84 } 85 index = set.getIndex(k); 86 assert(index != set.getIndexEmptyValue); 87 size_t group = index / 8; 88 size_t elIndex = index % 8; 89 return set.groups[group].values[elIndex]; 90 91 } 92 93 int byKey(scope int delegate(Key k) dg) { 94 int result; 95 foreach (ref Key k; set) { 96 result = dg(k); 97 if (result) 98 break; 99 } 100 return result; 101 } 102 103 int byValue(scope int delegate(ref T k) dg) { 104 int result; 105 foreach (ref Control c, ref Key k, ref Value v; set) { 106 result = dg(v); 107 if (result) 108 break; 109 } 110 return result; 111 } 112 113 int byKeyValue(scope int delegate(ref Key k, ref Value k) dg) { 114 int result; 115 foreach (ref Control c, ref Key k, ref Value v; set) { 116 result = dg(k, v); 117 if (result) 118 break; 119 } 120 return result; 121 } 122 123 import std.format : FormatSpec, formatValue; 124 125 /** 126 * Preety print 127 */ 128 void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt) { 129 formatValue(sink, '[', fmt); 130 foreach (ref k, ref v; &byKeyValue) { 131 formatValue(sink, k, fmt); 132 formatValue(sink, ':', fmt); 133 formatValue(sink, v, fmt); 134 formatValue(sink, ", ", fmt); 135 } 136 formatValue(sink, ']', fmt); 137 } 138 } 139 140 unittest { 141 HashMap!(int, int) map; 142 map.add(1, 10); 143 assert(map.get(1) == 10); 144 assert(map.getDefault(2, 20) == 20); 145 assert(!map.isIn(2)); 146 assert(map.getInsertDefault(2, 20) == 20); 147 assert(map.get(2) == 20); 148 foreach (k; &map.byKey) { 149 } 150 foreach (k, v; &map.byKeyValue) { 151 } 152 foreach (v; &map.byValue) { 153 } 154 155 }