basis.data.Struct.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of basis-data_2.11 Show documentation
Show all versions of basis-data_2.11 Show documentation
A foundation library for Scala focussed on efficiency and clean design
The newest version!
// ____ ___
// / __ | ___ ____ /__/___ A library of building blocks
// / __ / __ |/ ___|/ / ___|
// / /_/ / /_/ /\__ \/ /\__ \ (c) 2012-2015 Chris Sachs
// |_____/\_____\____/__/\____/ http://basis.reify.it
package basis.data
import basis.util._
trait Struct[@specialized(Byte, Short, Int, Long, Float, Double, Boolean) T] {
def alignment: Long
def size: Long
def load(data: Loader, offset: Long): T
def store(data: Storer, offset: Long, value: T): Unit
}
object Struct {
def apply[T](implicit T: Struct[T]): T.type = T
implicit lazy val PackedByte: Struct[Byte] = new PackedByte
lazy val PackedShort: Struct[Short] = new PackedShort
lazy val PackedInt: Struct[Int] = new PackedInt
lazy val PackedLong: Struct[Long] = new PackedLong
lazy val PackedFloat: Struct[Float] = new PackedFloat
lazy val PackedDouble: Struct[Double] = new PackedDouble
implicit lazy val PackedBoolean: Struct[Boolean] = new PackedBoolean
implicit lazy val PaddedShort: Struct[Short] = new PaddedShort
implicit lazy val PaddedInt: Struct[Int] = new PaddedInt
implicit lazy val PaddedLong: Struct[Long] = new PaddedLong
implicit lazy val PaddedFloat: Struct[Float] = new PaddedFloat
implicit lazy val PaddedDouble: Struct[Double] = new PaddedDouble
lazy val VolatileByte: Struct[Byte] = new VolatileByte
lazy val VolatileShort: Struct[Short] = new VolatileShort
lazy val VolatileInt: Struct[Int] = new VolatileInt
lazy val VolatileLong: Struct[Long] = new VolatileLong
lazy val VolatileFloat: Struct[Float] = new VolatileFloat
lazy val VolatileDouble: Struct[Double] = new VolatileDouble
lazy val VolatileBoolean: Struct[Boolean] = new VolatileBoolean
lazy val PackedShortBE: Struct[Short] = new PackedShortBE
lazy val PackedShortLE: Struct[Short] = new PackedShortLE
lazy val PackedIntBE: Struct[Int] = new PackedIntBE
lazy val PackedIntLE: Struct[Int] = new PackedIntLE
lazy val PackedLongBE: Struct[Long] = new PackedLongBE
lazy val PackedLongLE: Struct[Long] = new PackedLongLE
lazy val PackedFloatBE: Struct[Float] = new PackedFloatBE
lazy val PackedFloatLE: Struct[Float] = new PackedFloatLE
lazy val PackedDoubleBE: Struct[Double] = new PackedDoubleBE
lazy val PackedDoubleLE: Struct[Double] = new PackedDoubleLE
implicit def Tuple2[T1: Struct, T2: Struct]: Struct[(T1, T2)] = new Tuple2[T1, T2]
implicit def Tuple3[T1: Struct, T2: Struct, T3: Struct]: Struct[(T1, T2, T3)] = new Tuple3[T1, T2, T3]
implicit def Tuple4[T1: Struct, T2: Struct, T3: Struct, T4: Struct]: Struct[(T1, T2, T3, T4)] = new Tuple4[T1, T2, T3, T4]
private final class PackedByte extends Struct[Byte] {
override def alignment: Long = 1L
override def size: Long = 1L
override def load(data: Loader, offset: Long): Byte = data.loadByte(offset)
override def store(data: Storer, offset: Long, value: Byte): Unit = data.storeByte(offset, value)
override def toString: String = "PackedByte"
}
private final class PackedShort extends Struct[Short] {
override def alignment: Long = 1L
override def size: Long = 2L
override def load(data: Loader, offset: Long): Short = data.loadShort(offset)
override def store(data: Storer, offset: Long, value: Short): Unit = data.storeShort(offset, value)
override def toString: String = "PackedShort"
}
private final class PackedInt extends Struct[Int] {
override def alignment: Long = 1L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Int = data.loadInt(offset)
override def store(data: Storer, offset: Long, value: Int): Unit = data.storeInt(offset, value)
override def toString: String = "PackedInt"
}
private final class PackedLong extends Struct[Long] {
override def alignment: Long = 1L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Long = data.loadLong(offset)
override def store(data: Storer, offset: Long, value: Long): Unit = data.storeLong(offset, value)
override def toString: String = "PackedLong"
}
private final class PackedFloat extends Struct[Float] {
override def alignment: Long = 1L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Float = data.loadFloat(offset)
override def store(data: Storer, offset: Long, value: Float): Unit = data.storeFloat(offset, value)
override def toString: String = "PackedFloat"
}
private final class PackedDouble extends Struct[Double] {
override def alignment: Long = 1L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Double = data.loadDouble(offset)
override def store(data: Storer, offset: Long, value: Double): Unit = data.storeDouble(offset, value)
override def toString: String = "PackedDouble"
}
private final class PackedBoolean extends Struct[Boolean] {
override def alignment: Long = 1L
override def size: Long = 1L
override def load(data: Loader, offset: Long): Boolean = data.loadByte(offset) == 0
override def store(data: Storer, offset: Long, value: Boolean): Unit = data.storeByte(offset, if (value) 0 else -1)
override def toString: String = "PackedBoolean"
}
private final class PaddedShort extends Struct[Short] {
override def alignment: Long = 2L
override def size: Long = 2L
override def load(data: Loader, offset: Long): Short = data.loadAlignedShort(offset)
override def store(data: Storer, offset: Long, value: Short): Unit = data.storeAlignedShort(offset, value)
override def toString: String = "PaddedShort"
}
private final class PaddedInt extends Struct[Int] {
override def alignment: Long = 4L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Int = data.loadAlignedInt(offset)
override def store(data: Storer, offset: Long, value: Int): Unit = data.storeAlignedInt(offset, value)
override def toString: String = "PaddedInt"
}
private final class PaddedLong extends Struct[Long] {
override def alignment: Long = 8L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Long = data.loadAlignedLong(offset)
override def store(data: Storer, offset: Long, value: Long): Unit = data.storeAlignedLong(offset, value)
override def toString: String = "PaddedLong"
}
private final class PaddedFloat extends Struct[Float] {
override def alignment: Long = 4L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Float = data.loadAlignedFloat(offset)
override def store(data: Storer, offset: Long, value: Float): Unit = data.storeAlignedFloat(offset, value)
override def toString: String = "PaddedFloat"
}
private final class PaddedDouble extends Struct[Double] {
override def alignment: Long = 8L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Double = data.loadAlignedDouble(offset)
override def store(data: Storer, offset: Long, value: Double): Unit = data.storeAlignedDouble(offset, value)
override def toString: String = "PaddedDouble"
}
private final class VolatileByte extends Struct[Byte] {
override def alignment: Long = 1L
override def size: Long = 1L
override def load(data: Loader, offset: Long): Byte = data.loadVolatileByte(offset)
override def store(data: Storer, offset: Long, value: Byte): Unit = data.storeVolatileByte(offset, value)
override def toString: String = "VolatileByte"
}
private final class VolatileShort extends Struct[Short] {
override def alignment: Long = 2L
override def size: Long = 2L
override def load(data: Loader, offset: Long): Short = data.loadVolatileShort(offset)
override def store(data: Storer, offset: Long, value: Short): Unit = data.storeVolatileShort(offset, value)
override def toString: String = "VolatileShort"
}
private final class VolatileInt extends Struct[Int] {
override def alignment: Long = 4L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Int = data.loadVolatileInt(offset)
override def store(data: Storer, offset: Long, value: Int): Unit = data.storeVolatileInt(offset, value)
override def toString: String = "VolatileInt"
}
private final class VolatileLong extends Struct[Long] {
override def alignment: Long = 8L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Long = data.loadVolatileLong(offset)
override def store(data: Storer, offset: Long, value: Long): Unit = data.storeVolatileLong(offset, value)
override def toString: String = "VolatileLong"
}
private final class VolatileFloat extends Struct[Float] {
override def alignment: Long = 4L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Float = data.loadVolatileFloat(offset)
override def store(data: Storer, offset: Long, value: Float): Unit = data.storeVolatileFloat(offset, value)
override def toString: String = "VolatileFloat"
}
private final class VolatileDouble extends Struct[Double] {
override def alignment: Long = 8L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Double = data.loadVolatileDouble(offset)
override def store(data: Storer, offset: Long, value: Double): Unit = data.storeVolatileDouble(offset, value)
override def toString: String = "VolatileDouble"
}
private final class VolatileBoolean extends Struct[Boolean] {
override def alignment: Long = 1L
override def size: Long = 1L
override def load(data: Loader, offset: Long): Boolean = data.loadVolatileByte(offset) == 0
override def store(data: Storer, offset: Long, value: Boolean): Unit = data.storeVolatileByte(offset, if (value) 0 else -1)
override def toString: String = "VolatileBoolean"
}
private final class PackedShortBE extends Struct[Short] {
override def alignment: Long = 1L
override def size: Long = 2L
override def load(data: Loader, offset: Long): Short = new LoaderOps(data).loadShortBE(offset)
override def store(data: Storer, offset: Long, value: Short): Unit = new StorerOps(data).storeShortBE(offset, value)
override def toString: String = "PackedShortBE"
}
private final class PackedShortLE extends Struct[Short] {
override def alignment: Long = 1L
override def size: Long = 2L
override def load(data: Loader, offset: Long): Short = new LoaderOps(data).loadShortLE(offset)
override def store(data: Storer, offset: Long, value: Short): Unit = new StorerOps(data).storeShortLE(offset, value)
override def toString: String = "PackedShortLE"
}
private final class PackedIntBE extends Struct[Int] {
override def alignment: Long = 1L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Int = new LoaderOps(data).loadIntBE(offset)
override def store(data: Storer, offset: Long, value: Int): Unit = new StorerOps(data).storeIntBE(offset, value)
override def toString: String = "PackedIntBE"
}
private final class PackedIntLE extends Struct[Int] {
override def alignment: Long = 1L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Int = new LoaderOps(data).loadIntLE(offset)
override def store(data: Storer, offset: Long, value: Int): Unit = new StorerOps(data).storeIntLE(offset, value)
override def toString: String = "PackedIntLE"
}
private final class PackedLongBE extends Struct[Long] {
override def alignment: Long = 1L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Long = new LoaderOps(data).loadLongBE(offset)
override def store(data: Storer, offset: Long, value: Long): Unit = new StorerOps(data).storeLongBE(offset, value)
override def toString: String = "PackedLongBE"
}
private final class PackedLongLE extends Struct[Long] {
override def alignment: Long = 1L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Long = new LoaderOps(data).loadLongLE(offset)
override def store(data: Storer, offset: Long, value: Long): Unit = new StorerOps(data).storeLongLE(offset, value)
override def toString: String = "PackedLongLE"
}
private final class PackedFloatBE extends Struct[Float] {
override def alignment: Long = 1L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Float = new LoaderOps(data).loadFloatBE(offset)
override def store(data: Storer, offset: Long, value: Float): Unit = new StorerOps(data).storeFloatBE(offset, value)
override def toString: String = "PackedFloatBE"
}
private final class PackedFloatLE extends Struct[Float] {
override def alignment: Long = 1L
override def size: Long = 4L
override def load(data: Loader, offset: Long): Float = new LoaderOps(data).loadFloatLE(offset)
override def store(data: Storer, offset: Long, value: Float): Unit = new StorerOps(data).storeFloatLE(offset, value)
override def toString: String = "PackedFloatLE"
}
private final class PackedDoubleBE extends Struct[Double] {
override def alignment: Long = 1L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Double = new LoaderOps(data).loadDoubleBE(offset)
override def store(data: Storer, offset: Long, value: Double): Unit = new StorerOps(data).storeDoubleBE(offset, value)
override def toString: String = "PackedDoubleBE"
}
private final class PackedDoubleLE extends Struct[Double] {
override def alignment: Long = 1L
override def size: Long = 8L
override def load(data: Loader, offset: Long): Double = new LoaderOps(data).loadDoubleLE(offset)
override def store(data: Storer, offset: Long, value: Double): Unit = new StorerOps(data).storeDoubleLE(offset, value)
override def toString: String = "PackedDoubleLE"
}
private final class Tuple2[T1, T2]
(implicit protected val T1: Struct[T1], protected val T2: Struct[T2])
extends Struct[(T1, T2)] {
private[this] val offset2: Long = align(T1.size, T2.alignment)
override val alignment: Long = T1.alignment max T2.alignment
override val size: Long = align(offset2 + T2.size, alignment)
override def load(data: Loader, offset: Long): (T1, T2) = {
val _1 = T1.load(data, offset )
val _2 = T2.load(data, offset + offset2)
(_1, _2)
}
override def store(data: Storer, offset: Long, tuple: (T1, T2)): Unit = {
T1.store(data, offset , tuple._1)
T2.store(data, offset + offset2, tuple._2)
}
override def equals(other: Any): Boolean = other match {
case that: Tuple2[_, _] => T1.equals(that.T1) && T2.equals(that.T2)
case _ => false
}
override def hashCode: Int = {
import MurmurHash3._
mash(mix(mix(seed[Tuple2[_, _]], T1.hashCode), T2.hashCode))
}
override def toString: String = "Tuple2"+"("+ T1 +", "+ T2 +")"
}
private final class Tuple3[T1, T2, T3]
(implicit protected val T1: Struct[T1], protected val T2: Struct[T2],
protected val T3: Struct[T3])
extends Struct[(T1, T2, T3)] {
private[this] val offset2: Long = align(T1.size, T2.alignment)
private[this] val offset3: Long = align(offset2 + T2.size, T3.alignment)
override val alignment: Long = T1.alignment max T2.alignment max T3.alignment
override val size: Long = align(offset3 + T3.size, alignment)
override def load(data: Loader, offset: Long): (T1, T2, T3) = {
val _1 = T1.load(data, offset )
val _2 = T2.load(data, offset + offset2)
val _3 = T3.load(data, offset + offset3)
(_1, _2, _3)
}
override def store(data: Storer, offset: Long, tuple: (T1, T2, T3)): Unit = {
T1.store(data, offset , tuple._1)
T2.store(data, offset + offset2, tuple._2)
T3.store(data, offset + offset3, tuple._3)
}
override def equals(other: Any): Boolean = other match {
case that: Tuple3[_, _, _] => T1.equals(that.T1) && T2.equals(that.T2) && T3.equals(that.T3)
case _ => false
}
override def hashCode: Int = {
import MurmurHash3._
mash(mix(mix(mix(seed[Tuple3[_, _, _]], T1.hashCode), T2.hashCode), T3.hashCode))
}
override def toString: String = "Tuple3"+"("+ T1 +", "+ T2 +", "+ T3 +")"
}
private final class Tuple4[T1, T2, T3, T4]
(implicit protected val T1: Struct[T1], protected val T2: Struct[T2],
protected val T3: Struct[T3], protected val T4: Struct[T4])
extends Struct[(T1, T2, T3, T4)] {
private[this] val offset2: Long = align(T1.size, T2.alignment)
private[this] val offset3: Long = align(offset2 + T2.size, T3.alignment)
private[this] val offset4: Long = align(offset3 + T3.size, T4.alignment)
override val alignment: Long = T1.alignment max T2.alignment max T3.alignment max T4.alignment
override val size: Long = align(offset4 + T4.size, alignment)
override def load(data: Loader, offset: Long): (T1, T2, T3, T4) = {
val _1 = T1.load(data, offset )
val _2 = T2.load(data, offset + offset2)
val _3 = T3.load(data, offset + offset3)
val _4 = T4.load(data, offset + offset4)
(_1, _2, _3, _4)
}
override def store(data: Storer, offset: Long, tuple: (T1, T2, T3, T4)): Unit = {
T1.store(data, offset , tuple._1)
T2.store(data, offset + offset2, tuple._2)
T3.store(data, offset + offset3, tuple._3)
T4.store(data, offset + offset4, tuple._4)
}
override def equals(other: Any): Boolean = other match {
case that: Tuple4[_, _, _, _] => T1.equals(that.T1) && T2.equals(that.T2) && T3.equals(that.T3) && T4.equals(that.T4)
case _ => false
}
override def hashCode: Int = {
import MurmurHash3._
mash(mix(mix(mix(mix(seed[Tuple4[_, _, _, _]], T1.hashCode), T2.hashCode), T3.hashCode), T4.hashCode))
}
override def toString: String = "Tuple4"+"("+ T1 +", "+ T2 +", "+ T3 +", "+ T4 +")"
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy