parent
							
								
									999fe846e5
								
							
						
					
					
						commit
						89ef316db3
					
				|  | @ -194,6 +194,8 @@ fn (mut d DenseArray) zeros_to_end() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub struct map { | pub struct map { | ||||||
|  | 	// Number of bytes of a key
 | ||||||
|  | 	key_bytes       int | ||||||
| 	// Number of bytes of a value
 | 	// Number of bytes of a value
 | ||||||
| 	value_bytes     int | 	value_bytes     int | ||||||
| mut: | mut: | ||||||
|  | @ -219,12 +221,14 @@ pub mut: | ||||||
| 
 | 
 | ||||||
| fn new_map_1(value_bytes int) map { | fn new_map_1(value_bytes int) map { | ||||||
| 	metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc)) | 	metasize := int(sizeof(u32) * (init_capicity + extra_metas_inc)) | ||||||
|  | 	key_bytes := int(sizeof(string)) | ||||||
| 	return map{ | 	return map{ | ||||||
|  | 		key_bytes: key_bytes | ||||||
| 		value_bytes: value_bytes | 		value_bytes: value_bytes | ||||||
| 		cap: init_cap | 		cap: init_cap | ||||||
| 		cached_hashbits: max_cached_hashbits | 		cached_hashbits: max_cached_hashbits | ||||||
| 		shift: init_log_capicity | 		shift: init_log_capicity | ||||||
| 		key_values: new_dense_array(int(sizeof(string)), value_bytes) | 		key_values: new_dense_array(key_bytes, value_bytes) | ||||||
| 		metas: &u32(vcalloc(metasize)) | 		metas: &u32(vcalloc(metasize)) | ||||||
| 		extra_metas: extra_metas_inc | 		extra_metas: extra_metas_inc | ||||||
| 		len: 0 | 		len: 0 | ||||||
|  | @ -240,7 +244,14 @@ fn new_map_init(n int, value_bytes int, keys &string, values voidptr) map { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| [inline] | [inline] | ||||||
| fn (m &map) key_to_index(key string) (u32, u32) { | fn (m &map) keys_eq(a voidptr, b voidptr) bool { | ||||||
|  | 	// assume string for now
 | ||||||
|  | 	return fast_string_eq(*&string(a), *&string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [inline] | ||||||
|  | fn (m &map) key_to_index(pkey voidptr) (u32, u32) { | ||||||
|  | 	key := *&string(pkey) | ||||||
| 	hash := hash.wyhash_c(key.str, u64(key.len), 0) | 	hash := hash.wyhash_c(key.str, u64(key.len), 0) | ||||||
| 	index := hash & m.cap | 	index := hash & m.cap | ||||||
| 	meta := ((hash >> m.shift) & hash_mask) | probe_inc | 	meta := ((hash >> m.shift) & hash_mask) | probe_inc | ||||||
|  | @ -311,15 +322,15 @@ fn (mut m map) set(k string, value voidptr) { | ||||||
| 	if load_factor > max_load_factor { | 	if load_factor > max_load_factor { | ||||||
| 		m.expand() | 		m.expand() | ||||||
| 	} | 	} | ||||||
| 	mut index, mut meta := m.key_to_index(key) | 	mut index, mut meta := m.key_to_index(&key) | ||||||
| 	index, meta = m.meta_less(index, meta) | 	index, meta = m.meta_less(index, meta) | ||||||
| 	// While we might have a match
 | 	// While we might have a match
 | ||||||
| 	for meta == unsafe {m.metas[index]} { | 	for meta == unsafe {m.metas[index]} { | ||||||
| 		kv_index := int(unsafe {m.metas[index + 1]}) | 		kv_index := int(unsafe {m.metas[index + 1]}) | ||||||
| 		pkey := unsafe {&string(m.key_values.key(kv_index))} | 		pkey := unsafe {m.key_values.key(kv_index)} | ||||||
| 		if fast_string_eq(key, *pkey) { | 		if m.keys_eq(&key, pkey) { | ||||||
| 			unsafe { | 			unsafe { | ||||||
| 				pval := pkey + 1 // skip string
 | 				pval := byteptr(pkey) + m.key_bytes | ||||||
| 				C.memcpy(pval, value, m.value_bytes) | 				C.memcpy(pval, value, m.value_bytes) | ||||||
| 			} | 			} | ||||||
| 			return | 			return | ||||||
|  | @ -327,7 +338,7 @@ fn (mut m map) set(k string, value voidptr) { | ||||||
| 		index += 2 | 		index += 2 | ||||||
| 		meta += probe_inc | 		meta += probe_inc | ||||||
| 	} | 	} | ||||||
| 	kv_index := m.key_values.push(key, value) | 	kv_index := m.key_values.push(&key, value) | ||||||
| 	m.meta_greater(index, meta, u32(kv_index)) | 	m.meta_greater(index, meta, u32(kv_index)) | ||||||
| 	m.len++ | 	m.len++ | ||||||
| } | } | ||||||
|  | @ -363,8 +374,8 @@ fn (mut m map) rehash() { | ||||||
| 		if !m.key_values.has_index(i) { | 		if !m.key_values.has_index(i) { | ||||||
| 			continue | 			continue | ||||||
| 		} | 		} | ||||||
| 		pkey := unsafe {&string(m.key_values.key(i))} | 		pkey := unsafe {m.key_values.key(i)} | ||||||
| 		mut index, mut meta := m.key_to_index(*pkey) | 		mut index, mut meta := m.key_to_index(pkey) | ||||||
| 		index, meta = m.meta_less(index, meta) | 		index, meta = m.meta_less(index, meta) | ||||||
| 		m.meta_greater(index, meta, u32(i)) | 		m.meta_greater(index, meta, u32(i)) | ||||||
| 	} | 	} | ||||||
|  | @ -398,12 +409,12 @@ fn (mut m map) cached_rehash(old_cap u32) { | ||||||
| // If the key exists, its respective value is returned.
 | // If the key exists, its respective value is returned.
 | ||||||
| fn (mut m map) get_and_set(key string, zero voidptr) voidptr { | fn (mut m map) get_and_set(key string, zero voidptr) voidptr { | ||||||
| 	for { | 	for { | ||||||
| 		mut index, mut meta := m.key_to_index(key) | 		mut index, mut meta := m.key_to_index(&key) | ||||||
| 		for { | 		for { | ||||||
| 			if meta == unsafe {m.metas[index]} { | 			if meta == unsafe {m.metas[index]} { | ||||||
| 				kv_index := int(unsafe {m.metas[index + 1]}) | 				kv_index := int(unsafe {m.metas[index + 1]}) | ||||||
| 				pkey := unsafe {&string(m.key_values.key(kv_index))} | 				pkey := unsafe {m.key_values.key(kv_index)} | ||||||
| 				if fast_string_eq(key, *pkey) { | 				if m.keys_eq(&key, pkey) { | ||||||
| 					return unsafe {byteptr(pkey) + m.key_values.key_bytes} | 					return unsafe {byteptr(pkey) + m.key_values.key_bytes} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | @ -424,12 +435,12 @@ fn (mut m map) get_and_set(key string, zero voidptr) voidptr { | ||||||
| // the method returns a reference to its mapped value.
 | // the method returns a reference to its mapped value.
 | ||||||
| // If not, a zero/default value is returned.
 | // If not, a zero/default value is returned.
 | ||||||
| fn (m map) get(key string, zero voidptr) voidptr { | fn (m map) get(key string, zero voidptr) voidptr { | ||||||
| 	mut index, mut meta := m.key_to_index(key) | 	mut index, mut meta := m.key_to_index(&key) | ||||||
| 	for { | 	for { | ||||||
| 		if meta == unsafe {m.metas[index]} { | 		if meta == unsafe {m.metas[index]} { | ||||||
| 			kv_index := int(unsafe {m.metas[index + 1]}) | 			kv_index := int(unsafe {m.metas[index + 1]}) | ||||||
| 			pkey := unsafe {&string(m.key_values.key(kv_index))} | 			pkey := unsafe {m.key_values.key(kv_index)} | ||||||
| 			if fast_string_eq(key, *pkey) { | 			if m.keys_eq(&key, pkey) { | ||||||
| 				return unsafe {byteptr(pkey) + m.key_values.key_bytes} | 				return unsafe {byteptr(pkey) + m.key_values.key_bytes} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -444,12 +455,12 @@ fn (m map) get(key string, zero voidptr) voidptr { | ||||||
| 
 | 
 | ||||||
| // Checks whether a particular key exists in the map.
 | // Checks whether a particular key exists in the map.
 | ||||||
| fn (m map) exists(key string) bool { | fn (m map) exists(key string) bool { | ||||||
| 	mut index, mut meta := m.key_to_index(key) | 	mut index, mut meta := m.key_to_index(&key) | ||||||
| 	for { | 	for { | ||||||
| 		if meta == unsafe {m.metas[index]} { | 		if meta == unsafe {m.metas[index]} { | ||||||
| 			kv_index := int(unsafe {m.metas[index + 1]}) | 			kv_index := int(unsafe {m.metas[index + 1]}) | ||||||
| 			pkey := unsafe {&string(m.key_values.key(kv_index))} | 			pkey := unsafe {m.key_values.key(kv_index)} | ||||||
| 			if fast_string_eq(key, *pkey) { | 			if m.keys_eq(&key, pkey) { | ||||||
| 				return true | 				return true | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | @ -464,13 +475,13 @@ fn (m map) exists(key string) bool { | ||||||
| 
 | 
 | ||||||
| // Removes the mapping of a particular key from the map.
 | // Removes the mapping of a particular key from the map.
 | ||||||
| pub fn (mut m map) delete(key string) { | pub fn (mut m map) delete(key string) { | ||||||
| 	mut index, mut meta := m.key_to_index(key) | 	mut index, mut meta := m.key_to_index(&key) | ||||||
| 	index, meta = m.meta_less(index, meta) | 	index, meta = m.meta_less(index, meta) | ||||||
| 	// Perform backwards shifting
 | 	// Perform backwards shifting
 | ||||||
| 	for meta == unsafe {m.metas[index]} { | 	for meta == unsafe {m.metas[index]} { | ||||||
| 		kv_index := int(unsafe {m.metas[index + 1]}) | 		kv_index := int(unsafe {m.metas[index + 1]}) | ||||||
| 		pkey := unsafe {&string(m.key_values.key(kv_index))} | 		pkey := unsafe {&string(m.key_values.key(kv_index))} | ||||||
| 		if fast_string_eq(key, *pkey) { | 		if m.keys_eq(&key, pkey) { | ||||||
| 			for (unsafe {m.metas[index + 2]} >> hashbits) > 1 { | 			for (unsafe {m.metas[index + 2]} >> hashbits) > 1 { | ||||||
| 				unsafe { | 				unsafe { | ||||||
| 					m.metas[index] = m.metas[index + 2] - probe_inc | 					m.metas[index] = m.metas[index + 2] - probe_inc | ||||||
|  | @ -554,6 +565,7 @@ pub fn (d DenseArray) clone() DenseArray { | ||||||
| pub fn (m map) clone() map { | pub fn (m map) clone() map { | ||||||
| 	metasize := int(sizeof(u32) * (m.cap + 2 + m.extra_metas)) | 	metasize := int(sizeof(u32) * (m.cap + 2 + m.extra_metas)) | ||||||
| 	res := map{ | 	res := map{ | ||||||
|  | 		key_bytes: m.key_bytes | ||||||
| 		value_bytes: m.value_bytes | 		value_bytes: m.value_bytes | ||||||
| 		cap: m.cap | 		cap: m.cap | ||||||
| 		cached_hashbits: m.cached_hashbits | 		cached_hashbits: m.cached_hashbits | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue