change IdentityHashComparator to fall back to a real one
System.identityHashCode is not guaranteed to be consistent with equals() (cannot be, just imagine more than 2^32 objects); fix it by checking equals in case 0 would be returned and fall back to a real Comparator in case that’s needed.
This commit is contained in:
parent
34d3c0ad15
commit
43913b0490
2 changed files with 19 additions and 5 deletions
|
|
@ -9,7 +9,8 @@ import akka.actor.{ ActorCell, ActorRef }
|
|||
import java.util.concurrent.{ LinkedBlockingQueue, ConcurrentLinkedQueue, ConcurrentSkipListSet }
|
||||
import annotation.tailrec
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import akka.util.Duration
|
||||
import akka.util.{ Duration, Helpers }
|
||||
import java.util.Comparator
|
||||
|
||||
/**
|
||||
* An executor based event driven dispatcher which will try to redistribute work from busy actors to idle actors. It is assumed
|
||||
|
|
@ -35,10 +36,13 @@ class BalancingDispatcher(
|
|||
_shutdownTimeout: Duration)
|
||||
extends Dispatcher(_prerequisites, _id, throughput, throughputDeadlineTime, mailboxType, _executorServiceFactoryProvider, _shutdownTimeout) {
|
||||
|
||||
val buddies = new ConcurrentSkipListSet[ActorCell](akka.util.Helpers.IdentityHashComparator)
|
||||
val buddies = new ConcurrentSkipListSet[ActorCell](
|
||||
Helpers.identityHashComparator(new Comparator[ActorCell] {
|
||||
def compare(l: ActorCell, r: ActorCell) = l.self.path compareTo r.self.path
|
||||
}))
|
||||
|
||||
val messageQueue: MessageQueue = mailboxType match {
|
||||
case u: UnboundedMailbox ⇒ new QueueBasedMessageQueue with UnboundedMessageQueueSemantics {
|
||||
case _: UnboundedMailbox ⇒ new QueueBasedMessageQueue with UnboundedMessageQueueSemantics {
|
||||
final val queue = new ConcurrentLinkedQueue[Envelope]
|
||||
}
|
||||
case BoundedMailbox(cap, timeout) ⇒ new QueueBasedMessageQueue with BoundedMessageQueueSemantics {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,18 @@ object Helpers {
|
|||
if (diff > 0) 1 else if (diff < 0) -1 else 0
|
||||
}
|
||||
|
||||
val IdentityHashComparator = new Comparator[AnyRef] {
|
||||
def compare(a: AnyRef, b: AnyRef): Int = compareIdentityHash(a, b)
|
||||
/**
|
||||
* Create a comparator which will efficiently use `System.identityHashCode`,
|
||||
* unless that happens to be the same for two non-equals objects, in which
|
||||
* case the supplied “real” comparator is used; the comparator must be
|
||||
* consistent with equals, otherwise it would not be an enhancement over
|
||||
* the identityHashCode.
|
||||
*/
|
||||
def identityHashComparator[T <: AnyRef](comp: Comparator[T]): Comparator[T] = new Comparator[T] {
|
||||
def compare(a: T, b: T): Int = compareIdentityHash(a, b) match {
|
||||
case 0 if a != b ⇒ comp.compare(a, b)
|
||||
case x ⇒ x
|
||||
}
|
||||
}
|
||||
|
||||
final val base64chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+~"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue