blob: 860bf707355773fd752343f840c2f0c55b1efb1b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.s2graph.core.schema
import org.apache.s2graph.core.GraphUtil
import scalikejdbc._
import scala.util.{Try, Random}
object Experiment extends SQLSyntaxSupport[Experiment] {
import Schema._
val className = Experiment.getClass.getSimpleName
val ImpressionKey = "S2-Impression-Id"
val ImpressionId = "Impression-Id"
def apply(rs: WrappedResultSet): Experiment = {
Experiment(rs.intOpt("id"),
rs.int("service_id"),
rs.string("name"),
rs.string("description"),
rs.string("experiment_type"),
rs.int("total_modular"))
}
def finds(serviceId: Int)(implicit session: DBSession = AutoSession): List[Experiment] = {
val cacheKey = className + "serviceId=" + serviceId
withCaches(cacheKey, false) {
sql"""select * from experiments where service_id = ${serviceId}"""
.map { rs => Experiment(rs) }.list().apply()
}
}
def findBy(serviceId: Int, name: String)(implicit session: DBSession = AutoSession): Option[Experiment] = {
val cacheKey = className + "serviceId=" + serviceId + ":name=" + name
withCache(cacheKey, false) {
sql"""select * from experiments where service_id = ${serviceId} and name = ${name}"""
.map { rs => Experiment(rs) }.single.apply
}
}
def findById(id: Int)(implicit session: DBSession = AutoSession): Option[Experiment] = {
val cacheKey = className + "id=" + id
withCache(cacheKey, false)(
sql"""select * from experiments where id = ${id}"""
.map { rs => Experiment(rs) }.single.apply
)
}
def insert(service: Service, name: String, description: String, experimentType: String = "t", totalModular: Int = 100)
(implicit session: DBSession = AutoSession): Try[Experiment] = {
Try {
sql"""INSERT INTO experiments(service_id, service_name, `name`, description, experiment_type, total_modular)
VALUES(${service.id.get}, ${service.serviceName}, $name, $description, $experimentType, $totalModular)"""
.updateAndReturnGeneratedKey().apply()
}.map { newId =>
Experiment(Some(newId.toInt), service.id.get, name, description, experimentType, totalModular)
}
}
}
case class Experiment(id: Option[Int],
serviceId: Int,
name: String,
description: String,
experimentType: String,
totalModular: Int) {
def buckets = Bucket.finds(id.get)
def rangeBuckets = for {
bucket <- buckets
range <- bucket.rangeOpt
} yield range -> bucket
def findBucket(uuid: String, impIdOpt: Option[String] = None): Option[Bucket] = {
impIdOpt match {
case Some(impId) => Bucket.findByImpressionId(impId)
case None =>
val seed = experimentType match {
case "u" => (GraphUtil.murmur3(uuid) % totalModular) + 1
case _ => Random.nextInt(totalModular) + 1
}
findBucket(seed)
}
}
def findBucket(uuidMod: Int): Option[Bucket] = {
rangeBuckets.find { case ((from, to), bucket) =>
from <= uuidMod && uuidMod <= to
}.map(_._2)
}
}