parent
44f4fdb003
commit
90d2fb46fc
1 changed files with 13 additions and 10 deletions
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
package akka.routing
|
package akka.routing
|
||||||
|
|
||||||
import scala.collection.immutable.TreeMap
|
import scala.collection.immutable.SortedMap
|
||||||
|
import scala.reflect.ClassTag
|
||||||
import java.util.Arrays
|
import java.util.Arrays
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -17,16 +18,18 @@ import java.util.Arrays
|
||||||
* hash, i.e. make sure it is different for different nodes.
|
* hash, i.e. make sure it is different for different nodes.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ConsistentHash[T] private (nodes: Map[Int, T], virtualNodesFactor: Int) {
|
class ConsistentHash[T: ClassTag] private (nodes: SortedMap[Int, T], virtualNodesFactor: Int) {
|
||||||
|
|
||||||
import ConsistentHash._
|
import ConsistentHash._
|
||||||
|
|
||||||
if (virtualNodesFactor < 1) throw new IllegalArgumentException("virtualNodesFactor must be >= 1")
|
if (virtualNodesFactor < 1) throw new IllegalArgumentException("virtualNodesFactor must be >= 1")
|
||||||
|
|
||||||
// sorted hash values of the nodes
|
// arrays for fast binary search and access
|
||||||
private val (nodeHashRing: Array[Int], nodeRing: Vector[T]) = {
|
// nodeHashRing is the sorted hash values of the nodes
|
||||||
val (nhr: IndexedSeq[Int], nr: IndexedSeq[AnyRef]) = nodes.toArray.sortBy(_._1).unzip
|
// nodeRing is the nodes sorted in the same order as nodeHashRing, i.e. same index
|
||||||
(nhr.toArray, Vector[T]() ++ nr)
|
private val (nodeHashRing: Array[Int], nodeRing: Array[T]) = {
|
||||||
|
val (nhr: Seq[Int], nr: Seq[T]) = nodes.toSeq.unzip
|
||||||
|
(nhr.toArray, nr.toArray)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -102,8 +105,8 @@ class ConsistentHash[T] private (nodes: Map[Int, T], virtualNodesFactor: Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
object ConsistentHash {
|
object ConsistentHash {
|
||||||
def apply[T](nodes: Iterable[T], virtualNodesFactor: Int) = {
|
def apply[T: ClassTag](nodes: Iterable[T], virtualNodesFactor: Int): ConsistentHash[T] = {
|
||||||
new ConsistentHash(TreeMap.empty[Int, T] ++
|
new ConsistentHash(SortedMap.empty[Int, T] ++
|
||||||
(for (node ← nodes; vnode ← 1 to virtualNodesFactor) yield (nodeHashFor(node, vnode) -> node)),
|
(for (node ← nodes; vnode ← 1 to virtualNodesFactor) yield (nodeHashFor(node, vnode) -> node)),
|
||||||
virtualNodesFactor)
|
virtualNodesFactor)
|
||||||
}
|
}
|
||||||
|
|
@ -112,9 +115,9 @@ object ConsistentHash {
|
||||||
* Factory method to create a ConsistentHash
|
* Factory method to create a ConsistentHash
|
||||||
* JAVA API
|
* JAVA API
|
||||||
*/
|
*/
|
||||||
def create[T](nodes: java.lang.Iterable[T], virtualNodesFactor: Int) = {
|
def create[T](nodes: java.lang.Iterable[T], virtualNodesFactor: Int): ConsistentHash[T] = {
|
||||||
import scala.collection.JavaConverters._
|
import scala.collection.JavaConverters._
|
||||||
apply(nodes.asScala, virtualNodesFactor)
|
apply(nodes.asScala, virtualNodesFactor)(ClassTag(classOf[Any].asInstanceOf[Class[T]]))
|
||||||
}
|
}
|
||||||
|
|
||||||
private def nodeHashFor(node: Any, vnode: Int): Int =
|
private def nodeHashFor(node: Any, vnode: Int): Int =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue