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 }