revamp akka.util.Duration
- add comparison and arithmetic - add infinite subtypes
This commit is contained in:
parent
57d0e85a9a
commit
c7150f6da3
1 changed files with 201 additions and 3 deletions
|
|
@ -7,8 +7,8 @@ package akka.util
|
|||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object Duration {
|
||||
def apply(length: Long, unit: TimeUnit) = new Duration(length, unit)
|
||||
def apply(length: Long, unit: String) = new Duration(length, timeUnit(unit))
|
||||
def apply(length: Long, unit: TimeUnit) : Duration = new FiniteDuration(length, unit)
|
||||
def apply(length: Long, unit: String) : Duration = new FiniteDuration(length, timeUnit(unit))
|
||||
|
||||
def timeUnit(unit: String) = unit.toLowerCase match {
|
||||
case "nanoseconds" | "nanos" | "nanosecond" | "nano" => TimeUnit.NANOSECONDS
|
||||
|
|
@ -16,6 +16,45 @@ object Duration {
|
|||
case "milliseconds" | "millis" | "millisecond" | "milli" => TimeUnit.MILLISECONDS
|
||||
case _ => TimeUnit.SECONDS
|
||||
}
|
||||
|
||||
trait Infinite {
|
||||
this : Duration =>
|
||||
|
||||
override def equals(other : Any) = false
|
||||
|
||||
def +(other : Duration) : Duration = this
|
||||
def -(other : Duration) : Duration = this
|
||||
def *(other : Double) : Duration = this
|
||||
def /(other : Double) : Duration = this
|
||||
|
||||
def finite_? = false
|
||||
|
||||
def length : Long = error("length not allowed on infinite Durations")
|
||||
def unit : TimeUnit = error("unit not allowed on infinite Durations")
|
||||
def toNanos : Long = error("toNanos not allowed on infinite Durations")
|
||||
def toMicros : Long = error("toMicros not allowed on infinite Durations")
|
||||
def toMillis : Long = error("toMillis not allowed on infinite Durations")
|
||||
def toSeconds : Long = error("toSeconds not allowed on infinite Durations")
|
||||
}
|
||||
|
||||
object Inf extends Duration with Infinite {
|
||||
override def toString = "Duration.Inf"
|
||||
def >(other : Duration) = false
|
||||
def >=(other : Duration) = false
|
||||
def <(other : Duration) = true
|
||||
def <=(other : Duration) = true
|
||||
def unary_- : Duration = MinusInf
|
||||
}
|
||||
|
||||
object MinusInf extends Duration with Infinite {
|
||||
override def toString = "Duration.MinusInf"
|
||||
def >(other : Duration) = true
|
||||
def >=(other : Duration) = true
|
||||
def <(other : Duration) = false
|
||||
def <=(other : Duration) = false
|
||||
def unary_- : Duration = MinusInf
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -53,18 +92,177 @@ object Duration {
|
|||
* val duration = 100.millis
|
||||
* </pre>
|
||||
*/
|
||||
class Duration(val length: Long, val unit: TimeUnit) {
|
||||
trait Duration {
|
||||
def length : Long
|
||||
def unit : TimeUnit
|
||||
def toNanos : Long
|
||||
def toMicros : Long
|
||||
def toMillis : Long
|
||||
def toSeconds : Long
|
||||
def <(other : Duration) : Boolean
|
||||
def <=(other : Duration) : Boolean
|
||||
def >(other : Duration) : Boolean
|
||||
def >=(other : Duration) : Boolean
|
||||
def +(other : Duration) : Duration
|
||||
def -(other : Duration) : Duration
|
||||
def *(factor : Double) : Duration
|
||||
def /(factor : Double) : Duration
|
||||
def unary_- : Duration
|
||||
def finite_? : Boolean
|
||||
}
|
||||
|
||||
class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duration {
|
||||
def this(length: Long, unit: String) = this(length, Duration.timeUnit(unit))
|
||||
def toNanos = unit.toNanos(length)
|
||||
def toMicros = unit.toMicros(length)
|
||||
def toMillis = unit.toMillis(length)
|
||||
def toSeconds = unit.toSeconds(length)
|
||||
override def toString = "Duration(" + length + ", " + unit + ")"
|
||||
|
||||
def <(other : Duration) = {
|
||||
if (other.finite_?) {
|
||||
toNanos < other.asInstanceOf[FiniteDuration].toNanos
|
||||
} else {
|
||||
other > this
|
||||
}
|
||||
}
|
||||
|
||||
def <=(other : Duration) = {
|
||||
if (other.finite_?) {
|
||||
toNanos <= other.asInstanceOf[FiniteDuration].toNanos
|
||||
} else {
|
||||
other >= this
|
||||
}
|
||||
}
|
||||
|
||||
def >(other : Duration) = {
|
||||
if (other.finite_?) {
|
||||
toNanos > other.asInstanceOf[FiniteDuration].toNanos
|
||||
} else {
|
||||
other < this
|
||||
}
|
||||
}
|
||||
|
||||
def >=(other : Duration) = {
|
||||
if (other.finite_?) {
|
||||
toNanos >= other.asInstanceOf[FiniteDuration].toNanos
|
||||
} else {
|
||||
other <= this
|
||||
}
|
||||
}
|
||||
|
||||
private def fromNanos(nanos : Long) : Duration = {
|
||||
if (nanos % 1000000000L == 0) {
|
||||
Duration(nanos / 1000000000L, TimeUnit.SECONDS)
|
||||
} else if (nanos % 1000000L == 0) {
|
||||
Duration(nanos / 1000000L, TimeUnit.MILLISECONDS)
|
||||
} else if (nanos % 1000L == 0) {
|
||||
Duration(nanos / 1000L, TimeUnit.MICROSECONDS)
|
||||
} else {
|
||||
Duration(nanos, TimeUnit.NANOSECONDS)
|
||||
}
|
||||
}
|
||||
|
||||
private def fromNanos(nanos : Double) : Duration = fromNanos(nanos.asInstanceOf[Long])
|
||||
|
||||
def +(other : Duration) = {
|
||||
if (!other.finite_?) {
|
||||
other
|
||||
} else {
|
||||
val nanos = toNanos + other.asInstanceOf[FiniteDuration].toNanos
|
||||
fromNanos(nanos)
|
||||
}
|
||||
}
|
||||
|
||||
def -(other : Duration) = {
|
||||
if (!other.finite_?) {
|
||||
other
|
||||
} else {
|
||||
val nanos = toNanos - other.asInstanceOf[FiniteDuration].toNanos
|
||||
fromNanos(nanos)
|
||||
}
|
||||
}
|
||||
|
||||
def *(factor : Double) = fromNanos(long2double(toNanos) * factor)
|
||||
|
||||
def /(factor : Double) = fromNanos(long2double(toNanos) / factor)
|
||||
|
||||
def unary_- = Duration(-length, unit)
|
||||
|
||||
def finite_? = true
|
||||
|
||||
override def equals(other : Any) =
|
||||
other.isInstanceOf[FiniteDuration] &&
|
||||
toNanos == other.asInstanceOf[FiniteDuration].toNanos
|
||||
|
||||
override def hashCode = toNanos.asInstanceOf[Int]
|
||||
}
|
||||
|
||||
object Inf extends Duration {
|
||||
override def toString = "Duration.Inf"
|
||||
override def equals(other : Any) = false
|
||||
|
||||
def >(other : Duration) = true
|
||||
def >=(other : Duration) = true
|
||||
def <(other : Duration) = false
|
||||
def <=(other : Duration) = false
|
||||
|
||||
def +(other : Duration) : Duration = this
|
||||
def -(other : Duration) : Duration = this
|
||||
def *(other : Double) : Duration = this
|
||||
def /(other : Double) : Duration = this
|
||||
|
||||
def unary_- : Duration = MinusInf
|
||||
|
||||
def finite_? = false
|
||||
|
||||
def length : Long = error("length not allowed on Inf")
|
||||
def unit : TimeUnit = error("unit not allowed on Inf")
|
||||
def toNanos : Long = error("toNanos not allowed on Inf")
|
||||
def toMicros : Long = error("toMicros not allowed on Inf")
|
||||
def toMillis : Long = error("toMillis not allowed on Inf")
|
||||
def toSeconds : Long = error("toSeconds not allowed on Inf")
|
||||
}
|
||||
|
||||
object MinusInf extends Duration {
|
||||
override def toString = "Duration.MinusInf"
|
||||
override def equals(other : Any) = false
|
||||
|
||||
def >(other : Duration) = false
|
||||
def >=(other : Duration) = false
|
||||
def <(other : Duration) = true
|
||||
def <=(other : Duration) = true
|
||||
|
||||
def +(other : Duration) : Duration = this
|
||||
def -(other : Duration) : Duration = this
|
||||
def *(other : Double) : Duration = this
|
||||
def /(other : Double) : Duration = this
|
||||
|
||||
def unary_- : Duration = Inf
|
||||
|
||||
def finite_? = false
|
||||
|
||||
def length : Long = error("length not allowed on MinusInf")
|
||||
def unit : TimeUnit = error("unit not allowed on MinusInf")
|
||||
def toNanos : Long = error("toNanos not allowed on MinusInf")
|
||||
def toMicros : Long = error("toMicros not allowed on MinusInf")
|
||||
def toMillis : Long = error("toMillis not allowed on MinusInf")
|
||||
def toSeconds : Long = error("toSeconds not allowed on MinusInf")
|
||||
}
|
||||
|
||||
package object duration {
|
||||
implicit def intToDurationInt(n: Int) = new DurationInt(n)
|
||||
implicit def longToDurationLong(n: Long) = new DurationLong(n)
|
||||
implicit def pairIntToDuration(p : (Int, TimeUnit)) = Duration(p._1, p._2)
|
||||
implicit def pairLongToDuration(p : (Long, TimeUnit)) = Duration(p._1, p._2)
|
||||
implicit def durationToPair(d : Duration) = (d.length, d.unit)
|
||||
|
||||
implicit def intMult(i : Int) = new {
|
||||
def *(d : Duration) = d * i
|
||||
}
|
||||
implicit def longMult(l : Long) = new {
|
||||
def *(d : Duration) = d * l
|
||||
}
|
||||
}
|
||||
|
||||
class DurationInt(n: Int) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue