I have a requirement to be able to count number of times AtomicReference[V].get
is called in a class that has as field an array of wildcarded atomic references.
To that end, first, I've extended java's AtomicReference[V]:
import java.util.concurrent.atomic.{AtomicInteger => AInt, AtomicReference => ARef}
class MyAtomicReference[V] extends ARef[V]{
private val getCounter: AInt = new AInt(0)
def getAndListen(): V = {
getCounter.getAndIncrement()
super.get()
}
def counter(): Int = getCounter.get()
def resetCounter(): Unit = getCounter.set(0)
}
Then I've added trait AtomicRefCounter
which declares the method that I would wish to invoke:
import simulacrum.typeclass
@typeclass trait AtomicRefCounter [R[_], T] {
def countGets(container: R[T]): Int
}
Lastly, I've defined a default AtomicArrayRefCounter
in the object DefaultAtomicRefCounters
:
object DefaultAtomicRefCounters {
implicit val arrayOfAtomicsTraverser = new AtomicRefCounter[Array, MyAtomicReference[_]] {
override def countGets(container: Array[MyAtomicReference[_]]): Int = container map(_.counter()) sum
}
}
Despite that when I try to call the traverseAtomics() on a corresponding array in a test, I do not see it (I am using Intellij IDEA):
behavior of "removeO1"
"method" should "remove an element from the pool with time O(1)" in new IntPoolBuilder {
import org.learningconcurrency.traditional_concurrency.helpers.DefaultAtomicRefCounters._
pool.buckets.countGet
}
A piece of advice on what I am missing would really help. Usage of simulacrum is not mandatory - if you feel you know how to solve this without it, I would love to hear that.
update:
This is how the buckets
are implemented:
class Pool[T] {
type TimeStampedList = (List[T], Long)
val parallelism: Int = Runtime.getRuntime.availableProcessors * 32
val buckets = new Array[MyAtomicReference[TimeStampedList]](parallelism)
...