Skip to content
This repository has been archived by the owner on May 18, 2023. It is now read-only.

Commit

Permalink
Merge pull request #120 from unchartedsoftware/sparse-array-work
Browse files Browse the repository at this point in the history
Better implementation of SparseArray.
  • Loading branch information
Ghnuberath authored Nov 22, 2016
2 parents 18a4670 + 7131495 commit d41d89e
Show file tree
Hide file tree
Showing 13 changed files with 513 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class SeriesData[
* tile coordinate and the same bin dimensions. The new SeriesData will inherit this SeriesData's
* Projection.
*
* @param other the SeriesData to merge with
* @param that the SeriesData to merge with
* @param binMerge the function for merging bin values
* @param tileMetaMerge the Optional function for merging tile metadata
* @tparam OV other's bin value type
Expand All @@ -70,29 +70,25 @@ class SeriesData[
*/
@throws(classOf[SeriesDataMergeException])
def merge[OV, OX, NV: ClassTag, NX](
other: SeriesData[TC, BC, OV, OX],
that: SeriesData[TC, BC, OV, OX],
binMerge: (V, OV) => NV,
tileMetaMerge: Option[(X, OX) => NX] = None
): SeriesData[TC, BC, NV, NX] = {
if (other.bins.length != bins.length) {
if (this.bins.length != that.bins.length) {
throw new SeriesDataMergeException("Two Series with different bin dimensions cannot be merged.")
} else if (!coords.equals(other.coords)) {
} else if (this.coords != that.coords) {
throw new SeriesDataMergeException("SeriesData with nonmatching tile coordinates cannot be merged.")
}

// new default value
val newDefault = binMerge(bins.default, other.bins.default)

// merge bins
val newBins = new SparseArray[NV](0, newDefault)
while (newBins.length<bins.length) {
newBins += binMerge(bins(newBins.length), other.bins(newBins.length))
}
val newBins = SparseArray.merge(binMerge)(this.bins, that.bins)

// compute new meta
var newMeta: Option[NX] = None
if (tileMetaMerge.isDefined && tileMeta.isDefined && other.tileMeta.isDefined) {
newMeta = Some(tileMetaMerge.get(tileMeta.get, other.tileMeta.get))
val newMeta: Option[NX] = for (
mergeFcn <- tileMetaMerge;
thisMeta <- this.tileMeta;
thatMeta <- that.tileMeta
) yield {
mergeFcn(thisMeta, thatMeta)
}

new SeriesData(projection, maxBin, coords, newBins, newMeta)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,17 +267,14 @@ private class RDDSeriesWrapper[
}
val key = binData._1

var finishedBins = new SparseArray[V](0, series.binAggregator.finish(series.binAggregator.default))
val typedBinData = binData._2.asInstanceOf[SparseArray[U]]
while (finishedBins.length < typedBinData.length) {
val a = typedBinData(finishedBins.length)
val bin = series.binAggregator.finish(a)
if (series.tileAggregator.isDefined) {
tile = series.tileAggregator.get.add(tile, Some(bin))
val finishedBins = typedBinData.map(series.binAggregator.finish(_))

series.tileAggregator.foreach { aggregator =>
for (i <- finishedBins.indices) {
tile = aggregator.add(tile, Some(finishedBins(i)))
}
finishedBins += bin
}
finishedBins = finishedBins.result()

val finishedTile: Option[X] = series.tileAggregator match {
case None => None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,12 @@ abstract class Projection[DC, TC, BC]() extends Serializable {
* @return the bin index converted into its one-dimensional representation
*/
def binTo1D(bin: BC, maxBin: BC): Int

/**
* Project a 1 dimensional index into a bin index for easy retrieval of bin values from an array
* @param index An array index
* @param maxBin The maximum possible bin index (i.e. if your tile is 256x256, this would be (255, 255))
* @return The bin index indicated by this one dimensional representation
*/
def binFrom1D (index: Int, maxBin: BC): BC
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,10 @@ class CartesianProjection(
override def binTo1D(bin: (Int, Int), maxBin: (Int, Int)): Int = {
bin._1 + bin._2*(maxBin._1 + 1)
}
override def binFrom1D(index: Int, maxBin: (Int, Int)): (Int, Int) = {
val bins = maxBin._1 + 1

val x = index % bins
(x, (index - x) / bins)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,11 @@ class MercatorProjection(
override def binTo1D(bin: (Int, Int), maxBin: (Int, Int)): Int = {
bin._1 + bin._2*(maxBin._1 + 1)
}

override def binFrom1D (index: Int, maxBin: (Int, Int)): (Int, Int) = {
val bins = maxBin._1 + 1

val x = index % bins
(x, (index - x) / bins)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,8 @@ class SeriesProjection(
override def binTo1D(bin: Int, maxBin: Int): Int = {
bin
}

override def binFrom1D(index: Int, maxBin: Int): Int = {
index
}
}
Loading

0 comments on commit d41d89e

Please sign in to comment.