
// either i or glslang preprocessor suck, could not make nicer function signature generation working:(

#ifdef GPUHashMap_InsertIMPL
GPUHashMapInsertResult GPUHashMap_InsertIMPL(uint64_t key)
{
	GPUHashMapInsertResult res;
	res.slot      = -1;
	res.duplicate = false;

	uint64_t hash = GPUHashMapHash64(key);
	uint slot = uint(hash & (GPUHashMap_MapName.header.capacity - 1));

	// TODO: Add version which deals better with highly loaded hashmap at the cost of correctness
	// Linear probing is not super great (sometimes)
	while (true)
	{
		uint64_t prev = atomicCompSwap(GPUHashMap_MapName.keys[slot], GPUHashMap_EmptyKey64, key);
		if (prev == GPUHashMap_EmptyKey64 || prev == key)
		{
			//GPUHashMap_MapName.keys[slot].value = value;
			res.slot      = slot;
			res.duplicate = prev == key;
			return res;
		}

		slot = (slot + 1) & (GPUHashMap_MapName.header.capacity - 1);
	}

	return res;
}
#endif

#ifdef GPUHashMap_LookupIMPL
GPUHashMapLookupResult GPUHashMap_LookupIMPL(uint64_t key)
{
	GPUHashMapLookupResult res;
	res.slot  = 0;
	res.found = false;

	uint64_t hash = GPUHashMapHash64(key);
	uint slot = uint(hash & (GPUHashMap_MapName.header.capacity - 1));

	// TODO: Add version which deals better with highly loaded hashmap at the cost of correctness
	// Linear probing is not super great (sometimes)
	while (true)
	{
		uint64_t map_key = GPUHashMap_MapName.keys[slot];
		if (map_key == GPUHashMap_EmptyKey64)
			break;

		if (map_key == key)
		{
			res.slot  = slot;
			res.found = true;
			return res;
		}

		slot = (slot + 1) & (GPUHashMap_MapName.header.capacity - 1);
	}
	return res;
}
#endif