Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10 from ryan-williams/h
new iterators, factor out math/stats modules
- Loading branch information
Showing
70 changed files
with
1,589 additions
and
1,890 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,7 @@ | ||
name := "iterator" | ||
|
||
version := "1.2.2" | ||
version := "1.3.0" | ||
|
||
addScala212 | ||
|
||
deps ++= Seq( | ||
libs.value('commons_math), | ||
kryo.value, | ||
"com.chuusai" %% "shapeless" % "2.3.2", | ||
libs.value('spire) | ||
) | ||
deps += spire |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
addSbtPlugin("org.hammerlab" % "sbt-parent" % "2.0.1") | ||
addSbtPlugin("org.hammerlab" % "sbt-parent" % "3.0.0") |
17 changes: 0 additions & 17 deletions
17
src/main/scala/org/hammerlab/iterator/BufferedTakeWhileIterator.scala
This file was deleted.
Oops, something went wrong.
17 changes: 17 additions & 0 deletions
17
src/main/scala/org/hammerlab/iterator/DropEagerIterator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.hammerlab.iterator | ||
|
||
case class DropEagerIterator[T](it: Iterator[T]) { | ||
def dropEager(n: Int): Iterator[T] = { | ||
var idx = 0 | ||
while (it.hasNext && idx < n) { | ||
it.next | ||
idx += 1 | ||
} | ||
it | ||
} | ||
} | ||
|
||
object DropEagerIterator { | ||
implicit def makeDropEagerIterator[T](it: Iterator[T]): DropEagerIterator[T] = | ||
DropEagerIterator(it) | ||
} |
77 changes: 77 additions & 0 deletions
77
src/main/scala/org/hammerlab/iterator/EitherIterator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package org.hammerlab.iterator | ||
|
||
import org.hammerlab.iterator.bulk.BufferedBulkIterator._ | ||
import scala.collection.mutable.ArrayBuffer | ||
|
||
case class EitherIterator[T, U](it: BufferedIterator[Either[T, U]]) { | ||
|
||
def findLeft: Option[T] = | ||
it | ||
.collect { | ||
case Left(t) ⇒ t | ||
} | ||
.buffered | ||
.headOption | ||
|
||
def groupByLeft: BufferedIterator[(T, Iterator[U])] = { | ||
|
||
// Clear out any leading Rights | ||
it | ||
.collectwhile { | ||
case Right(_) ⇒ null | ||
} | ||
.toList | ||
|
||
new SimpleBufferedIterator[(T, BufferedIterator[U])] { | ||
var curLeft: Option[T] = None | ||
var curRights = Iterator[U]().buffered | ||
override protected def _advance: Option[(T, BufferedIterator[U])] = { | ||
|
||
// Clear any unused elements from the previous rights/U's/"values" iterator | ||
curRights.toList | ||
|
||
it | ||
.nextOption | ||
.collect { | ||
case Left(t) ⇒ | ||
curRights = | ||
it | ||
.collectwhile { | ||
case Right(u) ⇒ u | ||
} | ||
|
||
t → curRights | ||
case Right(u) ⇒ | ||
throw new IllegalStateException( | ||
s"nextOption should not be a Right" | ||
) | ||
} | ||
} | ||
} | ||
} | ||
|
||
def roundUpRight: BufferedIterator[(Seq[T], U)] = | ||
new SimpleBufferedIterator[(Seq[T], U)] { | ||
override protected def _advance: Option[(Seq[T], U)] = { | ||
val lefts = ArrayBuffer[T]() | ||
while (true) { | ||
it.headOption match { | ||
case Some(Left(t)) ⇒ | ||
it.next | ||
lefts += t | ||
case Some(Right(u)) ⇒ | ||
it.next | ||
return Some(lefts → u) | ||
case None ⇒ | ||
return None | ||
} | ||
} | ||
??? | ||
} | ||
} | ||
} | ||
|
||
object EitherIterator { | ||
implicit def makeEitherIterator[T, U](it: Iterator[Either[T, U]]): EitherIterator[T, U] = | ||
EitherIterator(it.buffered) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package org.hammerlab.iterator | ||
|
||
import org.hammerlab.iterator.DropEagerIterator._ | ||
|
||
case class SliceIterator[T](it: Iterator[T]) { | ||
def sliceOpt(start: Option[Int], length: Option[Int]): Iterator[T] = { | ||
start.foreach(it.dropEager) | ||
length.map(it.take).getOrElse(it) | ||
} | ||
def sliceOpt(start: Int, length: Int): Iterator[T] = sliceOpt(Some(start), Some(length)) | ||
def sliceOpt(start: Option[Int], length: Int): Iterator[T] = sliceOpt(start, Some(length)) | ||
def sliceOpt(start: Int, length: Option[Int] = None): Iterator[T] = sliceOpt(Some(start), length) | ||
} | ||
|
||
object SliceIterator { | ||
implicit def makeSliceIterator[T](it: Iterator[T]): SliceIterator[T] = SliceIterator(it) | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/scala/org/hammerlab/iterator/bulk/BufferedBulkIterator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package org.hammerlab.iterator.bulk | ||
|
||
import org.hammerlab.iterator.SimpleBufferedIterator | ||
|
||
/** | ||
* Some smarter bulk operations on [[BufferedIterator]]s | ||
*/ | ||
case class BufferedBulkIterator[T](it: BufferedIterator[T]) { | ||
def takewhile(fn: T ⇒ Boolean): SimpleBufferedIterator[T] = | ||
new SimpleBufferedIterator[T] { | ||
override protected def _advance: Option[T] = | ||
if (it.hasNext && fn(it.head)) | ||
Some(it.next) | ||
else | ||
None | ||
} | ||
|
||
def dropwhile(fn: T ⇒ Boolean): Unit = | ||
while (it.hasNext && fn(it.head)) | ||
it.next | ||
|
||
def collectwhile[U](pf: PartialFunction[T, U]): BufferedIterator[U] = | ||
new SimpleBufferedIterator[U] { | ||
override protected def _advance: Option[U] = | ||
if (it.hasNext && pf.isDefinedAt(it.head)) | ||
Some( | ||
pf( | ||
it.next | ||
) | ||
) | ||
else | ||
None | ||
} | ||
} | ||
|
||
object BufferedBulkIterator { | ||
implicit def makeBufferedBulkWhileIterator[T](it: BufferedIterator[T]): BufferedBulkIterator[T] = | ||
BufferedBulkIterator(it) | ||
} |
71 changes: 71 additions & 0 deletions
71
src/main/scala/org/hammerlab/iterator/range/OverlappingRangesIterator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package org.hammerlab.iterator.range | ||
|
||
import org.hammerlab.iterator.SimpleBufferedIterator | ||
|
||
import scala.collection.mutable | ||
|
||
case class OverlappingRangesIterator[T: Ordering](it: BufferedIterator[Range[T]]) { | ||
|
||
type RangeT = (T, Option[T]) | ||
|
||
val ≤ = implicitly[Ordering[T]].lteq _ | ||
|
||
implicit val orderZippedRangeByEndOpt: Ordering[(Range[T], Int)] = | ||
Ordering | ||
.by[(Range[T], Int), Option[T]](_._1.endOpt) | ||
.reverse | ||
|
||
def joinOverlaps(other: Iterable[Range[T]]): Iterator[(Range[T], Vector[(Range[T], Int)])] = | ||
joinOverlaps(other.iterator.buffered) | ||
|
||
def joinOverlaps(other: BufferedIterator[Range[T]]): Iterator[(Range[T], Vector[(Range[T], Int)])] = { | ||
val queue = mutable.PriorityQueue[(Range[T], Int)]() | ||
|
||
val zippedOther = | ||
other | ||
.zipWithIndex | ||
.buffered | ||
|
||
new SimpleBufferedIterator[(Range[T], Vector[(Range[T], Int)])] { | ||
override protected def _advance: Option[(Range[T], Vector[(Range[T], Int)])] = | ||
it | ||
.nextOption | ||
.map { | ||
elem ⇒ | ||
while (queue.headOption.exists(!_._1.∩(elem))) { | ||
queue.dequeue() | ||
} | ||
|
||
while ( | ||
zippedOther | ||
.headOption | ||
.flatMap(_._1.endOpt) | ||
.exists(≤(_, elem.start)) | ||
) { | ||
zippedOther.next | ||
} | ||
|
||
while ( | ||
zippedOther | ||
.headOption | ||
.exists(_._1.∩(elem)) | ||
) { | ||
queue.enqueue(zippedOther.next) | ||
} | ||
|
||
elem → | ||
queue | ||
.toVector | ||
.sortBy(_._2) | ||
} | ||
} | ||
} | ||
} | ||
|
||
object OverlappingRangesIterator { | ||
implicit def makeOverlappingRangesIteratorFromIterable[T: Ordering](it: Iterable[Range[T]]): OverlappingRangesIterator[T] = | ||
OverlappingRangesIterator(it.iterator.buffered) | ||
|
||
implicit def makeOverlappingRangesIterator[T: Ordering](it: Iterator[Range[T]]): OverlappingRangesIterator[T] = | ||
OverlappingRangesIterator(it.buffered) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.hammerlab.iterator.range | ||
|
||
case class Range[T](start: T, endOpt: Option[T]) { | ||
def ∩(right: Range[T])(implicit ord: Ordering[T]): Boolean = { | ||
val ≤ = ord.lteq _ | ||
val Range(rightStart, rightEndOpt) = right | ||
if (≤(start, rightStart)) | ||
!endOpt.exists(≤(_, rightStart)) | ||
else | ||
!rightEndOpt.exists(≤(_, start)) | ||
} | ||
|
||
override def toString: String = | ||
s"[$start,${endOpt.getOrElse("∞")})" | ||
} | ||
|
||
object Range { | ||
def apply[T](start: T, end: T): Range[T] = Range(start, Some(end)) | ||
def apply[T](start: T): Range[T] = Range(start, None) | ||
|
||
implicit def endOptOrdering[T](implicit ord: Ordering[T]): Ordering[Option[T]] = | ||
new Ordering[Option[T]] { | ||
override def compare(x: Option[T], y: Option[T]): Int = | ||
(x, y) match { | ||
case (None, None) ⇒ 0 | ||
case (None, _) ⇒ -1 | ||
case (_, None) ⇒ 1 | ||
case (Some(x), Some(y)) ⇒ ord.compare(x, y) | ||
} | ||
} | ||
|
||
implicit def orderByStartThenEnd[T: Ordering]: Ordering[Range[T]] = { | ||
|
||
implicit val tupleOrdering = | ||
Ordering.Tuple2[T, Option[T]] | ||
|
||
Ordering.by[Range[T], (T, Option[T])] { | ||
case Range(start, endOpt) ⇒ | ||
start → endOpt | ||
} | ||
} | ||
} |
4 changes: 3 additions & 1 deletion
4
...hammerlab/iterator/Sliding2Iterator.scala → ...b/iterator/sliding/Sliding2Iterator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 3 additions & 1 deletion
4
...hammerlab/iterator/Sliding3Iterator.scala → ...b/iterator/sliding/Sliding3Iterator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 3 additions & 1 deletion
4
.../hammerlab/iterator/SlidingIterator.scala → ...ab/iterator/sliding/SlidingIterator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.