-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Define TupleXXL and FunctionXXL using IArray #6929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Define TupleXXL and FunctionXXL using IArray #6929
Conversation
57eec5b
to
490a66c
Compare
This way we can avoid some unnecessary array copies.
490a66c
to
3d827b4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise, LGTM
case xs: IArray[Object] => xs | ||
case xs => | ||
// TODO suport IArray.map | ||
xs.asInstanceOf[Array[T]].map(_.asInstanceOf[Object]).asInstanceOf[IArray[Object]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will a bound on IArray
work, like opaque type IArray[+T] <: Seq[T] = Array[_ <: T]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably not. We need to do the same as array does and define a WrappedIArray for it.
assert(es.length > 22) | ||
|
||
def productElement(n: Int): Any = es(n) | ||
def productArity: Int = es.length | ||
|
||
override def toString = elems.mkString("(", ",", ")") | ||
override def hashCode = getClass.hashCode * 41 + deepHashCode(elems) | ||
override def toString = elems.asInstanceOf[Array[Object]].mkString("(", ",", ")") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After the bound on IArray
, this cast may be avoided.
library/src/scala/TupleXXL.scala
Outdated
|
||
def tailXXL: TupleXXL = { | ||
assert(es.length > 23) | ||
new TupleXXL(es.tail) | ||
new TupleXXL(es.asInstanceOf[Array[Object]].tail.asInstanceOf[IArray[Object]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to support IArray.tail
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding WrappedIArray would do it. Also imlementing all ArrayOps on IArray would help
library/src/scala/TupleXXL.scala
Outdated
def apply(elems: Array[Object]) = new TupleXXL(elems.clone) | ||
def apply(elems: Any*) = new TupleXXL(elems.asInstanceOf[Seq[Object]].toArray) | ||
def unapplySeq(x: TupleXXL): Option[Seq[Any]] = Some(x.elems.toSeq) | ||
def fromIterator(elems: Iterator[Any]) = new TupleXXL(elems.map(_.asInstanceOf[Object]).toArray.asInstanceOf[IArray[Object]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to avoid .asInstanceOf[IArray[Object]]
, as the Array instance might be aliased, thus break the protocol. Create IArray
through its constructors is recommended.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IArray
would copy the array at least twice, this is the best we can do for now. We need Iterator.toIArray
.
library/src/scala/TupleXXL.scala
Outdated
def unapplySeq(x: TupleXXL): Option[Seq[Any]] = Some(x.elems.toSeq) | ||
def fromIterator(elems: Iterator[Any]) = new TupleXXL(elems.map(_.asInstanceOf[Object]).toArray.asInstanceOf[IArray[Object]]) | ||
def fromIArray(elems: IArray[Object]) = new TupleXXL(elems) | ||
def apply(elems: Any*) = new TupleXXL(elems.asInstanceOf[Seq[Object]].toArray.asInstanceOf[IArray[Object]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to create IArray
through its constructors instead of cast.
@@ -52,9 +52,13 @@ object DynamicTuple { | |||
case 20 => Tuple20(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19)).asInstanceOf[T] | |||
case 21 => Tuple21(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19), xs(20)).asInstanceOf[T] | |||
case 22 => Tuple22(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19), xs(20), xs(21)).asInstanceOf[T] | |||
case _ => TupleXXL(xs).asInstanceOf[T] | |||
case _ => TupleXXL.fromIArray(xs.clone().asInstanceOf[IArray[Object]]).asInstanceOf[T] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to create IArray through its constructors instead of cast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. It might also be good to have a toIArray
on collections
@@ -169,7 +173,7 @@ object DynamicTuple { | |||
case _ => | |||
xs match { | |||
case xs: TupleXXL => xs | |||
case xs => TupleXXL(xs.productIterator.map(_.asInstanceOf[Object]).toArray) | |||
case xs => TupleXXL.fromIArray(xs.productIterator.map(_.asInstanceOf[Object]).toArray.asInstanceOf[IArray[Object]]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to create IArray through its constructors instead of cast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as before, need Iterator.toIArray
def dynamicToIArray(self: Tuple): IArray[Object] = (self: Any) match { | ||
case self: Unit => Array.emptyObjectArray.asInstanceOf[IArray[Object]] | ||
case self: TupleXXL => self.elems | ||
case self: Product => productToArray(self).asInstanceOf[IArray[Object]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to create IArray through its constructors instead of cast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The array constructor would create a new empty array each time
All this shows the need to implement all collection operations on IArray. I will open an issue describing the detail. |
On another note, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This way we can avoid some unnecessary array copies.