package ru.dbotthepony.kstarbound.test

import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import ru.dbotthepony.kstarbound.util.HashTableInterner
import ru.dbotthepony.kstarbound.util.random.MWCRandom
import java.util.concurrent.atomic.AtomicInteger
import java.util.random.RandomGenerator

object InternerTest {
	@Test
	@DisplayName("Interner stress test in high concurrency")
	fun test() {
		val interner = HashTableInterner<String>(5)
		val threads = ArrayList<Thread>()
		val misses = AtomicInteger()

		for (i in 0 until 8) {
			threads.add(Thread {
				val rand = MWCRandom()

				for (i2 in 0 until 100_000) {
					val v = rand.nextInt()
					val s1 = "String$v"
					val s2 = "String$v"

					check(s1 !== s2)

					if (interner.intern(s1) !== interner.intern(s2)) {
						misses.incrementAndGet()
					}
				}
			})
		}

		threads.forEach { it.start() }
		threads.forEach { it.join() }

		if (misses.get() != 0) {
			throw IllegalStateException("Interner stress test failed ($misses misses)")
		}
	}
}
