Skip to content

Commit

Permalink
Use Vector instead of Array for RespArray representation
Browse files Browse the repository at this point in the history
  • Loading branch information
knutwalker committed Apr 12, 2015
1 parent 0380e13 commit e56aef1
Show file tree
Hide file tree
Showing 11 changed files with 47 additions and 42 deletions.
19 changes: 11 additions & 8 deletions modules/core/src/main/scala/rx/redis/resp/dataType.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,19 @@ case class RespInteger(value: Long) extends RespType {
override def toString: String = value.toString
}

case class RespArray(elements: Array[RespType]) extends RespType {
case class RespArray(elements: Vector[RespType]) extends RespType {
override def toString: String = elements.map(_.toString).mkString("[", ", ", "]")

override def equals(obj: scala.Any): Boolean = obj match {
case RespArray(other)
util.Arrays.equals(elements.asInstanceOf[Array[AnyRef]], other.asInstanceOf[Array[AnyRef]])
case _ super.equals(obj)
}
override def hashCode(): Int =
util.Arrays.hashCode(elements.asInstanceOf[Array[AnyRef]])
def :+(x: RespType): RespArray = RespArray(elements :+ x)
def +:(x: RespType): RespArray = RespArray(x +: elements)
def ++(xs: RespArray): RespArray = RespArray(elements ++ xs.elements)
def ++(xs: RespType*): RespArray = RespArray(elements ++ xs)
}
object RespArray {
val empty = RespArray(Vector.empty)

def apply(x: RespType, xs: RespType*): RespArray =
RespArray(x +: xs.toVector)
}

case class RespBytes(bytes: Array[Byte]) extends RespType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

package rx.redis.serialization

import collection.immutable.VectorBuilder
import scala.annotation.tailrec
import scala.collection.mutable.ArrayBuffer

import rx.redis.resp._
import rx.redis.util._
Expand Down Expand Up @@ -147,9 +147,10 @@ final class Deserializer[A](implicit A: BytesAccess[A]) {
val size = parseLen(bytes)
if (size == -1) NullArray
else {
val lb = new ArrayBuffer[RespType](size)
val lb = new VectorBuilder[RespType]()
lb.sizeHint(size)
@tailrec def loop(n: Int): RespType = {
if (n == 0) RespArray(lb.toArray)
if (n == 0) RespArray(lb.result())
else {
lb += quickApply(bytes)
loop(n - 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ object Reads {
private[this] def pairPf[T, U](T: PartialFunction[RespType, T], U: PartialFunction[RespType, U]): PartialFunction[RespType, List[(T, U)]] = {
case RespArray(items)
items.grouped(2).collect {
case Array(t, u) if T.isDefinedAt(t) && U.isDefinedAt(u)
case Vector(t, u) if T.isDefinedAt(t) && U.isDefinedAt(u)
T(t) -> U(u)
}.toList
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ final class Serializer[A](implicit A: BytesAccess[A]) {
A.writeBytes(bb, CrLf)
}

private[this] def writeArray(bb: A, items: Array[RespType]): Unit = {
private[this] def writeArray(bb: A, items: Vector[RespType]): Unit = {
val size = BytesFormat[Long].bytes(items.length.toLong)
A.writeByte(bb, Asterisk)
A.writeBytes(bb, size)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ object Writes {

implicit object DirectStringWrites extends Writes[String] {
def write(value: String): RespType = {
val items: Array[RespType] = value.split(' ').map(RespBytes(_))(collection.breakOut)
val items: Vector[RespType] = value.split(' ').map(RespBytes(_))(collection.breakOut)
RespArray(items)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,11 @@ class WritesMacro(val c: blackbox.Context) {
val generated = q"""
object $objectName extends $finalTpe {
def write(value: $tpe): $dt = {
val buf = new scala.collection.mutable.ArrayBuffer[$dt](${sizeHeader(arguments)})
val buf = new scala.collection.immutable.VectorBuilder[$dt]()
buf.sizeHint(${sizeHeader(arguments)})
buf += $rb(${nameHeader(typeName)})
..$argumentTrees
$ra(buf.toArray)
$ra(buf.result())
}
}
$objectName
Expand Down
2 changes: 1 addition & 1 deletion tests/src/test/scala/rx/redis/commands/CommandsSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ class CommandsSuite extends FunSuite {
}

protected def sers[A: Writes](c: A, expectedParts: String*) =
ser(c, RespArray(expectedParts.map(RespBytes(_)).toArray))
ser(c, RespArray(expectedParts.map(RespBytes(_)).toVector))
}
2 changes: 1 addition & 1 deletion tests/src/test/scala/rx/redis/pipeline/RespCodecSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class RespCodecSpec extends FunSuite with BeforeAndAfter {
}

test("should handle arrays") {
compare(RespArray(Array(RespString("foo"), RespBytes("bar"))), "*2\r\n+foo\r\n$3\r\nbar\r\n")
compare(RespArray(RespString("foo"), RespBytes("bar")), "*2\r\n+foo\r\n$3\r\nbar\r\n")
}

test("should fail on outbound writing for non data types ") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class CodecRegressionSpec extends FunSuite with PropertyChecks {
val genBytes = arbitrary[Array[Byte]] map (RespBytes(_))
val genInteger = arbitrary[Long] map RespInteger
val genAnyPrimitive = Gen.oneOf(genString, genError, genBytes, genInteger, Gen.const(NullString))
val genArray = Gen.containerOf[Array, RespType](genAnyPrimitive) map RespArray
val genArray = Gen.containerOf[Vector, RespType](genAnyPrimitive) map (xs RespArray(xs))
val genAnyData = Gen.oneOf(genString, genError, genBytes, genInteger, genArray, Gen.const(NullArray))

test("serialze <> deserialze must be the same") {
Expand Down
24 changes: 12 additions & 12 deletions tests/src/test/scala/rx/redis/serialization/DeserializerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -102,26 +102,26 @@ class DeserializerSpec extends FunSuite with Inside {
}

test("deserialize arrays") {
compare("*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n", RespArray(Array(RespBytes("foo"), RespBytes("bar"))))
compare("*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n", RespArray(RespBytes("foo"), RespBytes("bar")))
}

test("deserialize integer arrays") {
compare("*3\r\n:1\r\n:2\r\n:3\r\n", RespArray(Array(RespInteger(1), RespInteger(2), RespInteger(3))))
compare("*3\r\n:1\r\n:2\r\n:3\r\n", RespArray(RespInteger(1), RespInteger(2), RespInteger(3)))
}

test("deserialize mixed arrays") {
compare("*5\r\n:1\r\n:2\r\n:3\r\n:4\r\n$6\r\nfoobar\r\n",
RespArray(Array(
RespArray(
RespInteger(1),
RespInteger(2),
RespInteger(3),
RespInteger(4),
RespBytes("foobar")
)))
))
}

test("deserialize an empty array") {
compare("*0\r\n", RespArray(Array()))
compare("*0\r\n", RespArray.empty)
}

test("deserialize the null array") {
Expand All @@ -130,17 +130,17 @@ class DeserializerSpec extends FunSuite with Inside {

test("deserialize nested arrays") {
compare("*2\r\n*3\r\n:1\r\n:2\r\n:3\r\n*2\r\n+Foo\r\n-Bar\r\n",
RespArray(Array(
RespArray(Array(
RespArray(
RespArray(
RespInteger(1),
RespInteger(2),
RespInteger(3)
)),
RespArray(Array(
),
RespArray(
RespString("Foo"),
RespError("Bar")
))
))
)
)
)
}

Expand Down Expand Up @@ -174,7 +174,7 @@ class DeserializerSpec extends FunSuite with Inside {
}

test("size underflow in arrays") {
compare("*1\r\n:1\r\n:2\r\n", RespArray(Array(RespInteger(1))))
compare("*1\r\n:1\r\n:2\r\n", RespArray(RespInteger(1)))
}

test("missing type marker") {
Expand Down
22 changes: 11 additions & 11 deletions tests/src/test/scala/rx/redis/serialization/SerializerSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,28 +69,28 @@ class SerializerSpec extends FunSuite with Inside {
}

test("serialize arrays") {
compare(RespArray(Array(RespBytes("foo"), RespBytes("bar"))), "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n")
compare(RespArray(RespBytes("foo"), RespBytes("bar")), "*2\r\n$3\r\nfoo\r\n$3\r\nbar\r\n")
}

test("serialize integer arrays") {
compare(RespArray(Array(RespInteger(1), RespInteger(2), RespInteger(3))), "*3\r\n:1\r\n:2\r\n:3\r\n")
compare(RespArray(RespInteger(1), RespInteger(2), RespInteger(3)), "*3\r\n:1\r\n:2\r\n:3\r\n")
}

test("serialize mixed arrays") {
compare(
RespArray(Array(
RespArray(
RespInteger(1),
RespInteger(2),
RespInteger(3),
RespInteger(4),
RespBytes("foobar")
)),
),
"*5\r\n:1\r\n:2\r\n:3\r\n:4\r\n$6\r\nfoobar\r\n"
)
}

test("serialize an empty array") {
compare(RespArray(Array()), "*0\r\n")
compare(RespArray.empty, "*0\r\n")
}

test("serialize the null array") {
Expand All @@ -99,17 +99,17 @@ class SerializerSpec extends FunSuite with Inside {

test("serialize nested arrays") {
compare(
RespArray(Array(
RespArray(Array(
RespArray(
RespArray(
RespInteger(1),
RespInteger(2),
RespInteger(3)
)),
RespArray(Array(
),
RespArray(
RespString("Foo"),
RespError("Bar")
))
)),
)
),
"*2\r\n*3\r\n:1\r\n:2\r\n:3\r\n*2\r\n+Foo\r\n-Bar\r\n"
)
}
Expand Down

0 comments on commit e56aef1

Please sign in to comment.