Github user dszeto commented on a diff in the pull request:

    
https://github.com/apache/incubator-predictionio/pull/424#discussion_r134588503
  
    --- Diff: 
data/src/main/scala/org/apache/predictionio/data/store/Common.scala ---
    @@ -19,35 +19,46 @@
     package org.apache.predictionio.data.store
     
     import org.apache.predictionio.data.storage.Storage
    +import scala.collection.mutable
     import grizzled.slf4j.Logger
     
     private[predictionio] object Common {
     
       @transient lazy val logger = Logger[this.type]
       @transient lazy private val appsDb = Storage.getMetaDataApps()
       @transient lazy private val channelsDb = Storage.getMetaDataChannels()
    +  // Memoize app & channel name-to-ID resolution to avoid excessive 
storage IO
    +  @transient lazy val appNameToIdCache =
    +    mutable.Map[(String, Option[String]), (Int, Option[Int])]()
     
       /* throw exception if invalid app name or channel name */
       def appNameToId(appName: String, channelName: Option[String]): (Int, 
Option[Int]) = {
    -    val appOpt = appsDb.getByName(appName)
    -
    -    appOpt.map { app =>
    -      val channelMap: Map[String, Int] = channelsDb.getByAppid(app.id)
    -        .map(c => (c.name, c.id)).toMap
    -
    -      val channelId: Option[Int] = channelName.map { ch =>
    -        if (channelMap.contains(ch)) {
    -          channelMap(ch)
    -        } else {
    -          logger.error(s"Invalid channel name ${ch}.")
    -          throw new IllegalArgumentException(s"Invalid channel name 
${ch}.")
    +    val cacheHit = appNameToIdCache.get(appName, channelName)
    +    cacheHit match {
    +      case Some((a: Int, c: Option[Int])) => (a,c)
    +      case None => {
    +        val appOpt = appsDb.getByName(appName)
    +
    +        appOpt.map { app =>
    +          val channelMap: Map[String, Int] = channelsDb.getByAppid(app.id)
    +            .map(c => (c.name, c.id)).toMap
    +
    +          val channelId: Option[Int] = channelName.map { ch =>
    +            if (channelMap.contains(ch)) {
    +              channelMap(ch)
    +            } else {
    +              logger.error(s"Invalid channel name ${ch}.")
    +              throw new IllegalArgumentException(s"Invalid channel name 
${ch}.")
    +            }
    +          }
    +
    +          appNameToIdCache((appName, channelName)) = (app.id, channelId)
    +          (app.id, channelId)
    +        }.getOrElse {
    +          logger.error(s"Invalid app name ${appName}")
    +          throw new IllegalArgumentException(s"Invalid app name 
${appName}")
    --- End diff --
    
    It looks like this whole block can be simplified to
    
    ```scala
    appNameToIdCache.getOrElseUpdate((appName, channelName), {
      val appOpt = ...
      appOpt map { app =>
        ...
        val channelId: Option[Int] = ...
        // do not need to set appNameToIdCache here manually
        (app.id, channelId)
      } getOrElse {
        ...
      }
    })
    ```


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastruct...@apache.org or file a JIRA ticket
with INFRA.
---

Reply via email to