Bladeren bron

Inline map gets; cast explicitly on TOMBSTONE checking

gingerBill 2 jaren geleden
bovenliggende
commit
bbb2164e38
3 gewijzigde bestanden met toevoegingen van 36 en 16 verwijderingen
  1. 19 8
      src/ptr_map.cpp
  2. 5 5
      src/ptr_set.cpp
  3. 12 3
      src/string_map.cpp

+ 19 - 8
src/ptr_map.cpp

@@ -112,11 +112,12 @@ gb_internal MapFindResult map__find(PtrMap<K, V> *h, K key) {
 	fr.hash_index = cast(MapIndex)(hash & (h->hashes.count-1));
 	fr.entry_index = h->hashes.data[fr.hash_index];
 	while (fr.entry_index != MAP_SENTINEL) {
-		if (h->entries.data[fr.entry_index].key == key) {
+		auto *entry = &h->entries.data[fr.entry_index];
+		if (entry->key == key) {
 			return fr;
 		}
 		fr.entry_prev = fr.entry_index;
-		fr.entry_index = h->entries.data[fr.entry_index].next;
+		fr.entry_index = entry->next;
 	}
 	return fr;
 }
@@ -190,18 +191,28 @@ gb_internal void map_rehash(PtrMap<K, V> *h, isize new_count) {
 
 template <typename K, typename V>
 gb_internal V *map_get(PtrMap<K, V> *h, K key) {
-	MapIndex index = map__find(h, key).entry_index;
-	if (index != MAP_SENTINEL) {
-		return &h->entries.data[index].value;
+	MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL};
+	if (h->hashes.count != 0) {
+		u32 hash = ptr_map_hash_key(key);
+		fr.hash_index = cast(MapIndex)(hash & (h->hashes.count-1));
+		fr.entry_index = h->hashes.data[fr.hash_index];
+		while (fr.entry_index != MAP_SENTINEL) {
+			auto *entry = &h->entries.data[fr.entry_index];
+			if (entry->key == key) {
+				return &entry->value;
+			}
+			fr.entry_prev = fr.entry_index;
+			fr.entry_index = entry->next;
+		}
 	}
 	return nullptr;
 }
 
 template <typename K, typename V>
 gb_internal V &map_must_get(PtrMap<K, V> *h, K key) {
-	MapIndex index = map__find(h, key).entry_index;
-	GB_ASSERT(index != MAP_SENTINEL);
-	return h->entries.data[index].value;
+	V *ptr = map_get(h, key);
+	GB_ASSERT(ptr != nullptr);
+	return *ptr;
 }
 
 template <typename K, typename V>

+ 5 - 5
src/ptr_set.cpp

@@ -12,7 +12,7 @@ struct TypeIsPointer<T *> {
 template <typename T>
 struct PtrSet {
 	static_assert(TypeIsPointer<T>::value, "PtrSet::T must be a pointer");
-	static constexpr T TOMBSTONE = (T)(~uintptr(0));
+	static constexpr uintptr TOMBSTONE = ~(uintptr)(0ull);
 
 	T *   keys;
 	usize count;
@@ -133,7 +133,7 @@ gb_internal bool ptr_set_update(PtrSet<T> *s, T ptr) { // returns true if it pre
 	for (usize i = 0; i < s->capacity; i++) {
 		T *key = &s->keys[hash_index];
 		GB_ASSERT(*key != ptr);
-		if (*key == PtrSet<T>::TOMBSTONE || *key == nullptr) {
+		if (*key == (T)PtrSet<T>::TOMBSTONE || *key == nullptr) {
 			*key = ptr;
 			s->count++;
 			return false;
@@ -157,7 +157,7 @@ gb_internal void ptr_set_remove(PtrSet<T> *s, T ptr) {
 	isize index = ptr_set__find(s, ptr);
 	if (index >= 0) {
 		GB_ASSERT(s->count > 0);
-		s->keys[index] = PtrSet<T>::TOMBSTONE;
+		s->keys[index] = (T)PtrSet<T>::TOMBSTONE;
 		s->count--;
 	}
 }
@@ -180,7 +180,7 @@ struct PtrSetIterator {
 				return *this;
 			}
 			T key = set->keys[index];
-			if (key != nullptr && key != PtrSet<T>::TOMBSTONE) {
+			if (key != nullptr && key != (T)PtrSet<T>::TOMBSTONE) {
 				return *this;
 			}
 		}
@@ -202,7 +202,7 @@ gb_internal PtrSetIterator<T> begin(PtrSet<T> &set) noexcept {
 	usize index = 0;
 	while (index < set.capacity) {
 		T key = set.keys[index];
-		if (key != nullptr && key != PtrSet<T>::TOMBSTONE) {
+		if (key != nullptr && key != (T)PtrSet<T>::TOMBSTONE) {
 			break;
 		}
 		index++;

+ 12 - 3
src/string_map.cpp

@@ -180,9 +180,18 @@ gb_internal void string_map_rehash(StringMap<T> *h, isize new_count) {
 
 template <typename T>
 gb_internal T *string_map_get(StringMap<T> *h, StringHashKey const &key) {
-	isize index = string_map__find(h, key).entry_index;
-	if (index != MAP_SENTINEL) {
-		return &h->entries.data[index].value;
+	MapFindResult fr = {MAP_SENTINEL, MAP_SENTINEL, MAP_SENTINEL};
+	if (h->hashes.count != 0) {
+		fr.hash_index = cast(MapIndex)(key.hash & (h->hashes.count-1));
+		fr.entry_index = h->hashes.data[fr.hash_index];
+		while (fr.entry_index != MAP_SENTINEL) {
+			auto *entry = &h->entries.data[fr.entry_index];
+			if (string_hash_key_equal(entry->key, key)) {
+				return &entry->value;
+			}
+			fr.entry_prev = fr.entry_index;
+			fr.entry_index = entry->next;
+		}
 	}
 	return nullptr;
 }