Skip to content

Commit c1e7c7e

Browse files
committed
Move more sort logic into the construction phase
1 parent 2f57a59 commit c1e7c7e

File tree

5 files changed

+458
-494
lines changed

5 files changed

+458
-494
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.finos.vuu.core.sort
2+
3+
import com.typesafe.scalalogging.StrictLogging
4+
import org.finos.vuu.core.sort.SortDirection.Ascending
5+
import org.finos.vuu.core.table.{Column, DataType, RowData}
6+
7+
trait RowDataComparator extends java.util.Comparator[RowData]
8+
9+
object RowDataComparator extends StrictLogging {
10+
11+
def apply(columns: List[Column], sortDirections: List[SortDirection]): RowDataComparator = {
12+
val comparators = columns
13+
.lazyZip(sortDirections)
14+
.map((col, dir) => buildColumnComparator(col, dir == Ascending))
15+
.toArray
16+
RowDataComparatorImpl(comparators)
17+
}
18+
19+
private def buildColumnComparator(column: Column, isAscending: Boolean): (RowData, RowData) => Int = {
20+
column.dataType match {
21+
case DataType.StringDataType =>
22+
(o1: RowData, o2: RowData) => compareString(o1.get(column), o2.get(column), isAscending)
23+
case DataType.LongDataType | DataType.IntegerDataType | DataType.DoubleDataType |
24+
DataType.BooleanDataType | DataType.CharDataType | DataType.EpochTimestampType |
25+
DataType.ScaledDecimal2Type | DataType.ScaledDecimal4Type |
26+
DataType.ScaledDecimal6Type | DataType.ScaledDecimal8Type =>
27+
(o1: RowData, o2: RowData) => compareComparable(o1.get(column), o2.get(column), isAscending)
28+
case _ =>
29+
logger.warn(s"Unable to sort datatype ${column.dataType}")
30+
(_, _) => 0
31+
}
32+
}
33+
34+
private def compareComparable(v1: Any, v2: Any, isAscending: Boolean): Int = {
35+
val c1 = v1.asInstanceOf[Comparable[AnyRef]]
36+
val c2 = v2.asInstanceOf[AnyRef]
37+
38+
if (c1 eq c2) 0
39+
else if (c1 == null) if (isAscending) 1 else -1
40+
else if (c2 == null) if (isAscending) -1 else 1
41+
else {
42+
val res = c1.compareTo(c2)
43+
if (isAscending) res else -res
44+
}
45+
}
46+
47+
private def compareString(v1: Any, v2: Any, isAscending: Boolean): Int = {
48+
val c1 = v1.asInstanceOf[String]
49+
val c2 = v2.asInstanceOf[String]
50+
51+
if (c1 eq c2) 0
52+
else if (c1 == null) if (isAscending) 1 else -1
53+
else if (c2 == null) if (isAscending) -1 else 1
54+
else {
55+
val res = c1.compareToIgnoreCase(c2)
56+
if (isAscending) res else -res
57+
}
58+
}
59+
60+
}
61+
62+
case class RowDataComparatorImpl(comparators: Array[(RowData, RowData) => Int]) extends RowDataComparator {
63+
64+
override def compare(o1: RowData, o2: RowData): Int = {
65+
var i = 0
66+
var result = 0
67+
while (i < comparators.length && result == 0) {
68+
result = comparators(i)(o1, o2)
69+
i += 1
70+
}
71+
result
72+
}
73+
74+
}

vuu/src/main/scala/org/finos/vuu/core/sort/SortCompares.scala

Lines changed: 0 additions & 108 deletions
This file was deleted.

vuu/src/main/scala/org/finos/vuu/core/sort/Sorts.scala

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package org.finos.vuu.core.sort
33
import com.typesafe.scalalogging.StrictLogging
44
import org.finos.toolbox.collection.array.ImmutableArray
55
import org.finos.toolbox.time.TimeIt.timeIt
6-
import org.finos.vuu.core.table.{Column, RowData, RowWithData, TablePrimaryKeys}
6+
import org.finos.vuu.core.table.{Column, RowWithData, TablePrimaryKeys}
77
import org.finos.vuu.feature.inmem.InMemTablePrimaryKeys
88
import org.finos.vuu.net.SortSpec
99
import org.finos.vuu.viewport.{RowSource, ViewPortColumns}
@@ -15,7 +15,11 @@ trait Sort {
1515
}
1616

1717
object Sort {
18-
def apply(spec: SortSpec, columns: List[Column]): Sort = GenericSort2(spec, columns)
18+
def apply(spec: SortSpec, columns: List[Column]): Sort = {
19+
val sortDirections = spec.sortDefs.map(sd => SortDirection.fromExternal(sd.sortType))
20+
val comparator = RowDataComparator.apply(columns, sortDirections)
21+
GenericSort2(comparator)
22+
}
1923
}
2024

2125
object NoSort extends Sort {
@@ -24,13 +28,7 @@ object NoSort extends Sort {
2428
}
2529
}
2630

27-
private case class GenericSort2(spec: SortSpec, columns: List[Column]) extends Sort with StrictLogging {
28-
29-
private val sortDirections = spec.sortDefs.map(sd => SortDirection.fromExternal(sd.sortType))
30-
private val comparator = new java.util.Comparator[RowData] {
31-
override def compare(o1: RowData, o2: RowData): Int =
32-
SortCompares.compare(o1, o2, columns, sortDirections, 0)
33-
}
31+
private case class GenericSort2(rowDataComparator: RowDataComparator) extends Sort with StrictLogging {
3432

3533
override def doSort(source: RowSource, primaryKeys: TablePrimaryKeys, vpColumns: ViewPortColumns): TablePrimaryKeys = {
3634

@@ -45,7 +43,7 @@ private case class GenericSort2(spec: SortSpec, columns: List[Column]) extends S
4543
logger.trace("Starting sort")
4644

4745
val (millisSort, _ ) = timeIt {
48-
util.Arrays.sort(snapshotAndCount._1, 0, snapshotAndCount._2, comparator)
46+
util.Arrays.sort(snapshotAndCount._1, 0, snapshotAndCount._2, rowDataComparator)
4947
}
5048

5149
logger.trace("Starting build imm arr")

0 commit comments

Comments
 (0)