@@ -92,43 +92,42 @@ fn fast_string_eq(a, b string) bool {
9292 return C.memcmp (a.str, b.str, b.len) == 0
9393}
9494
95- struct KeyValue {
96- key string
97- mut :
98- value voidptr
99- }
100-
10195// Dynamic array with very low growth factor
10296struct DenseArray {
97+ value_bytes int
10398mut :
104- cap u32
105- size u32
106- deletes u32
107- data & KeyValue
99+ cap u32
100+ size u32
101+ deletes u32
102+ keys & string
103+ values byteptr
108104}
109105
110106[inline ]
111- fn new_dense_array () DenseArray {
112- unsafe {
113- return DenseArray{
114- cap: 8
115- size: 0
116- deletes: 0
117- data: & KeyValue (malloc (8 * sizeof (KeyValue)))
118- }
107+ [unsafe_fn]
108+ fn new_dense_array (value_bytes int ) DenseArray {
109+ return DenseArray{
110+ value_bytes: value_bytes
111+ cap: 8
112+ size: 0
113+ deletes: 0
114+ keys: & string (malloc (8 * sizeof (string )))
115+ values: malloc (8 * value_bytes)
119116 }
120117}
121118
122119// Push element to array and return index
123120// The growth-factor is roughly 1.125 `(x + (x >> 3))`
124121[inline ]
125- fn (d mut DenseArray) push (kv KeyValue ) u32 {
122+ fn (d mut DenseArray) push (key string , value voidptr ) u32 {
126123 if d.cap == d.size {
127- d.cap + = d.cap>> 3
128- d.data = & KeyValue (C.realloc (d.data, sizeof (KeyValue) * d.cap))
124+ d.cap + = d.cap >> 3
125+ d.keys = & string (C.realloc (d.keys, sizeof (string ) * d.cap))
126+ d.values = C.realloc (d.values, d.value_bytes * d.cap)
129127 }
130128 push_index := d.size
131- d.data[push_index] = kv
129+ d.keys[push_index] = key
130+ C.memcpy (d.values + push_index * d.value_bytes, value, d.value_bytes)
132131 d.size++
133132 return push_index
134133}
@@ -140,25 +139,33 @@ fn (d DenseArray) get(i int) voidptr {
140139 panic ('DenseArray.get: index out of range (i == $i , d.len == $d.size )' )
141140 }
142141 }
143- return byteptr (d.data ) + i * sizeof (KeyValue )
142+ return byteptr (d.keys ) + i * sizeof (string )
144143}
145144
146145// Move all zeros to the end of the array
147146// and resize array
148147fn (d mut DenseArray) zeros_to_end () {
148+ mut tmp_value := malloc (d.value_bytes)
149149 mut count := u32 (0 )
150150 for i in 0 .. d.size {
151- if d.data[i].key.str != 0 {
152- tmp := d.data[count]
153- d.data[count] = d.data[i]
154- d.data[i] = tmp
151+ if d.keys[i].str != 0 {
152+ // swap keys
153+ tmp_key := d.keys[count]
154+ d.keys[count] = d.keys[i]
155+ d.keys[i] = tmp_key
156+ // swap values (TODO: optimize)
157+ C.memcpy (tmp_value, d.values + count * d.value_bytes, d.value_bytes)
158+ C.memcpy (d.values + count * d.value_bytes, d.values + i * d.value_bytes, d.value_bytes)
159+ C.memcpy (d.values + i * d.value_bytes, tmp_value, d.value_bytes)
155160 count++
156161 }
157162 }
163+ free (tmp_value)
158164 d.deletes = 0
159165 d.size = count
160166 d.cap = if count < 8 { u32 (8 ) } else { count }
161- d.data = & KeyValue (C.realloc (d.data, sizeof (KeyValue) * d.cap))
167+ d.keys = & string (C.realloc (d.keys, sizeof (string ) * d.cap))
168+ d.values = C.realloc (d.values, d.value_bytes * d.cap)
162169}
163170
164171pub struct map {
@@ -185,17 +192,13 @@ pub mut:
185192 size int
186193}
187194
188- // TODO: remove this after vc is regenerated.
189- fn new_map (n, value_bytes int ) map {
190- return new_map_1 (value_bytes)
191- }
192195fn new_map_1 (value_bytes int ) map {
193196 return map {
194197 value_bytes: value_bytes
195198 cap: init_cap
196199 cached_hashbits: max_cached_hashbits
197200 shift: init_log_capicity
198- key_values: new_dense_array ()
201+ key_values: new_dense_array (value_bytes )
199202 metas: & u32 (vcalloc (sizeof (u32 ) * (init_capicity + extra_metas_inc)))
200203 extra_metas: extra_metas_inc
201204 size: 0
@@ -271,20 +274,14 @@ fn (m mut map) set(key string, value voidptr) {
271274 // While we might have a match
272275 for meta == m.metas[index] {
273276 kv_index := m.metas[index + 1 ]
274- if fast_string_eq (key, m.key_values.data [kv_index].key ) {
275- C.memcpy (m.key_values.data[ kv_index].value , value, m.value_bytes)
277+ if fast_string_eq (key, m.key_values.keys [kv_index]) {
278+ C.memcpy (m.key_values.values + kv_index * m.value_bytes , value, m.value_bytes)
276279 return
277280 }
278281 index + = 2
279282 meta + = probe_inc
280283 }
281- // Match not possible anymore
282- kv := KeyValue{
283- key: key
284- value: malloc (m.value_bytes)
285- }
286- C.memcpy (kv.value, value, m.value_bytes)
287- kv_index := m.key_values.push (kv)
284+ kv_index := m.key_values.push (key, value)
288285 m.meta_greater (index, meta, kv_index)
289286 m.size++
290287}
@@ -301,20 +298,19 @@ fn (m mut map) expand() {
301298 }
302299 else {
303300 m.cached_rehash (old_cap)
301+ m.cached_hashbits--
304302 }
305- m.cached_hashbits--
306303}
307304
308305fn (m mut map) rehash () {
309306 meta_bytes := sizeof (u32 ) * (m.cap + 2 + m.extra_metas)
310307 m.metas = & u32 (C.realloc (m.metas, meta_bytes))
311308 C.memset (m.metas, 0 , meta_bytes)
312309 for i := u32 (0 ); i < m.key_values.size; i++ {
313- if m.key_values.data [i].key .str == 0 {
310+ if m.key_values.keys [i].str == 0 {
314311 continue
315312 }
316- kv := m.key_values.data[i]
317- mut index,mut meta := m.key_to_index (kv.key)
313+ mut index,mut meta := m.key_to_index (m.key_values.keys[i])
318314 index ,meta = m.meta_less (index, meta)
319315 m.meta_greater (index, meta, i)
320316 }
@@ -347,8 +343,8 @@ fn (m map) get3(key string, zero voidptr) voidptr {
347343 index ,meta = m.meta_less (index, meta)
348344 for meta == m.metas[index] {
349345 kv_index := m.metas[index + 1 ]
350- if fast_string_eq (key, m.key_values.data [kv_index].key ) {
351- return m.key_values.data[ kv_index].value
346+ if fast_string_eq (key, m.key_values.keys [kv_index]) {
347+ return voidptr ( m.key_values.values + kv_index * m.value_bytes)
352348 }
353349 index + = 2
354350 meta + = probe_inc
@@ -361,7 +357,7 @@ fn (m map) exists(key string) bool {
361357 index ,meta = m.meta_less (index, meta)
362358 for meta == m.metas[index] {
363359 kv_index := m.metas[index + 1 ]
364- if fast_string_eq (key, m.key_values.data [kv_index].key ) {
360+ if fast_string_eq (key, m.key_values.keys [kv_index]) {
365361 return true
366362 }
367363 index + = 2
@@ -376,7 +372,7 @@ pub fn (m mut map) delete(key string) {
376372 // Perform backwards shifting
377373 for meta == m.metas[index] {
378374 kv_index := m.metas[index + 1 ]
379- if fast_string_eq (key, m.key_values.data [kv_index].key ) {
375+ if fast_string_eq (key, m.key_values.keys [kv_index]) {
380376 for (m.metas[index + 2 ]>> hashbits) > 1 {
381377 m.metas[index] = m.metas[index + 2 ] - probe_inc
382378 m.metas[index + 1 ] = m.metas[index + 3 ]
@@ -385,7 +381,7 @@ pub fn (m mut map) delete(key string) {
385381 m.size--
386382 m.metas[index] = 0
387383 m.key_values.deletes++
388- C.memset (& m.key_values.data [kv_index], 0 , sizeof (KeyValue ))
384+ C.memset (& m.key_values.keys [kv_index], 0 , sizeof (string ))
389385 if m.key_values.size < = 32 {
390386 return
391387 }
@@ -407,10 +403,10 @@ pub fn (m &map) keys() []string {
407403 mut keys := ['' ].repeat (m.size)
408404 mut j := 0
409405 for i := u32 (0 ); i < m.key_values.size; i++ {
410- if m.key_values.data [i].key .str == 0 {
406+ if m.key_values.keys [i].str == 0 {
411407 continue
412408 }
413- keys[j] = m.key_values.data [i].key
409+ keys[j] = m.key_values.keys [i]
414410 j++
415411 }
416412 return keys
@@ -420,12 +416,13 @@ pub fn (m &map) keys() []string {
420416pub fn (m map) free () {
421417 free (m.metas)
422418 for i := u32 (0 ); i < m.key_values.size; i++ {
423- if m.key_values.data [i].key .str == 0 {
419+ if m.key_values.keys [i].str == 0 {
424420 continue
425421 }
426- m.key_values.data [i].key .free ()
422+ m.key_values.keys [i].free ()
427423 }
428- free (m.key_values.data)
424+ free (m.key_values.keys)
425+ free (m.key_values.values)
429426}
430427
431428pub fn (m map_string) str () string {
0 commit comments