<commit_before>package sp.models

import akka.actor._
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
import sp.domain._
import sp.system.messages._
import akka.persistence._

/**
 * Created by Kristofer on 2014-06-12.
 */
class ModelActor(val model: ID) extends PersistentActor with ModelActorState  {
  override def persistenceId = model.toString()
  implicit val timeout = Timeout(7 seconds)
  import context.dispatcher

  def receiveCommand = {
    //case mess @ _ if {println(s"model got: $mess from $sender"); false} => Unit
    case upd @ UpdateIDs(m, v, ids) => {
      //println(s"update me: $upd")
      val reply = sender
      createDiffUpd(ids, v) match {
        case Right(diff) => {
          persist(diff)(d =>{
            updateState(d)
            //reply ! SPIDs(diff.updatedItems)
            reply ! SPIDs(ids)
          })
        }
        case Left(error) => reply ! error
      }
    }
    case DeleteIDs(m, dels) => {
      val reply = sender
      createDiffDel(dels.toSet) match {
        case Right(diff) => {
          persist(diff)(d =>{
            updateState(d)
            reply ! SPIDs(diff.deletedItems)
          })
        }
        case Left(error) => reply ! error
      }
    }

    case UpdateModelInfo(_, ModelInfo(m, newName, v, attribute)) => {
      val reply = sender
      val diff = ModelDiff(model, List(), List(), state.version, state.version + 1, newName, (attribute + ("time", DatePrimitive.now)))

      persist(diff)( d => {
          updateState(d)
          reply ! getModelInfo
      })
    }

    case Revert(_, v) => {
      val reply = sender
      val view = context.actorOf(sp.models.ModelView.props(model, v, "modelReverter"))
      val infoF = view ? GetModels
      val itemsF = view ? GetIds(model, List())
      for {
        info <- infoF.mapTo[ModelInfo]
        items <- itemsF.mapTo[SPIDs]
      } yield {
        val itemMap = items.items.map(x=> x.id -> x) toMap
        val upd = itemMap.filter{case (id, x) =>
          !state.idMap.contains(id) || state.idMap(id) != x
        }
        val del = state.idMap.filter{case (id, x) =>
          !itemMap.contains(id)
        }
        val diff = ModelDiff(
          model,
          upd.values.toList,
          del.values.toList,
          state.version,
          state.version + 1,
          info.name,
          SPAttributes(info.attributes.attrs + ("time" -> DatePrimitive.now))
        )
        self ! (diff, reply)
      }
    }

    case (diff: ModelDiff, reply: ActorRef) => {
      persist(diff)(d =>{
        updateState(d)
        reply ! getModelInfo
      })
    }

    /**
     * TODO: This is a temporary solution. When we go more production
     * the Query should be in a separate actor. 140630
     * Query handled in trait below
     */
    case mess: ModelQuery => {
      queryMessage(sender, mess)
    }
    case "printState" => println(s"$model: $state")
    case "snapshot" => saveSnapshot(state)
    case GetModels => sender ! getModelInfo
  }

  def receiveRecover = {
    case d: ModelDiff  => {
      updateState(d)
    }
    case SnapshotOffer(_, snapshot: ModelState) => state = snapshot
  }

}

object ModelActor{
  def props(model: ID) = Props(classOf[ModelActor], model)
}

trait ModelActorState  {
  val model: ID
  //def persist[A](event: A)(handler: A ⇒ Unit)

  private val noDiffInMemory = 50;

  // A model state
  case class ModelState(version: Long, idMap: Map[ID, IDAble], diff: Map[Long, ModelDiff], attributes: SPAttributes, name: String){
    lazy val operations = idMap filter (_._2.isInstanceOf[Operation])
    lazy val things = idMap filter (_._2.isInstanceOf[Thing])
    lazy val specifications = idMap filter (_._2.isInstanceOf[Specification])
    lazy val results = idMap filter (_._2.isInstanceOf[Result])
    lazy val items = idMap.values.toSet
  }

  var state = ModelState(0, Map(), Map(), Attr(), "noName")


  def queryMessage(reply: ActorRef, mess: ModelQuery) = {
    mess match {
      case GetIds(_, ids) => {
        if (ids.isEmpty) reply ! SPIDs(state.idMap.values.toList)
        else {
          ids foreach(id=> if (!state.idMap.contains(id)) reply ! MissingID(id, model))
          val res = for {
            i <- ids
            x <- state.idMap.get(i)
          } yield x
          reply ! SPIDs(res)
        }
      }
      case GetOperations(_, f) => {
        val res = state.operations.values filter f
        reply ! SPIDs(res.toList)
      }
      case GetThings(_, f) => {<commit_msg>Changed ModelActorState default version back to 1<commit_after>package sp.models

import akka.actor._
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
import sp.domain._
import sp.system.messages._
import akka.persistence._

/**
 * Created by Kristofer on 2014-06-12.
 */
class ModelActor(val model: ID) extends PersistentActor with ModelActorState  {
  override def persistenceId = model.toString()
  implicit val timeout = Timeout(7 seconds)
  import context.dispatcher

  def receiveCommand = {
    //case mess @ _ if {println(s"model got: $mess from $sender"); false} => Unit
    case upd @ UpdateIDs(m, v, ids) => {
      //println(s"update me: $upd")
      val reply = sender
      createDiffUpd(ids, v) match {
        case Right(diff) => {
          persist(diff)(d =>{
            updateState(d)
            //reply ! SPIDs(diff.updatedItems)
            reply ! SPIDs(ids)
          })
        }
        case Left(error) => reply ! error
      }
    }
    case DeleteIDs(m, dels) => {
      val reply = sender
      createDiffDel(dels.toSet) match {
        case Right(diff) => {
          persist(diff)(d =>{
            updateState(d)
            reply ! SPIDs(diff.deletedItems)
          })
        }
        case Left(error) => reply ! error
      }
    }

    case UpdateModelInfo(_, ModelInfo(m, newName, v, attribute)) => {
      val reply = sender
      val diff = ModelDiff(model, List(), List(), state.version, state.version + 1, newName, (attribute + ("time", DatePrimitive.now)))

      persist(diff)( d => {
          updateState(d)
          reply ! getModelInfo
      })
    }

    case Revert(_, v) => {
      val reply = sender
      val view = context.actorOf(sp.models.ModelView.props(model, v, "modelReverter"))
      val infoF = view ? GetModels
      val itemsF = view ? GetIds(model, List())
      for {
        info <- infoF.mapTo[ModelInfo]
        items <- itemsF.mapTo[SPIDs]
      } yield {
        val itemMap = items.items.map(x=> x.id -> x) toMap
        val upd = itemMap.filter{case (id, x) =>
          !state.idMap.contains(id) || state.idMap(id) != x
        }
        val del = state.idMap.filter{case (id, x) =>
          !itemMap.contains(id)
        }
        val diff = ModelDiff(
          model,
          upd.values.toList,
          del.values.toList,
          state.version,
          state.version + 1,
          info.name,
          SPAttributes(info.attributes.attrs + ("time" -> DatePrimitive.now))
        )
        self ! (diff, reply)
      }
    }

    case (diff: ModelDiff, reply: ActorRef) => {
      persist(diff)(d =>{
        updateState(d)
        reply ! getModelInfo
      })
    }

    /**
     * TODO: This is a temporary solution. When we go more production
     * the Query should be in a separate actor. 140630
     * Query handled in trait below
     */
    case mess: ModelQuery => {
      queryMessage(sender, mess)
    }
    case "printState" => println(s"$model: $state")
    case "snapshot" => saveSnapshot(state)
    case GetModels => sender ! getModelInfo
  }

  def receiveRecover = {
    case d: ModelDiff  => {
      updateState(d)
    }
    case SnapshotOffer(_, snapshot: ModelState) => state = snapshot
  }

}

object ModelActor{
  def props(model: ID) = Props(classOf[ModelActor], model)
}

trait ModelActorState  {
  val model: ID
  //def persist[A](event: A)(handler: A ⇒ Unit)

  private val noDiffInMemory = 50;

  // A model state
  case class ModelState(version: Long, idMap: Map[ID, IDAble], diff: Map[Long, ModelDiff], attributes: SPAttributes, name: String){
    lazy val operations = idMap filter (_._2.isInstanceOf[Operation])
    lazy val things = idMap filter (_._2.isInstanceOf[Thing])
    lazy val specifications = idMap filter (_._2.isInstanceOf[Specification])
    lazy val results = idMap filter (_._2.isInstanceOf[Result])
    lazy val items = idMap.values.toSet
  }

  var state = ModelState(1, Map(), Map(), Attr(), "noName")


  def queryMessage(reply: ActorRef, mess: ModelQuery) = {
    mess match {
      case GetIds(_, ids) => {
        if (ids.isEmpty) reply ! SPIDs(state.idMap.values.toList)
        else {
          ids foreach(id=> if (!state.idMap.contains(id)) reply ! MissingID(id, model))
          val res = for {
            i <- ids
            x <- state.idMap.get(i)
          } yield x
          reply ! SPIDs(res)
        }
      }
      case GetOperations(_, f) => {
        val res = state.operations.values filter f
        reply ! SPIDs(res.toList)
      }
      case GetThings(_, f) => {
{'fraction_non_alphanumeric': 0.12450505939287286, 'fraction_numerical': 0.005389353277606687, 'mean_word_length': 2.2256119191202552, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6879934', 'n_tokens_mistral': 2876, 'n_tokens_neox': 2828, 'n_words': 738}