Skip to content

Commit

Permalink
Prepared for include into zip implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszwawrzyk committed Aug 10, 2018
1 parent c026120 commit 18367b8
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 17 deletions.
3 changes: 2 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ resolvers += Resolver.sonatypeRepo("releases")
libraryDependencies ++= Seq(
"net.lingala.zip4j" % "zip4j" % "1.3.2",
"org.openjdk.jmh" % "jmh-core" % "1.21",
"org.openjdk.jmh" % "jmh-generator-annprocess" % "1.21"
"org.openjdk.jmh" % "jmh-generator-annprocess" % "1.21",
"org.scala-sbt" %% "io" % "1.2.1"
)

enablePlugins(JmhPlugin)
4 changes: 4 additions & 0 deletions src/main/java/org/virtuslab/zipops/ZipMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,10 @@ public static class Entry extends IndexNode {

Entry() {}

public long getLastModifiedTime() {
return mtime;
}

public long getEntryOffset() {
return locoff;
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/org/virtuslab/zipops/IndexBasedZipOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import java.nio.channels.{ FileChannel, Channels, ReadableByteChannel }
import java.io._
import java.nio.file.{ Files, Path }

import org.virtuslab.zipops.ZipOps.InZipPath

trait IndexBasedZipOps extends ZipOps {

override def includeFiles(zip: File, files: Seq[(File, InZipPath)]): Unit = () // noop for now

override def readPaths(jar: File): Seq[String] = {
val metadata = readMetadata(jar.toPath)
val headers = getHeaders(metadata)
Expand Down
15 changes: 12 additions & 3 deletions src/main/scala/org/virtuslab/zipops/ZipOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@ package org.virtuslab.zipops

import java.io.File

import org.virtuslab.zipops.ZipOps.{ InZipPath, Timestamp }

object ZipOps {
type InZipPath = String
type Timestamp = Long
}

trait ZipOps {
def readPaths(jar: File): Seq[String]
def readPaths(jar: File): Seq[InZipPath]
def createStamper(jar: File): Stamper
def readCentralDirectory(jar: File): Unit = ()
def removeEntries(jarFile: File, classes: Iterable[String]): Unit
def removeEntries(jarFile: File, classes: Iterable[InZipPath]): Unit
def mergeArchives(into: File, from: File): Unit
def includeFiles(zip: File, files: Seq[(File, InZipPath)])
}

trait Stamper {
def readStamp(jar: File, cls: String): Long

def readStamp(jar: File, cls: InZipPath): Timestamp
}
8 changes: 7 additions & 1 deletion src/main/scala/org/virtuslab/zipops/bench/BenchUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,13 @@ trait BenchUtil {
tempFile.toFile
}

def extract(zip: File, targetDir: Path): Unit = {
def extractSomewhere(file: File): Path = {
val tempDir = Files.createTempDirectory("lols")
extract(file, tempDir)
tempDir
}

private def extract(zip: File, targetDir: Path): Unit = {
new ZipFile(zip).extractAll(targetDir.toString)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package org.virtuslab.zipops.bench
import org.virtuslab.zipops.ZipOps
import org.openjdk.jmh.annotations._
import java.io.File
import ZipOpsBench._

class BigCentralDirBench extends CentralDirBenchmark("scala-library-2.12.6.jar")
class BigCentralDirBench extends CentralDirBenchmark(BigJar)

@State(Scope.Thread)
abstract class CentralDirBenchmark(jar: String) extends ZipOpsBench with BenchUtil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import java.io.File

import org.openjdk.jmh.annotations._
import org.virtuslab.zipops.ZipOps
import ZipOpsBench._

class DeleteFromBigJarBench extends DeleteBenchmark("scala-library-2.12.6.jar") {
class DeleteFromBigJarBench extends DeleteBenchmark(BigJar) {

val toDelete = Set(
"scala/util/matching/Regex$MatchIterator$$anon$1.class",
Expand Down Expand Up @@ -33,7 +34,7 @@ class DeleteFromBigJarBench extends DeleteBenchmark("scala-library-2.12.6.jar")

}

class SmallJarDeleteBench extends DeleteBenchmark("scala-xml_2.12-1.0.6.jar") {
class SmallJarDeleteBench extends DeleteBenchmark(MediumJar) {

val toDelete = Set(
"scala/xml/pull/EvText.class",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.virtuslab.zipops.bench

import org.virtuslab.zipops.ZipOps
import java.io.File

import ZipOpsBench._

import org.openjdk.jmh.annotations._
import sbt.io.{ IO, DirectoryFilter }

class IncludeSomeFilesBench extends IncludeFilesBenchmark(zip = BigJar, zipToExtractAndInclude = SmallJar)

@State(Scope.Thread)
abstract class IncludeFilesBenchmark(
zip: String,
zipToExtractAndInclude: String
) extends ZipOpsBench with BenchUtil {

var zipFile: File = _
var extractDir: File = _
var extractedFiles: Seq[(File, String)] = _

@Setup(Level.Invocation)
def setup(): Unit = {
zipFile = copyResource(zip)

val zipToExtract = copyResource(zipToExtractAndInclude)
extractDir = extractSomewhere(zipToExtract).toFile
extractedFiles = dirContent(extractDir)
}

private def dirContent(dir: File): Seq[(File, String)] = {
import sbt.io.syntax._
(dir ** -DirectoryFilter).get.flatMap { extractedFile =>
IO.relativize(dir, extractedFile) match {
case Some(relPath) =>
List((extractedFile, relPath))
case _ => Nil
}
}
}

@TearDown(Level.Invocation)
def teardown(): Unit = {
zipFile.delete()
IO.delete(extractDir)
}

override def run(ops: ZipOps): Unit = ops.includeFiles(zipFile, extractedFiles)

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import java.io.File

import org.virtuslab.zipops.ZipOps
import org.openjdk.jmh.annotations._
import ZipOpsBench._

class MergeToSmallBench extends MergeBench("scala-xml_2.12-1.0.6.jar", "zip-ops_2.12-0.1.jar")
class MergeToSmallBench extends MergeBench(MediumJar, SmallJar)

class MergeToBigBench extends MergeBench("scala-library-2.12.6.jar", "zip-ops_2.12-0.1.jar")
class MergeToBigBench extends MergeBench(BigJar, SmallJar)

class MergeBigToSmallBench extends MergeBench("zip-ops_2.12-0.1.jar", "scala-library-2.12.6.jar")
class MergeBigToSmallBench extends MergeBench(SmallJar, BigJar)

@State(Scope.Thread)
abstract class MergeBench(target: String, source: String) extends ZipOpsBench with BenchUtil {
Expand Down
10 changes: 5 additions & 5 deletions src/main/scala/org/virtuslab/zipops/bench/StamperBenchmark.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import java.util.concurrent.TimeUnit.{ SECONDS, MILLISECONDS }
import ZipOpsBench._
import org.openjdk.jmh.infra.Blackhole
import org.virtuslab.zipops.impl.MyZipFsOps
import sbt.io.IO

class BigJarStamperBenchmark extends StamperBenchmark("scala-library-2.12.6.jar")
class SmallJarStamperBenchmark extends StamperBenchmark("zip-ops_2.12-0.1.jar")
class BigJarStamperBenchmark extends StamperBenchmark(BigJar)
class SmallJarStamperBenchmark extends StamperBenchmark(SmallJar)

@State(Scope.Thread)
abstract class StamperBenchmark(jar: String) extends ZipOpsBench with BenchUtil {
Expand All @@ -24,16 +25,15 @@ abstract class StamperBenchmark(jar: String) extends ZipOpsBench with BenchUtil
@Setup(Level.Trial)
def setup(): Unit = {
jarFile = copyResource(jar)
extractDir = Files.createTempDirectory("lols")
extract(jarFile, extractDir)
extractDir = extractSomewhere(jarFile)
inJarPaths = MyZipFsOps.readPaths(jarFile)
absExtractedPaths = inJarPaths.map(extractDir.resolve).map(_.toAbsolutePath)
}

@TearDown(Level.Trial)
def teardown(): Unit = {
jarFile.delete()
// TODO rm extract dir
IO.delete(extractDir.toFile)
}

@Benchmark
Expand Down
4 changes: 4 additions & 0 deletions src/main/scala/org/virtuslab/zipops/bench/ZipOpsBench.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ object ZipOpsBench {
final val WarmupIterationTime = 20
final val Iterations = 10
final val IterationTime = 20

val BigJar = "scala-library-2.12.6.jar" // 2542 files
val MediumJar = "scala-xml_2.12-1.0.6.jar" // 249 files
val SmallJar = "zip-ops_2.12-0.1.jar" // 9 files, 3 dirs
}

trait ZipOpsBench {
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/org/virtuslab/zipops/impl/MyZipFsOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ trait MyZipFsOpsBase extends IndexBasedZipOps {
}

protected def getLastModifiedTime(header: Header): Long = {
header.mtime
header.getLastModifiedTime
}

protected def dumpMetadata(metadata: Metadata, outputStream: OutputStream): Unit = {
Expand Down
16 changes: 16 additions & 0 deletions src/main/scala/org/virtuslab/zipops/impl/ZipFsOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,26 @@ import java.util.function.Consumer
import java.io.File
import java.nio.file._

import org.virtuslab.zipops.ZipOps.InZipPath
import org.virtuslab.zipops.{ Stamper, ZipOps }

object ZipFsOps extends ZipOps {

override def includeFiles(zip: File, files: Seq[(File, InZipPath)]): Unit = {
withZipFs(zip, create = true) { fs =>
files.foreach {
case (file, target) =>
val targetPath = fs.getPath(target)
Option(targetPath.getParent).foreach(Files.createDirectories(_))
Files.copy(
file.toPath,
targetPath,
StandardCopyOption.REPLACE_EXISTING,
StandardCopyOption.COPY_ATTRIBUTES)
}
}
}

override def readPaths(jar: File): Seq[String] = {
if (jar.exists()) {
withZipFs(jar) { fs =>
Expand Down

0 comments on commit 18367b8

Please sign in to comment.