All Downloads are FREE. Search and download functionalities are using the official Maven repository.

akka.util.Unsafe.scala Maven / Gradle / Ivy

The newest version!
package akka.util

import scala.collection.mutable

import akka.actor.dungeon.AbstractActorCell
import akka.actor.dungeon.ChildrenContainer.EmptyChildrenContainer
import akka.actor.FunctionRef

object Unsafe {

    val unsafeVars: WeakMap[AnyRef, mutable.HashMap[Int, Any]] =
      new WeakMap[AnyRef, mutable.HashMap[Int, Any]]()

    def fallback(offset: Long) = {
      //Missing initializations...
      if (offset == AbstractActorCell.childrenOffset)
        EmptyChildrenContainer
      else if (offset == AbstractActorCell.nextNameOffset)
        0L
      else if (offset == AbstractActorCell.functionRefsOffset)
        Map.empty[String, FunctionRef]
      else null
    }

    def toAnyRef(a: Any): AnyRef =
      a.asInstanceOf[AnyRef]

    def safeGet(m: WeakMap[AnyRef, mutable.HashMap[Int, Any]], k: AnyRef):
      Option[mutable.HashMap[Int, Any]] = {
      if (m.has(k)) Some(m.get(k))
      else None
    }

    final val instance = new {

      def getObjectVolatile(o: Any, offset: Long): AnyRef = {
        safeGet(unsafeVars, toAnyRef(o))
          .map(_.get(offset.asInstanceOf[Int]))
          .flatten
          .getOrElse(fallback(offset)).asInstanceOf[AnyRef]
      }

      def compareAndSwapObject(o: Any, offset: Long, old: Any, next: Any) = {
        val key = offset.asInstanceOf[Int]
        if (next == null)
          safeGet(unsafeVars, toAnyRef(o))
            .map(_.remove(key))
        else {
          val old = safeGet(unsafeVars, toAnyRef(o))
          if (old.isDefined)
            old.get.update(key, next)
          else {
            val in = new mutable.HashMap[Int, Any]()
            in.update(key, next)
            unsafeVars.set(toAnyRef(o), in)
          }
        }
        true
      }

      def getAndSetObject(o: Any, offset: Long, next: Any) = {
        val key = offset.asInstanceOf[Int]
        val ret = safeGet(unsafeVars, toAnyRef(o))
          .map(_.get(key))
          .flatten
          .getOrElse(fallback(offset))

        if (next == null)
          safeGet(unsafeVars, toAnyRef(o))
            .map(_.remove(key))
        else {
          val old = safeGet(unsafeVars, toAnyRef(o))
          if (old.isDefined)
            old.get.update(key, next)
          else {
            val in = new mutable.HashMap[Int, Any]()
            in.update(key, next)
            unsafeVars.set(toAnyRef(o), in)
          }
        }
        ret
      }

      def getAndAddLong(o: Any, offset: Long, next: Long) = {
        val key = offset.asInstanceOf[Int]
        val ret = safeGet(unsafeVars, toAnyRef(o))
          .map(_.get(key))
          .flatten
          .map(_.asInstanceOf[Long])
          .getOrElse(0L)

        if (next == 0L)
          safeGet(unsafeVars, toAnyRef(o))
            .map(_.remove(key))
        else {
          val old = safeGet(unsafeVars, toAnyRef(o))
          if (old.isDefined)
            old.get.update(key, ret + next)
          else {
            val in = new mutable.HashMap[Int, Any]()
            in.update(key, next)
            unsafeVars.set(toAnyRef(o), in)
          }
        }
        ret
      }

      def getAndAddInt(o: Any, offset: Long, next: Int) = {
        val key = offset.asInstanceOf[Int]
        val ret = safeGet(unsafeVars, toAnyRef(o))
          .map(_.get(key))
          .flatten
          .map(_.asInstanceOf[Int])
          .getOrElse(0)

        if (next == 0)
          safeGet(unsafeVars, toAnyRef(o))
            .map(_.remove(key))
        else {
          val old = safeGet(unsafeVars, toAnyRef(o))
          if (old.isDefined)
            old.get.update(key, ret + next)
          else {
            val in = new mutable.HashMap[Int, Any]()
            in.update(key, next)
            unsafeVars.set(toAnyRef(o), in)
          }
        }
        ret
      }

      def putObjectVolatile(o: Any, offset: Long, next: Any) = {
        val key = offset.asInstanceOf[Int]

        if (next == null)
          safeGet(unsafeVars, toAnyRef(o))
            .map(_.remove(key))
        else {
          val old = safeGet(unsafeVars, toAnyRef(o))
          if (old.isDefined)
            old.get.update(key, next)
          else {
            val in = new mutable.HashMap[Int, Any]()
            in.update(key, next)
            unsafeVars.set(toAnyRef(o), in)
          }
        }
      }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy