2009-08-26 14:38:20 +02:00
|
|
|
package xsbt
|
|
|
|
|
|
|
|
|
|
import java.io.File
|
|
|
|
|
import scala.collection.mutable.{HashMap, Map, MultiMap, Set}
|
2009-08-29 16:19:00 +02:00
|
|
|
import scala.reflect.Manifest
|
|
|
|
|
import sbinary.{DefaultProtocol, Format}
|
2009-08-26 14:38:20 +02:00
|
|
|
import DefaultProtocol._
|
|
|
|
|
import TrackingFormat._
|
2009-08-29 16:19:00 +02:00
|
|
|
import CacheIO.{fromFile, toFile}
|
2009-08-30 17:10:37 +02:00
|
|
|
import DependencyTracking.{DependencyMap => DMap, newMap, TagMap}
|
2009-08-26 14:38:20 +02:00
|
|
|
|
2009-08-29 16:19:00 +02:00
|
|
|
private class TrackingFormat[T](directory: File, translateProducts: Boolean)(implicit tFormat: Format[T], mf: Manifest[T]) extends NotNull
|
2009-08-26 14:38:20 +02:00
|
|
|
{
|
|
|
|
|
val indexFile = new File(directory, "index")
|
|
|
|
|
val dependencyFile = new File(directory, "dependencies")
|
|
|
|
|
def read(): DependencyTracking[T] =
|
|
|
|
|
{
|
2009-08-29 16:19:00 +02:00
|
|
|
val indexMap = CacheIO.fromFile[Map[Int,T]](indexFile)
|
2009-08-26 14:38:20 +02:00
|
|
|
val indexedFormat = wrap[T,Int](ignore => error("Read-only"), indexMap.apply)
|
2009-08-29 16:19:00 +02:00
|
|
|
val trackFormat = trackingFormat(translateProducts)(indexedFormat)
|
|
|
|
|
fromFile(trackFormat)(dependencyFile)
|
2009-08-26 14:38:20 +02:00
|
|
|
}
|
|
|
|
|
def write(tracking: DependencyTracking[T])
|
|
|
|
|
{
|
|
|
|
|
val index = new IndexMap[T]
|
|
|
|
|
val indexedFormat = wrap[T,Int](t => index(t), ignore => error("Write-only"))
|
2009-08-29 16:19:00 +02:00
|
|
|
val trackFormat = trackingFormat(translateProducts)(indexedFormat)
|
|
|
|
|
toFile(trackFormat)(tracking)(dependencyFile)
|
|
|
|
|
toFile(index.indices)(indexFile)
|
2009-08-26 14:38:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private object TrackingFormat
|
|
|
|
|
{
|
|
|
|
|
implicit def mutableMapFormat[S, T](implicit binS : Format[S], binT : Format[T]) : Format[Map[S, T]] =
|
|
|
|
|
viaArray( (x : Array[(S, T)]) => Map(x :_*));
|
|
|
|
|
implicit def depMapFormat[T](implicit bin: Format[T]) : Format[DMap[T]] =
|
|
|
|
|
{
|
|
|
|
|
viaArray { (x : Array[(T, Set[T])]) =>
|
|
|
|
|
val map = newMap[T]
|
|
|
|
|
map ++= x
|
|
|
|
|
map
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
def trackingFormat[T](translateProducts: Boolean)(implicit tFormat: Format[T]): Format[DependencyTracking[T]] =
|
2009-08-30 17:10:37 +02:00
|
|
|
{
|
|
|
|
|
implicit val arrayFormat = sbinary.Operations.format[Array[Byte]]
|
|
|
|
|
asProduct4((a: DMap[T],b: DMap[T],c: DMap[T], d:TagMap[T]) => new DefaultTracking(translateProducts)(a,b,c,d) : DependencyTracking[T]
|
|
|
|
|
)(dt => Some(dt.reverseDependencies, dt.reverseUses, dt.sourceMap, dt.tagMap))
|
|
|
|
|
}
|
2009-08-26 14:38:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private final class IndexMap[T] extends NotNull
|
|
|
|
|
{
|
|
|
|
|
private[this] var lastIndex = 0
|
|
|
|
|
private[this] val map = new HashMap[T, Int]
|
|
|
|
|
def indices = map.toArray.map( (_: (T,Int)).swap )
|
|
|
|
|
def apply(t: T) = map.getOrElseUpdate(t, { lastIndex += 1; lastIndex })
|
|
|
|
|
}
|