Merge branch 'develop'
This commit is contained in:
commit
e5d86ee61e
6
Makefile
6
Makefile
|
@ -56,7 +56,7 @@ $(TARGET)/jni-classes/org/xerial/snappy/SnappyNative.class : $(SRC)/org/xerial/s
|
|||
$(JAVAC) -source 1.6 -target 1.6 -d $(TARGET)/jni-classes -sourcepath $(SRC) $<
|
||||
|
||||
$(SRC)/org/xerial/snappy/SnappyNative.h: $(TARGET)/jni-classes/org/xerial/snappy/SnappyNative.class
|
||||
$(JAVAH) -force -classpath $(TARGET)/classes -o $@ org.xerial.snappy.SnappyNative
|
||||
$(JAVAH) -force -classpath $(TARGET)/jni-classes -o $@ org.xerial.snappy.SnappyNative
|
||||
|
||||
ifndef USE_GIT
|
||||
$(SNAPPY_SRC): $(SNAPPY_UNPACKED)
|
||||
|
@ -135,6 +135,10 @@ linux-arm:
|
|||
linux-armhf:
|
||||
$(MAKE) native CROSS_PREFIX=arm-linux-gnueabihf- OS_NAME=Linux OS_ARCH=armhf
|
||||
|
||||
# for cross-compilation on Ubuntu, install the g++-aarch64-linux-gnu
|
||||
linux-aarch64:
|
||||
$(MAKE) native CROSS_PREFIX=aarch64-linux-gnu- OS_NAME=Linux OS_ARCH=aarch64
|
||||
|
||||
clean-native-linux32:
|
||||
$(MAKE) clean-native OS_NAME=Linux OS_ARCH=x86
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
TARGET:=target
|
||||
SRC:=src/main/java
|
||||
include $(SRC)/org/xerial/snappy/VERSION
|
||||
include src/main/resources/org/xerial/snappy/VERSION
|
||||
|
||||
ifndef JAVA_HOME
|
||||
$(error Set JAVA_HOME environment variable)
|
||||
|
@ -42,7 +42,7 @@ endif
|
|||
|
||||
# os=Default is meant to be generic unix/linux
|
||||
|
||||
known_os_archs := Linux-x86 Linux-x86_64 Linux-arm Linux-armhf Linux-ppc64 Mac-x86 Mac-x86_64 FreeBSD-x86_64 Windows-x86 Windows-x86_64 SunOS-x86 SunOS-sparc SunOS-x86_64
|
||||
known_os_archs := Linux-x86 Linux-x86_64 Linux-arm Linux-armhf Linux-ppc Linux-ppc64 Mac-x86 Mac-x86_64 FreeBSD-x86_64 Windows-x86 Windows-x86_64 SunOS-x86 SunOS-sparc SunOS-x86_64 AIX-ppc64
|
||||
os_arch := $(OS_NAME)-$(OS_ARCH)
|
||||
IBM_JDK_7 := $(findstring IBM, $(shell $(JAVA) -version 2>&1 | grep IBM | grep "JRE 1.7"))
|
||||
|
||||
|
@ -50,12 +50,14 @@ ifeq (,$(findstring $(strip $(os_arch)),$(known_os_archs)))
|
|||
os_arch := Default
|
||||
endif
|
||||
|
||||
os_folder := $(shell echo $(OS_NAME) | tr A-Z a-z)
|
||||
|
||||
ifneq ($(IBM_JDK_7),)
|
||||
$(shell mkdir -p $(IBM_JDK_LIB))
|
||||
$(shell cp $(JAVA_HOME)/include/jniport.h $(IBM_JDK_LIB))
|
||||
$(shell sed -i "s|#define JNIEXPORT *$$|#define JNIEXPORT __attribute__((__visibility__(\"default\")))|" $(IBM_JDK_LIB)/jniport.h)
|
||||
$(shell sed -i "s|typedef long long jlong;.*|/*typedef long long jlong;*/|" $(IBM_JDK_LIB)/jniport.h)
|
||||
$(shell cp $(JAVA_HOME)/include/linux/jni_md.h $(IBM_JDK_LIB))
|
||||
$(shell cp $(JAVA_HOME)/include/$(os_folder)/jni_md.h $(IBM_JDK_LIB))
|
||||
$(shell sed -i "s|#define JNIEXPORT|#define JNIEXPORT __attribute__((__visibility__(\"default\")))|" $(IBM_JDK_LIB)/jni_md.h)
|
||||
$(shell sed -i "s|typedef long long jlong;.*|/*typedef long long jlong;*/|" $(IBM_JDK_LIB)/jni_md.h)
|
||||
endif
|
||||
|
@ -92,17 +94,39 @@ Linux-x86_64_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
|||
Linux-x86_64_LIBNAME := libsnappyjava.so
|
||||
Linux-x86_64_SNAPPY_FLAGS :=
|
||||
|
||||
Linux-ppc_CXX := g++
|
||||
Linux-ppc_STRIP := strip
|
||||
ifeq ($(IBM_JDK_7),)
|
||||
Linux-ppc_CXXFLAGS := -DHAVE_CONFIG_H -Ilib/inc_linux -I$(JAVA_HOME)/include -Ilib/inc_mac -O2 -fPIC -fvisibility=hidden -m32
|
||||
else
|
||||
Linux-ppc_CXXFLAGS := -DHAVE_CONFIG_H -include lib/inc_linux/jni_md.h -include $(IBM_JDK_LIB)/jniport.h -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -O2 -fPIC -m32
|
||||
endif
|
||||
Linux-ppc_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
||||
Linux-ppc_LIBNAME := libsnappyjava.so
|
||||
Linux-ppc_SNAPPY_FLAGS :=
|
||||
|
||||
Linux-ppc64_CXX := g++
|
||||
Linux-ppc64_STRIP := strip
|
||||
ifeq ($(IBM_JDK_7),)
|
||||
Linux-ppc64_CXXFLAGS := -DHAVE_CONFIG_H -Ilib/inc_linux -I$(JAVA_HOME)/include -Ilib/inc_mac -O2 -fPIC -fvisibility=hidden -m64
|
||||
else
|
||||
Linux-ppc64_CXXFLAGS := -DHAVE_CONFIG_H -include $(IBM_JDK_LIB)/jni_md.h -include $(IBM_JDK_LIB)/jniport.h -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -O2 -fPIC
|
||||
Linux-ppc64_CXXFLAGS := -DHAVE_CONFIG_H -include $(IBM_JDK_LIB)/jni_md.h -include $(IBM_JDK_LIB)/jniport.h -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux -O2 -fPIC -m64
|
||||
endif
|
||||
Linux-ppc64_LINKFLAGS := -shared -static-libgcc -static-libstdc++
|
||||
Linux-ppc64_LIBNAME := libsnappyjava.so
|
||||
Linux-ppc64_SNAPPY_FLAGS :=
|
||||
|
||||
AIX-ppc64_CXX := g++
|
||||
AIX-ppc64_STRIP := strip -X64
|
||||
AIX-ppc64_LIBNAME := libsnappyjava.a
|
||||
ifeq ($(IBM_JDK_7),)
|
||||
AIX-ppc64_CXXFLAGS := -DHAVE_CONFIG_H -Ilib/inc_linux -I$(JAVA_HOME)/include -Ilib/inc_mac -O2 -fPIC -fvisibility=hidden -m64
|
||||
else
|
||||
AIX-ppc64_CXXFLAGS := -DHAVE_CONFIG_H -I$(JAVA_HOME)/include/aix -Ilib/inc_ibm -I$(JAVA_HOME)/include -Ilib/inc_mac -O2 -fPIC -maix64
|
||||
endif
|
||||
AIX-ppc64_LINKFLAGS := -shared -static-libgcc -static-libstdc++ -lcrypt
|
||||
AIX-ppc64_SNAPPY_FLAGS :=
|
||||
|
||||
SunOS-x86_CXX := g++
|
||||
SunOS-x86_STRIP := strip
|
||||
SunOS-x86_CXXFLAGS := -include lib/inc_linux/jni_md.h -I$(JAVA_HOME)/include -O2 -fPIC -fvisibility=hidden
|
||||
|
@ -193,3 +217,4 @@ ifneq ($(jni_include),)
|
|||
CXXFLAGS := $(CXXFLAGS) -I"$(jni_include)"
|
||||
endif
|
||||
|
||||
|
||||
|
|
22
Milestone.md
22
Milestone.md
|
@ -1,9 +1,23 @@
|
|||
## Features under consideration
|
||||
* `SnappyIndexer` for parallel compression/decompression
|
||||
* CUI commands (snap/unsnap)
|
||||
|
||||
Since vesion 1.1.0.x, Java 6 (1.6) or higher is required.
|
||||
|
||||
## snappy-java-1.1.2-RC1 (13 May 2015)
|
||||
* SnappyInputStream now supports reading concatenated compressed results of SnappyOutputStream
|
||||
* There has been no compressed format change since 1.0.5.x. So You can read the compressed results interchangeablly between these versions.
|
||||
* Fixes a problem when java.io.tmpdir does not exist.
|
||||
|
||||
## snappy-java-1.1.1.7 (14 Apr 2015)
|
||||
* Fixes #100
|
||||
|
||||
## snappy-java-1.1.1.6 (26 Oct 2014)
|
||||
* Fixes #88, #89, #90 and #91
|
||||
* Fixed the broken build of 1.1.1.4 and memory leak bug 1.1.1.5 (so never use these versions)
|
||||
|
||||
## snappy-java-1.0.5.4 (12 September 2014)
|
||||
* Embedded libstdc++ for Linux/amd64 native library (hotfix to 1.0.5.x series)
|
||||
|
||||
## snappy-java-1.1.1.3 (19 July 2014)
|
||||
* Improved the performance of SnappyOutputStream
|
||||
|
||||
## snappy-java-1.1.1 (4 July 2014)
|
||||
* Added Snappy framing format support: SnappyFramedInput/OutputStream
|
||||
* Added native libraries for PowerPC, IBM-AIX 6.4, SunOS.
|
||||
|
|
64
README.md
64
README.md
|
@ -2,9 +2,11 @@ The snappy-java is a Java port of the snappy
|
|||
<http://code.google.com/p/snappy/>, a fast C++ compresser/decompresser developed by Google.
|
||||
|
||||
## Features
|
||||
* Fast compression/decompression tailored to 64-bit CPU architecture.
|
||||
* Fast compression/decompression around 200~400MB/sec.
|
||||
* Less memory usage. SnappyOutputStream uses only 32KB+ in default.
|
||||
* JNI-based implementation to achieve comparable performance to the native C++ version.
|
||||
* Although snappy-java uses JNI, it can be used safely with multiple class loaders (e.g. Tomcat, etc.).
|
||||
* Although snappy-java uses JNI, it can be used safely with multiple class loaders (e.g. Tomcat, etc.).
|
||||
* Compression/decompression of Java primitive arrays (`float[]`, `double[]`, `int[]`, `short[]`, `long[]`, etc.)
|
||||
* Portable across various operating systems; Snappy-java contains native libraries built for Window/Mac/Linux (64-bit). snappy-java loads one of these libraries according to your machine environment (It looks system properties, `os.name` and `os.arch`).
|
||||
* Simple usage. Add the snappy-java-(version).jar file to your classpath. Then call compression/decompression methods in `org.xerial.snappy.Snappy`.
|
||||
* [Framing-format support](http://snappy.googlecode.com/svn/trunk/framing_format.txt) (Since 1.1.0 version)
|
||||
|
@ -17,10 +19,8 @@ The snappy-java is a Java port of the snappy
|
|||
* Here are some [benchmark results](https://github.com/ning/jvm-compressor-benchmark/wiki), comparing
|
||||
snappy-java and the other compressors
|
||||
`LZO-java`/`LZF`/`QuickLZ`/`Gzip`/`Bzip2`. Thanks [Tatu Saloranta @cotowncoder](http://twitter.com/#!/cowtowncoder) for providing the benchmark suite.
|
||||
* The benchmark result indicates snappy-java is the fastest compreesor/decompressor in Java
|
||||
* <http://ning.github.com/jvm-compressor-benchmark/results/canterbury-roundtrip-2011-07-28/index.html>
|
||||
* The decompression speed is twice as fast as the others:
|
||||
* <http://ning.github.com/jvm-compressor-benchmark/results/canterbury-uncompress-2011-07-28/index.html>
|
||||
* The benchmark result indicates snappy-java is the fastest compreesor/decompressor in Java: http://ning.github.com/jvm-compressor-benchmark/results/canterbury-roundtrip-2011-07-28/index.html
|
||||
* The decompression speed is twice as fast as the others: http://ning.github.com/jvm-compressor-benchmark/results/canterbury-uncompress-2011-07-28/index.html
|
||||
|
||||
|
||||
## Download
|
||||
|
@ -29,10 +29,27 @@ The snappy-java is a Java port of the snappy
|
|||
|
||||
The current stable version is available from here:
|
||||
* Release version: http://central.maven.org/maven2/org/xerial/snappy/snappy-java/
|
||||
* (Old archives are here: http://code.google.com/p/snappy-java/downloads/list)
|
||||
* Snapshot version (the latest beta version): https://oss.sonatype.org/content/repositories/snapshots/org/xerial/snappy/snappy-java/
|
||||
|
||||
For Maven user, see [pom.xml example](#using-with-maven).
|
||||
### Using with Maven
|
||||
* Snappy-java is available from Maven's central repository: <http://central.maven.org/maven2/org/xerial/snappy/snappy-java>
|
||||
|
||||
Add the following dependency to your pom.xml:
|
||||
|
||||
<dependency>
|
||||
<groupId>org.xerial.snappy</groupId>
|
||||
<artifactId>snappy-java</artifactId>
|
||||
<version>1.1.2-RC1</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
### Using with sbt
|
||||
|
||||
```
|
||||
libraryDependencies += "org.xerial.snappy" % "snappy-java" % "1.1.2-RC1"
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
First, import `org.xerial.snapy.Snappy` in your Java code:
|
||||
|
@ -56,9 +73,18 @@ System.out.println(result);
|
|||
In addition, high-level methods (`Snappy.compress(String)`, `Snappy.compress(float[] ..)` etc. ) and low-level ones (e.g. `Snappy.rawCompress(.. )`, `Snappy.rawUncompress(..)`, etc.), which minimize memory copies, can be used.
|
||||
|
||||
### Stream-based API
|
||||
Stream-based compressor/decompressor `SnappyFramedOutputStream`/`SnappyFramedInputStream` are also available for reading/writing large data sets.
|
||||
Stream-based compressor/decompressor `SnappyOutputStream`/`SnappyInputStream` are also available for reading/writing large data sets. `SnappyFramedOutputStream`/`SnappyFramedInputStream` can be used for the [framing format](https://code.google.com/p/snappy/source/browse/trunk/framing_format.txt).
|
||||
|
||||
* See also [Javadoc API](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/snappy/snappy-java/1.1.0/snappy-java-1.1.0-javadoc.jar/!/index.html)
|
||||
* See also [Javadoc API](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/snappy/snappy-java/1.1.1.6/snappy-java-1.1.1.6-javadoc.jar/!/index.html)
|
||||
|
||||
#### Compatibility Notes
|
||||
* `SnappyOutputStream` and `SnappyInputStream` use `[magic header:16 bytes]([block size:int32][compressed data:byte array])*` format. You can read the result of `Snappy.compress` with `SnappyInputStream`, but you cannot read the compressed data generated by `SnappyOutputStream` with `Snappy.uncompress`. Here is the compatibility matrix of data foramt:
|
||||
|
||||
| Write\Read | `Snappy.uncompress` | `SnappyInputStream` | `SnappyFramedInputStream` |
|
||||
| --------------- |:-------------------:|:------------------:|:-----------------------:|
|
||||
| `Snappy.compress` | ok | ok | x |
|
||||
| `SnappyOutputStream` | x | ok | x |
|
||||
| `SnappyFramedOutputStream` | x | x | ok |
|
||||
|
||||
### Setting classpath
|
||||
If you have snappy-java-(VERSION).jar in the current directory, use `-classpath` option as follows:
|
||||
|
@ -68,24 +94,6 @@ If you have snappy-java-(VERSION).jar in the current directory, use `-classpath`
|
|||
$ javac -classpath ".:snappy-java-(VERSION).jar" Sample.java # in Mac or Linux
|
||||
|
||||
|
||||
### Using with Maven
|
||||
* Snappy-java is available from Maven's central repository: <http://repo1.maven.org/maven2/org/xerial/snappy/snappy-java>
|
||||
|
||||
Add the following dependency to your pom.xml:
|
||||
|
||||
<dependency>
|
||||
<groupId>org.xerial.snappy</groupId>
|
||||
<artifactId>snappy-java</artifactId>
|
||||
<version>(version)</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
### Using with sbt
|
||||
|
||||
```
|
||||
libraryDependencies += "org.xerial.snappy" % "snappy-java" % "(version)"
|
||||
```
|
||||
|
||||
|
||||
## Public discussion group
|
||||
|
|
45
build.sbt
45
build.sbt
|
@ -1,6 +1,3 @@
|
|||
import SonatypeKeys._
|
||||
|
||||
sonatypeSettings
|
||||
|
||||
name := "snappy-java"
|
||||
|
||||
|
@ -10,7 +7,7 @@ organizationName := "xerial.org"
|
|||
|
||||
description := "snappy-java: A fast compression/decompression library"
|
||||
|
||||
profileName := "org.xerial"
|
||||
sonatypeProfileName := "org.xerial"
|
||||
|
||||
pomExtra := {
|
||||
<url>https://github.comm/xerial/snappy-java</url>
|
||||
|
@ -47,11 +44,21 @@ pomExtra := {
|
|||
</scm>
|
||||
}
|
||||
|
||||
scalaVersion := "2.11.6"
|
||||
|
||||
javacOptions in (Compile, compile) ++= Seq("-encoding", "UTF-8", "-Xlint:unchecked", "-Xlint:deprecation", "-source", "1.6", "-target", "1.6")
|
||||
|
||||
javacOptions in doc := {
|
||||
val opts = Seq("-source", "1.6")
|
||||
if (scala.util.Properties.isJavaAtLeast("1.8"))
|
||||
opts ++ Seq("-Xdoclint:none")
|
||||
else
|
||||
opts
|
||||
}
|
||||
|
||||
testOptions += Tests.Argument(TestFrameworks.JUnit, "-q", "-v")
|
||||
|
||||
//concurrentRestrictions in Global := Seq(Tags.limit(Tags.Test, 1))
|
||||
concurrentRestrictions in Global := Seq(Tags.limit(Tags.Test, 1))
|
||||
|
||||
autoScalaLibrary := false
|
||||
|
||||
|
@ -64,7 +71,9 @@ incOptions := incOptions.value.withNameHashing(true)
|
|||
libraryDependencies ++= Seq(
|
||||
"junit" % "junit" % "4.8.2" % "test",
|
||||
"org.codehaus.plexus" % "plexus-classworlds" % "2.4" % "test",
|
||||
"org.xerial" % "xerial-core" % "1.0.21" % "test",
|
||||
"org.xerial.java" % "xerial-core" % "2.1" % "test",
|
||||
"org.xerial" % "xerial-core" % "3.2.3" % "test",
|
||||
"org.scalatest" % "scalatest_2.11" % "2.2.0" % "test",
|
||||
"org.osgi" % "org.osgi.core" % "4.3.0" % "provided",
|
||||
"com.novocode" % "junit-interface" % "0.10" % "test"
|
||||
)
|
||||
|
@ -72,7 +81,7 @@ libraryDependencies ++= Seq(
|
|||
osgiSettings
|
||||
|
||||
|
||||
OsgiKeys.exportPackage := Seq("org.xerial.snappy")
|
||||
OsgiKeys.exportPackage := Seq("org.xerial.snappy", "org.xerial.snappy.buffer")
|
||||
|
||||
OsgiKeys.bundleSymbolicName := "org.xerial.snappy.snappy-java"
|
||||
|
||||
|
@ -88,9 +97,11 @@ OsgiKeys.additionalHeaders := Map(
|
|||
"org/xerial/snappy/native/Mac/x86_64/libsnappyjava.jnilib;osname=macosx;processor=x86-64",
|
||||
"org/xerial/snappy/native/Linux/x86_64/libsnappyjava.so;osname=linux;processor=x86-64",
|
||||
"org/xerial/snappy/native/Linux/x86/libsnappyjava.so;osname=linux;processor=x86",
|
||||
"org/xerial/snappy/native/Linux/aarch64/libsnappyjava.so;osname=linux;processor=aarch64",
|
||||
"org/xerial/snappy/native/Linux/arm/libsnappyjava.so;osname=linux;processor=arm",
|
||||
"org/xerial/snappy/native/Linux/ppc64/libsnappyjava.so;osname=linux;processor=ppc64",
|
||||
"org/xerial/snappy/native/Linux/ppc64le/libsnappyjava.so;osname=linux;processor=ppc64le",
|
||||
"org/xerial/snappy/native/AIX/ppc64/libsnappyjava.a;osname=aix;processor=ppc64",
|
||||
"org/xerial/snappy/native/SunOS/x86/libsnappyjava.so;osname=sunos;processor=x86",
|
||||
"org/xerial/snappy/native/SunOS/x86_64/libsnappyjava.so;osname=sunos;processor=x86-64",
|
||||
"org/xerial/snappy/native/SunOS/sparc/libsnappyjava.so;osname=sunos;processor=sparc"
|
||||
|
@ -100,3 +111,23 @@ OsgiKeys.additionalHeaders := Map(
|
|||
"Bundle-ActivationPolicy" -> "lazy",
|
||||
"Bundle-Name" -> "snappy-java: A fast compression/decompression library"
|
||||
)
|
||||
|
||||
import ReleaseTransformations._
|
||||
import sbtrelease._
|
||||
|
||||
releaseTagName := { (version in ThisBuild).value }
|
||||
|
||||
releaseProcess := Seq[ReleaseStep](
|
||||
checkSnapshotDependencies,
|
||||
inquireVersions,
|
||||
runClean,
|
||||
runTest,
|
||||
setReleaseVersion,
|
||||
commitReleaseVersion,
|
||||
tagRelease,
|
||||
ReleaseStep(action = Command.process("publishSigned", _)),
|
||||
setNextVersion,
|
||||
commitNextVersion,
|
||||
ReleaseStep(action = Command.process("sonatypeReleaseAll", _)),
|
||||
pushChanges
|
||||
)
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*===========================================================================
|
||||
* Licensed Materials - Property of IBM
|
||||
* "Restricted Materials of IBM"
|
||||
*
|
||||
* IBM SDK, Java(tm) Technology Edition, v7
|
||||
* (C) Copyright IBM Corp. 2014, 2014. All Rights Reserved
|
||||
*
|
||||
* US Government Users Restricted Rights - Use, duplication or disclosure
|
||||
* restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
*===========================================================================
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1996, 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _JAVASOFT_JNI_MD_H_
|
||||
#define _JAVASOFT_JNI_MD_H_
|
||||
|
||||
#define JNIEXPORT __attribute__((__visibility__("default")))
|
||||
#define JNIIMPORT
|
||||
#define JNICALL
|
||||
|
||||
typedef int jint;
|
||||
#ifdef _LP64 /* 64-bit Solaris */
|
||||
typedef long jlong;
|
||||
#else
|
||||
/*typedef long long jlong;*/
|
||||
#endif
|
||||
|
||||
typedef signed char jbyte;
|
||||
|
||||
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
|
@ -0,0 +1,56 @@
|
|||
/*******************************************************************************
|
||||
* Licensed Materials - Property of IBM
|
||||
* "Restricted Materials of IBM"
|
||||
*
|
||||
* (c) Copyright IBM Corp. 1991, 2014 All Rights Reserved
|
||||
*
|
||||
* US Government Users Restricted Rights - Use, duplication or disclosure
|
||||
* restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef jniport_h
|
||||
#define jniport_h
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(RIM386) || (defined(BREW) && defined(AEE_SIMULATOR))
|
||||
|
||||
#define JNIEXPORT __declspec(dllexport)
|
||||
#define JNICALL __stdcall
|
||||
typedef signed char jbyte;
|
||||
typedef int jint;
|
||||
typedef __int64 jlong;
|
||||
|
||||
#else
|
||||
|
||||
#define JNIEXPORT __attribute__((__visibility__("default")))
|
||||
|
||||
typedef signed char jbyte;
|
||||
/*typedef long long jlong;*/
|
||||
|
||||
#ifdef BREW
|
||||
#include "AEEFile.h"
|
||||
#define FILE IFile
|
||||
#endif
|
||||
|
||||
typedef int jint;
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifndef JNICALL
|
||||
#define JNICALL
|
||||
#endif
|
||||
|
||||
#ifndef JNIEXPORT
|
||||
#define JNIEXPORT __attribute__((__visibility__("default")))
|
||||
#endif
|
||||
|
||||
#ifndef JNIIMPORT
|
||||
#define JNIIMPORT
|
||||
#endif
|
||||
|
||||
#ifdef _JNI_IMPLEMENTATION_
|
||||
#define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT
|
||||
#else
|
||||
#define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT
|
||||
#endif
|
||||
|
||||
#endif /* jniport_h */
|
|
@ -1,2 +1,2 @@
|
|||
sbt.version=0.13.5
|
||||
sbt.version=0.13.8
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
|
||||
addSbtPlugin("com.github.gseitz" % "sbt-release" % "0.7.1")
|
||||
addSbtPlugin("com.github.gseitz" % "sbt-release" % "1.0.0")
|
||||
|
||||
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.2.1")
|
||||
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "0.5.0")
|
||||
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3")
|
||||
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0")
|
||||
|
||||
addSbtPlugin("de.johoop" % "findbugs4sbt" % "1.3.0")
|
||||
|
||||
|
|
10
sbt
10
sbt
|
@ -4,8 +4,8 @@
|
|||
# Author: Paul Phillips <paulp@typesafe.com>
|
||||
|
||||
# todo - make this dynamic
|
||||
declare -r sbt_release_version="0.13.1"
|
||||
declare -r sbt_unreleased_version="0.13.2-SNAPSHOT" # -sbt-dev doesn't work at present
|
||||
declare -r sbt_release_version="0.13.8"
|
||||
declare -r sbt_unreleased_version="0.13.8-SNAPSHOT" # -sbt-dev doesn't work at present
|
||||
declare -r buildProps="project/build.properties"
|
||||
|
||||
declare sbt_jar sbt_dir sbt_create sbt_launch_dir
|
||||
|
@ -119,12 +119,12 @@ init_default_option_file () {
|
|||
|
||||
declare -r cms_opts="-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC"
|
||||
declare -r jit_opts="-XX:ReservedCodeCacheSize=256m -XX:+TieredCompilation"
|
||||
declare -r default_jvm_opts="-Dfile.encoding=UTF8 -XX:MaxPermSize=384m -Xms512m -Xmx1536m -Xss2m $jit_opts $cms_opts"
|
||||
declare -r default_jvm_opts="-ea -Dfile.encoding=UTF8 -Xms512m -Xmx1536m -Xss2m $jit_opts $cms_opts"
|
||||
declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy"
|
||||
declare -r latest_28="2.8.2"
|
||||
declare -r latest_29="2.9.3"
|
||||
declare -r latest_210="2.10.3"
|
||||
declare -r latest_211="2.11.0-M5"
|
||||
declare -r latest_210="2.10.5"
|
||||
declare -r latest_211="2.11.6"
|
||||
|
||||
declare -r script_path="$(get_script_path "$BASH_SOURCE")"
|
||||
declare -r script_name="${script_path##*/}"
|
||||
|
|
|
@ -43,6 +43,7 @@ public class OSInfo
|
|||
public static final String IA64_32 = "ia64_32";
|
||||
public static final String IA64 = "ia64";
|
||||
public static final String PPC = "ppc";
|
||||
public static final String PPC64 = "ppc64";
|
||||
|
||||
static {
|
||||
// x86 mappings
|
||||
|
@ -75,6 +76,11 @@ public class OSInfo
|
|||
archMapping.put("power_rs", PPC);
|
||||
|
||||
// TODO: PowerPC 64bit mappings
|
||||
archMapping.put(PPC64, PPC64);
|
||||
archMapping.put("power64", PPC64);
|
||||
archMapping.put("powerpc64", PPC64);
|
||||
archMapping.put("power_pc64", PPC64);
|
||||
archMapping.put("power_rs64", PPC64);
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,7 +146,11 @@ public class OSInfo
|
|||
else if (osName.contains("Linux")) {
|
||||
return "Linux";
|
||||
}
|
||||
else {
|
||||
else if (osName.contains("AIX")) {
|
||||
return "AIX";
|
||||
}
|
||||
|
||||
else {
|
||||
return osName.replaceAll("\\W", "");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,15 @@ import java.util.Arrays;
|
|||
public class SnappyCodec
|
||||
{
|
||||
public static final byte[] MAGIC_HEADER = new byte[] { -126, 'S', 'N', 'A', 'P', 'P', 'Y', 0 };
|
||||
public static final int MAGIC_LEN = 8;
|
||||
public static final int MAGIC_LEN = MAGIC_HEADER.length;
|
||||
public static final int HEADER_SIZE = MAGIC_LEN + 8;
|
||||
public static final int MAGIC_HEADER_HEAD = SnappyOutputStream.readInt(MAGIC_HEADER, 0);
|
||||
public static final int MAGIC_HEADER_TAIL = SnappyOutputStream.readInt(MAGIC_HEADER, 4);
|
||||
|
||||
static {
|
||||
assert(MAGIC_HEADER_HEAD < 0);
|
||||
}
|
||||
|
||||
|
||||
public static final int DEFAULT_VERSION = 1;
|
||||
public static final int MINIMUM_COMPATIBLE_VERSION = 1;
|
||||
|
@ -58,11 +66,25 @@ public class SnappyCodec
|
|||
public final byte[] magic;
|
||||
public final int version;
|
||||
public final int compatibleVersion;
|
||||
private final byte[] headerArray;
|
||||
|
||||
private SnappyCodec(byte[] magic, int version, int compatibleVersion) {
|
||||
this.magic = magic;
|
||||
this.version = version;
|
||||
this.compatibleVersion = compatibleVersion;
|
||||
|
||||
ByteArrayOutputStream header = new ByteArrayOutputStream(HEADER_SIZE);
|
||||
DataOutputStream d = new DataOutputStream(header);
|
||||
try {
|
||||
d.write(magic, 0, MAGIC_LEN);
|
||||
d.writeInt(version);
|
||||
d.writeInt(compatibleVersion);
|
||||
d.close();
|
||||
}
|
||||
catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
headerArray = header.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -71,17 +93,17 @@ public class SnappyCodec
|
|||
}
|
||||
|
||||
public static int headerSize() {
|
||||
return MAGIC_LEN + 4 * 2;
|
||||
return HEADER_SIZE;
|
||||
}
|
||||
|
||||
public void writeHeader(OutputStream out) throws IOException {
|
||||
ByteArrayOutputStream header = new ByteArrayOutputStream();
|
||||
DataOutputStream d = new DataOutputStream(header);
|
||||
d.write(magic, 0, MAGIC_LEN);
|
||||
d.writeInt(version);
|
||||
d.writeInt(compatibleVersion);
|
||||
d.close();
|
||||
out.write(header.toByteArray(), 0, header.size());
|
||||
public int writeHeader(byte[] dst, int dstOffset) {
|
||||
System.arraycopy(headerArray, 0, dst, dstOffset, headerArray.length);
|
||||
return headerArray.length;
|
||||
}
|
||||
|
||||
public int writeHeader(OutputStream out) throws IOException {
|
||||
out.write(headerArray, 0, headerArray.length);
|
||||
return headerArray.length;
|
||||
}
|
||||
|
||||
public boolean isValidMagicHeader() {
|
||||
|
@ -97,8 +119,6 @@ public class SnappyCodec
|
|||
return new SnappyCodec(magic, version, compatibleVersion);
|
||||
}
|
||||
|
||||
public static SnappyCodec currentHeader() {
|
||||
return new SnappyCodec(MAGIC_HEADER, DEFAULT_VERSION, MINIMUM_COMPATIBLE_VERSION);
|
||||
}
|
||||
public static SnappyCodec currentHeader = new SnappyCodec(MAGIC_HEADER, DEFAULT_VERSION, MINIMUM_COMPATIBLE_VERSION);
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,11 @@ public enum SnappyErrorCode {
|
|||
PARSING_ERROR(2),
|
||||
NOT_A_DIRECT_BUFFER(3),
|
||||
OUT_OF_MEMORY(4),
|
||||
FAILED_TO_UNCOMPRESS(5);
|
||||
FAILED_TO_UNCOMPRESS(5),
|
||||
EMPTY_INPUT(6),
|
||||
INCOMPATIBLE_VERSION(7),
|
||||
INVALID_CHUNK_SIZE(8)
|
||||
;
|
||||
|
||||
public final int id;
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package org.xerial.snappy;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Enhanced IOException with SnappyErrorCode
|
||||
*/
|
||||
public class SnappyIOException extends IOException {
|
||||
private final SnappyErrorCode errorCode;
|
||||
|
||||
public SnappyIOException(SnappyErrorCode errorCode, String message) {
|
||||
super(message);
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return String.format("[%s] %s", errorCode.name(), super.getMessage());
|
||||
}
|
||||
|
||||
public SnappyErrorCode getErrorCode() { return errorCode; }
|
||||
|
||||
}
|
|
@ -45,7 +45,7 @@ public class SnappyInputStream extends InputStream
|
|||
private int uncompressedCursor = 0;
|
||||
private int uncompressedLimit = 0;
|
||||
|
||||
private byte[] chunkSizeBuf = new byte[4];
|
||||
private byte[] header = new byte[SnappyCodec.headerSize()];
|
||||
|
||||
/**
|
||||
* Create a filter for reading compressed data as a uncompressed stream
|
||||
|
@ -73,7 +73,6 @@ public class SnappyInputStream extends InputStream
|
|||
}
|
||||
|
||||
protected void readHeader() throws IOException {
|
||||
byte[] header = new byte[SnappyCodec.headerSize()];
|
||||
int readBytes = 0;
|
||||
while (readBytes < header.length) {
|
||||
int ret = in.read(header, readBytes, header.length - readBytes);
|
||||
|
@ -82,31 +81,45 @@ public class SnappyInputStream extends InputStream
|
|||
readBytes += ret;
|
||||
}
|
||||
|
||||
// Quick test of the header
|
||||
// Quick test of the header
|
||||
if(readBytes == 0) {
|
||||
// Snappy produces at least 1-byte result. So the empty input is not a valid input
|
||||
throw new SnappyIOException(SnappyErrorCode.EMPTY_INPUT, "Cannot decompress empty stream");
|
||||
}
|
||||
if (readBytes < header.length || header[0] != SnappyCodec.MAGIC_HEADER[0]) {
|
||||
// do the default uncompression
|
||||
readFully(header, readBytes);
|
||||
return;
|
||||
}
|
||||
|
||||
SnappyCodec codec = SnappyCodec.readHeader(new ByteArrayInputStream(header));
|
||||
if (codec.isValidMagicHeader()) {
|
||||
// The input data is compressed by SnappyOutputStream
|
||||
if (codec.version < SnappyCodec.MINIMUM_COMPATIBLE_VERSION) {
|
||||
throw new IOException(String.format(
|
||||
"compressed with imcompatible codec version %d. At least version %d is required",
|
||||
codec.version, SnappyCodec.MINIMUM_COMPATIBLE_VERSION));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(!isValidHeader(header)) {
|
||||
// (probably) compressed by Snappy.compress(byte[])
|
||||
readFully(header, readBytes);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidHeader(byte[] header) throws IOException {
|
||||
SnappyCodec codec = SnappyCodec.readHeader(new ByteArrayInputStream(header));
|
||||
if (codec.isValidMagicHeader()) {
|
||||
// The input data is compressed by SnappyOutputStream
|
||||
if(codec.version < SnappyCodec.MINIMUM_COMPATIBLE_VERSION) {
|
||||
throw new SnappyIOException(SnappyErrorCode.INCOMPATIBLE_VERSION, String.format(
|
||||
"Compressed with an incompatible codec version %d. At least version %d is required",
|
||||
codec.version, SnappyCodec.MINIMUM_COMPATIBLE_VERSION));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void readFully(byte[] fragment, int fragmentLength) throws IOException {
|
||||
// read the entire input data to the buffer
|
||||
if(fragmentLength == 0) {
|
||||
finishedReading = true;
|
||||
return;
|
||||
}
|
||||
// read the entire input data to the buffer
|
||||
compressed = new byte[Math.max(8 * 1024, fragmentLength)]; // 8K
|
||||
System.arraycopy(fragment, 0, compressed, 0, fragmentLength);
|
||||
int cursor = fragmentLength;
|
||||
|
@ -316,6 +329,26 @@ public class SnappyInputStream extends InputStream
|
|||
return read(d, 0, d.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read next len bytes
|
||||
* @param dest
|
||||
* @param offset
|
||||
* @param len
|
||||
* @return read bytes
|
||||
*/
|
||||
private int readNext(byte[] dest, int offset, int len) throws IOException {
|
||||
int readBytes = 0;
|
||||
while (readBytes < len) {
|
||||
int ret = in.read(dest, readBytes + offset, len - readBytes);
|
||||
if (ret == -1) {
|
||||
finishedReading = true;
|
||||
return readBytes;
|
||||
}
|
||||
readBytes += ret;
|
||||
}
|
||||
return readBytes;
|
||||
}
|
||||
|
||||
protected boolean hasNextChunk() throws IOException {
|
||||
if (finishedReading)
|
||||
return false;
|
||||
|
@ -323,16 +356,24 @@ public class SnappyInputStream extends InputStream
|
|||
uncompressedCursor = 0;
|
||||
uncompressedLimit = 0;
|
||||
|
||||
int readBytes = 0;
|
||||
while (readBytes < 4) {
|
||||
int ret = in.read(chunkSizeBuf, readBytes, 4 - readBytes);
|
||||
if (ret == -1) {
|
||||
finishedReading = true;
|
||||
int readBytes = readNext(header, 0, 4);
|
||||
if(readBytes < 4)
|
||||
return false;
|
||||
|
||||
int chunkSize = SnappyOutputStream.readInt(header, 0);
|
||||
if(chunkSize == SnappyCodec.MAGIC_HEADER_HEAD) {
|
||||
// Concatenated data
|
||||
int remainingHeaderSize = SnappyCodec.headerSize() - 4;
|
||||
readBytes = readNext(header, 4, remainingHeaderSize);
|
||||
if(readBytes < remainingHeaderSize)
|
||||
return false;
|
||||
|
||||
if(isValidHeader(header))
|
||||
return hasNextChunk();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
readBytes += ret;
|
||||
}
|
||||
int chunkSize = SnappyOutputStream.readInt(chunkSizeBuf, 0);
|
||||
|
||||
// extend the compressed data buffer size
|
||||
if (compressed == null || chunkSize > compressed.length) {
|
||||
compressed = new byte[chunkSize];
|
||||
|
@ -347,20 +388,15 @@ public class SnappyInputStream extends InputStream
|
|||
if (readBytes < chunkSize) {
|
||||
throw new IOException("failed to read chunk");
|
||||
}
|
||||
try {
|
||||
int uncompressedLength = Snappy.uncompressedLength(compressed, 0, chunkSize);
|
||||
if (uncompressed == null || uncompressedLength > uncompressed.length) {
|
||||
uncompressed = new byte[uncompressedLength];
|
||||
}
|
||||
int actualUncompressedLength = Snappy.uncompress(compressed, 0, chunkSize, uncompressed, 0);
|
||||
if (uncompressedLength != actualUncompressedLength) {
|
||||
throw new IOException("invalid uncompressed byte size");
|
||||
}
|
||||
uncompressedLimit = actualUncompressedLength;
|
||||
int uncompressedLength = Snappy.uncompressedLength(compressed, 0, chunkSize);
|
||||
if (uncompressed == null || uncompressedLength > uncompressed.length) {
|
||||
uncompressed = new byte[uncompressedLength];
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IOException("failed to uncompress the chunk: " + e.getMessage());
|
||||
int actualUncompressedLength = Snappy.uncompress(compressed, 0, chunkSize, uncompressed, 0);
|
||||
if (uncompressedLength != actualUncompressedLength) {
|
||||
throw new SnappyIOException(SnappyErrorCode.INVALID_CHUNK_SIZE, String.format("expected %,d bytes, but decompressed chunk has %,d bytes", uncompressedLength, actualUncompressedLength));
|
||||
}
|
||||
uncompressedLimit = actualUncompressedLength;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -300,11 +300,13 @@ public class SnappyLoader
|
|||
}
|
||||
|
||||
// Temporary folder for the native lib. Use the value of org.xerial.snappy.tempdir or java.io.tmpdir
|
||||
String tempFolder = new File(System.getProperty(KEY_SNAPPY_TEMPDIR,
|
||||
System.getProperty("java.io.tmpdir"))).getAbsolutePath();
|
||||
File tempFolder = new File(System.getProperty(KEY_SNAPPY_TEMPDIR, System.getProperty("java.io.tmpdir")));
|
||||
if (!tempFolder.exists()) {
|
||||
tempFolder.mkdir();
|
||||
}
|
||||
|
||||
// Extract and load a native library inside the jar file
|
||||
return extractLibraryFile(snappyNativeLibraryPath, snappyNativeLibraryName, tempFolder);
|
||||
return extractLibraryFile(snappyNativeLibraryPath, snappyNativeLibraryName, tempFolder.getAbsolutePath());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,315 +1,332 @@
|
|||
/*--------------------------------------------------------------------------
|
||||
* Copyright 2011 Taro L. Saito
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*--------------------------------------------------------------------------*/
|
||||
//--------------------------------------
|
||||
// XerialJ
|
||||
//
|
||||
// SnappyOutputStream.java
|
||||
// Since: 2011/03/31 17:44:10
|
||||
//
|
||||
// $URL$
|
||||
// $Author$
|
||||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* This class implements a stream filter for writing compressed data using
|
||||
* Snappy.
|
||||
*
|
||||
* The input data is blocked into 32kb size (in default), and each block is
|
||||
* compressed and then passed to the given {@link OutputStream}.
|
||||
*
|
||||
* The output data format is:
|
||||
* <ol>
|
||||
* <li>snappy codec header defined in {@link SnappyCodec} (8 bytes)
|
||||
* <li>compressed block 1 : a pair of (compressed data size [4 byte integer.
|
||||
* Big-endian], compressed data...)
|
||||
* <li>compressed block 2
|
||||
* <li>...
|
||||
* </ol>
|
||||
*
|
||||
* Note that the compressed data created by {@link SnappyOutputStream} cannot be
|
||||
* uncompressed by {@link Snappy#uncompress(byte[])} since the output formats of
|
||||
* {@link Snappy#compress(byte[])} and {@link SnappyOutputStream} are different.
|
||||
* Use {@link SnappyInputStream} for uncompress the data generated by
|
||||
* {@link SnappyOutputStream}.
|
||||
*
|
||||
* @author leo
|
||||
*
|
||||
*/
|
||||
public class SnappyOutputStream extends OutputStream
|
||||
{
|
||||
static final int DEFAULT_BLOCK_SIZE = 32 * 1024; // Use 32kb for the default block size
|
||||
|
||||
protected final OutputStream out;
|
||||
private final int blockSize;
|
||||
private int cursor = 0;
|
||||
protected byte[] uncompressed;
|
||||
protected byte[] compressed;
|
||||
|
||||
public SnappyOutputStream(OutputStream out) throws IOException {
|
||||
this(out, DEFAULT_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param out
|
||||
* @param blockSize
|
||||
* byte size of the internal buffer size
|
||||
* @throws IOException
|
||||
*/
|
||||
public SnappyOutputStream(OutputStream out, int blockSize) throws IOException {
|
||||
this.out = out;
|
||||
this.blockSize = blockSize;
|
||||
uncompressed = new byte[blockSize];
|
||||
compressed = new byte[Snappy.maxCompressedLength(blockSize)];
|
||||
writeHeader();
|
||||
}
|
||||
|
||||
protected void writeHeader() throws IOException {
|
||||
SnappyCodec.currentHeader().writeHeader(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes len bytes from the specified byte array starting at offset off to
|
||||
* this output stream. The general contract for write(b, off, len) is that
|
||||
* some of the bytes in the array b are written to the output stream in
|
||||
* order; element b[off] is the first byte written and b[off+len-1] is the
|
||||
* last byte written by this operation.
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
rawWrite(b, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input long array data
|
||||
*
|
||||
* @param d
|
||||
* input array
|
||||
* @param off
|
||||
* offset in the array
|
||||
* @param len
|
||||
* the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(long[] d, int off, int len) throws IOException {
|
||||
rawWrite(d, off * 8, len * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input double array data
|
||||
*
|
||||
* @param f
|
||||
* input array
|
||||
* @param off
|
||||
* offset in the array
|
||||
* @param len
|
||||
* the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(double[] f, int off, int len) throws IOException {
|
||||
rawWrite(f, off * 8, len * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input float array data
|
||||
*
|
||||
* @param f
|
||||
* input array
|
||||
* @param off
|
||||
* offset in the array
|
||||
* @param len
|
||||
* the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(float[] f, int off, int len) throws IOException {
|
||||
rawWrite(f, off * 4, len * 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input int array data
|
||||
*
|
||||
* @param f
|
||||
* input array
|
||||
* @param off
|
||||
* offset in the array
|
||||
* @param len
|
||||
* the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(int[] f, int off, int len) throws IOException {
|
||||
rawWrite(f, off * 4, len * 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input short array data
|
||||
*
|
||||
* @param f
|
||||
* input array
|
||||
* @param off
|
||||
* offset in the array
|
||||
* @param len
|
||||
* the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(short[] f, int off, int len) throws IOException {
|
||||
rawWrite(f, off * 2, len * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param d
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(long[] d) throws IOException {
|
||||
write(d, 0, d.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param f
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(double[] f) throws IOException {
|
||||
write(f, 0, f.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param f
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(float[] f) throws IOException {
|
||||
write(f, 0, f.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param f
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(int[] f) throws IOException {
|
||||
write(f, 0, f.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param f
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(short[] f) throws IOException {
|
||||
write(f, 0, f.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the raw byte array data.
|
||||
*
|
||||
* @param array
|
||||
* array data of any type (e.g., byte[], float[], long[], ...)
|
||||
* @param byteOffset
|
||||
* @param byteLength
|
||||
* @throws IOException
|
||||
*/
|
||||
public void rawWrite(Object array, int byteOffset, int byteLength) throws IOException {
|
||||
for (int readBytes = 0; readBytes < byteLength;) {
|
||||
int copyLen = Math.min(uncompressed.length - cursor, byteLength - readBytes);
|
||||
Snappy.arrayCopy(array, byteOffset + readBytes, copyLen, uncompressed, cursor);
|
||||
readBytes += copyLen;
|
||||
cursor += copyLen;
|
||||
|
||||
if (cursor >= uncompressed.length) {
|
||||
dump();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte to this output stream. The general contract for
|
||||
* write is that one byte is written to the output stream. The byte to be
|
||||
* written is the eight low-order bits of the argument b. The 24 high-order
|
||||
* bits of b are ignored.
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
if (cursor >= uncompressed.length) {
|
||||
dump();
|
||||
}
|
||||
uncompressed[cursor++] = (byte) b;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
dump();
|
||||
out.flush();
|
||||
}
|
||||
|
||||
static void writeInt(OutputStream out, int value) throws IOException {
|
||||
out.write((value >> 24) & 0xFF);
|
||||
out.write((value >> 16) & 0xFF);
|
||||
out.write((value >> 8) & 0xFF);
|
||||
out.write((value >> 0) & 0xFF);
|
||||
}
|
||||
|
||||
static int readInt(byte[] buffer, int pos) {
|
||||
int b1 = (buffer[pos] & 0xFF) << 24;
|
||||
int b2 = (buffer[pos + 1] & 0xFF) << 16;
|
||||
int b3 = (buffer[pos + 2] & 0xFF) << 8;
|
||||
int b4 = buffer[pos + 3] & 0xFF;
|
||||
return b1 | b2 | b3 | b4;
|
||||
}
|
||||
|
||||
protected void dump() throws IOException {
|
||||
if (cursor <= 0)
|
||||
return; // no need to dump
|
||||
|
||||
// Compress and dump the buffer content
|
||||
int compressedSize = Snappy.compress(uncompressed, 0, cursor, compressed, 0);
|
||||
writeInt(out, compressedSize);
|
||||
out.write(compressed, 0, compressedSize);
|
||||
cursor = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* close the stream
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
flush();
|
||||
|
||||
super.close();
|
||||
out.close();
|
||||
}
|
||||
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
* Copyright 2011 Taro L. Saito
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*--------------------------------------------------------------------------*/
|
||||
//--------------------------------------
|
||||
// XerialJ
|
||||
//
|
||||
// SnappyOutputStream.java
|
||||
// Since: 2011/03/31 17:44:10
|
||||
//
|
||||
// $URL$
|
||||
// $Author$
|
||||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import org.xerial.snappy.buffer.BufferAllocatorFactory;
|
||||
import org.xerial.snappy.buffer.BufferAllocator;
|
||||
import org.xerial.snappy.buffer.CachedBufferAllocator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* This class implements a stream filter for writing compressed data using
|
||||
* Snappy.
|
||||
* <p>
|
||||
* The input data is blocked into 32kb size (in default), and each block is
|
||||
* compressed and then passed to the given {@link OutputStream}.
|
||||
* </p>
|
||||
* The output data format is:
|
||||
* <ol>
|
||||
* <li>snappy codec header defined in {@link SnappyCodec} (8 bytes)
|
||||
* <li>compressed block 1 : a pair of (compressed data size [4 byte integer.
|
||||
* Big-endian], compressed data...)
|
||||
* <li>compressed block 2
|
||||
* <li>...
|
||||
* </ol>
|
||||
* <p/>
|
||||
* Note that the compressed data created by {@link SnappyOutputStream} cannot be
|
||||
* uncompressed by {@link Snappy#uncompress(byte[])} since the output formats of
|
||||
* {@link Snappy#compress(byte[])} and {@link SnappyOutputStream} are different.
|
||||
* Use {@link SnappyInputStream} for uncompress the data generated by
|
||||
* {@link SnappyOutputStream}.
|
||||
*
|
||||
* @author leo
|
||||
*/
|
||||
public class SnappyOutputStream extends OutputStream {
|
||||
static final int MIN_BLOCK_SIZE = 1 * 1024;
|
||||
static final int DEFAULT_BLOCK_SIZE = 32 * 1024; // Use 32kb for the default block size
|
||||
|
||||
protected final OutputStream out;
|
||||
private final int blockSize;
|
||||
|
||||
private final BufferAllocator inputBufferAllocator;
|
||||
private final BufferAllocator outputBufferAllocator;
|
||||
|
||||
protected final byte[] inputBuffer;
|
||||
protected final byte[] outputBuffer;
|
||||
private int inputCursor = 0;
|
||||
private int outputCursor = 0;
|
||||
|
||||
public SnappyOutputStream(OutputStream out) {
|
||||
this(out, DEFAULT_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param out
|
||||
* @param blockSize byte size of the internal buffer size
|
||||
* @throws IOException
|
||||
*/
|
||||
public SnappyOutputStream(OutputStream out, int blockSize) {
|
||||
this(out, blockSize, CachedBufferAllocator.factory);
|
||||
}
|
||||
|
||||
public SnappyOutputStream(OutputStream out, int blockSize, BufferAllocatorFactory bufferAllocatorFactory) {
|
||||
this.out = out;
|
||||
this.blockSize = Math.max(MIN_BLOCK_SIZE, blockSize);
|
||||
int inputSize = blockSize;
|
||||
int outputSize = SnappyCodec.HEADER_SIZE + 4 + Snappy.maxCompressedLength(blockSize);
|
||||
|
||||
this.inputBufferAllocator = bufferAllocatorFactory.getBufferAllocator(inputSize);
|
||||
this.outputBufferAllocator = bufferAllocatorFactory.getBufferAllocator(outputSize);
|
||||
|
||||
inputBuffer = inputBufferAllocator.allocate(inputSize);
|
||||
outputBuffer = outputBufferAllocator.allocate(outputSize);
|
||||
|
||||
outputCursor = SnappyCodec.currentHeader.writeHeader(outputBuffer, 0);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(byte[], int, int)
|
||||
*/
|
||||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
rawWrite(b, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input long array data
|
||||
*
|
||||
* @param d input array
|
||||
* @param off offset in the array
|
||||
* @param len the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(long[] d, int off, int len) throws IOException {
|
||||
rawWrite(d, off * 8, len * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input double array data
|
||||
*
|
||||
* @param f input array
|
||||
* @param off offset in the array
|
||||
* @param len the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(double[] f, int off, int len) throws IOException {
|
||||
rawWrite(f, off * 8, len * 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input float array data
|
||||
*
|
||||
* @param f input array
|
||||
* @param off offset in the array
|
||||
* @param len the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(float[] f, int off, int len) throws IOException {
|
||||
rawWrite(f, off * 4, len * 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input int array data
|
||||
*
|
||||
* @param f input array
|
||||
* @param off offset in the array
|
||||
* @param len the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(int[] f, int off, int len) throws IOException {
|
||||
rawWrite(f, off * 4, len * 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input short array data
|
||||
*
|
||||
* @param f input array
|
||||
* @param off offset in the array
|
||||
* @param len the number of elements in the array to copy
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(short[] f, int off, int len) throws IOException {
|
||||
rawWrite(f, off * 2, len * 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param d
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(long[] d) throws IOException {
|
||||
write(d, 0, d.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param f
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(double[] f) throws IOException {
|
||||
write(f, 0, f.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param f
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(float[] f) throws IOException {
|
||||
write(f, 0, f.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param f
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(int[] f) throws IOException {
|
||||
write(f, 0, f.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array data
|
||||
*
|
||||
* @param f
|
||||
* @throws IOException
|
||||
*/
|
||||
public void write(short[] f) throws IOException {
|
||||
write(f, 0, f.length);
|
||||
}
|
||||
|
||||
private boolean hasSufficientOutputBufferFor(int inputSize) {
|
||||
int maxCompressedSize = Snappy.maxCompressedLength(inputSize);
|
||||
return maxCompressedSize < outputBuffer.length - outputCursor - 4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the raw byte array data.
|
||||
*
|
||||
* @param array array data of any type (e.g., byte[], float[], long[], ...)
|
||||
* @param byteOffset
|
||||
* @param byteLength
|
||||
* @throws IOException
|
||||
*/
|
||||
public void rawWrite(Object array, int byteOffset, int byteLength) throws IOException {
|
||||
int cursor = 0;
|
||||
while(cursor < byteLength) {
|
||||
int readLen = Math.min(byteLength - cursor, blockSize - inputCursor);
|
||||
// copy the input data to uncompressed buffer
|
||||
if(readLen > 0) {
|
||||
Snappy.arrayCopy(array, byteOffset + cursor, readLen, inputBuffer, inputCursor);
|
||||
inputCursor += readLen;
|
||||
}
|
||||
if(inputCursor < blockSize)
|
||||
return;
|
||||
|
||||
compressInput();
|
||||
cursor += readLen;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte to this output stream. The general contract for
|
||||
* write is that one byte is written to the output stream. The byte to be
|
||||
* written is the eight low-order bits of the argument b. The 24 high-order
|
||||
* bits of b are ignored.
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#write(int)
|
||||
*/
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
if(inputCursor >= inputBuffer.length) {
|
||||
compressInput();
|
||||
}
|
||||
inputBuffer[inputCursor++] = (byte) b;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#flush()
|
||||
*/
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
compressInput();
|
||||
dumpOutput();
|
||||
out.flush();
|
||||
}
|
||||
|
||||
static void writeInt(byte[] dst, int offset, int v) {
|
||||
dst[offset] = (byte) ((v >> 24) & 0xFF);
|
||||
dst[offset + 1] = (byte) ((v >> 16) & 0xFF);
|
||||
dst[offset + 2] = (byte) ((v >> 8) & 0xFF);
|
||||
dst[offset + 3] = (byte) ((v >> 0) & 0xFF);
|
||||
}
|
||||
|
||||
static int readInt(byte[] buffer, int pos) {
|
||||
int b1 = (buffer[pos] & 0xFF) << 24;
|
||||
int b2 = (buffer[pos + 1] & 0xFF) << 16;
|
||||
int b3 = (buffer[pos + 2] & 0xFF) << 8;
|
||||
int b4 = buffer[pos + 3] & 0xFF;
|
||||
return b1 | b2 | b3 | b4;
|
||||
}
|
||||
|
||||
protected void dumpOutput() throws IOException {
|
||||
if(outputCursor > 0) {
|
||||
out.write(outputBuffer, 0, outputCursor);
|
||||
outputCursor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected void compressInput() throws IOException {
|
||||
if(inputCursor <= 0) {
|
||||
return; // no need to dump
|
||||
}
|
||||
|
||||
// Compress and dump the buffer content
|
||||
if(!hasSufficientOutputBufferFor(inputCursor)) {
|
||||
dumpOutput();
|
||||
}
|
||||
int compressedSize = Snappy.compress(inputBuffer, 0, inputCursor, outputBuffer, outputCursor + 4);
|
||||
// Write compressed data size
|
||||
writeInt(outputBuffer, outputCursor, compressedSize);
|
||||
outputCursor += 4 + compressedSize;
|
||||
inputCursor = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* close the stream
|
||||
*/
|
||||
/* (non-Javadoc)
|
||||
* @see java.io.OutputStream#close()
|
||||
*/
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
flush();
|
||||
out.close();
|
||||
} finally {
|
||||
inputBufferAllocator.release(inputBuffer);
|
||||
outputBufferAllocator.release(outputBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
VERSION=1.1.1
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package org.xerial.snappy.buffer;
|
||||
|
||||
/**
|
||||
* BufferAllocator interface. The implementation of this interface must be thread-safe
|
||||
*/
|
||||
public interface BufferAllocator {
|
||||
|
||||
public byte[] allocate(int size);
|
||||
public void release(byte[] buffer);
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.xerial.snappy.buffer;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface BufferAllocatorFactory {
|
||||
|
||||
BufferAllocator getBufferAllocator(int minSize);
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package org.xerial.snappy.buffer;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Cached buffer
|
||||
*/
|
||||
public class CachedBufferAllocator implements BufferAllocator {
|
||||
|
||||
public static BufferAllocatorFactory factory = new BufferAllocatorFactory() {
|
||||
@Override
|
||||
public BufferAllocator getBufferAllocator(int bufferSize) {
|
||||
return CachedBufferAllocator.getAllocator(bufferSize);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Use SoftReference so that having this queueTable does not prevent the GC of CachedBufferAllocator instances
|
||||
*/
|
||||
public static Map<Integer, SoftReference<CachedBufferAllocator>> queueTable = new HashMap<Integer, SoftReference<CachedBufferAllocator>>();
|
||||
|
||||
private final int bufferSize;
|
||||
private final Deque<byte[]> bufferQueue;
|
||||
|
||||
public CachedBufferAllocator(int bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
this.bufferQueue = new ArrayDeque<byte[]>();
|
||||
}
|
||||
|
||||
public static synchronized CachedBufferAllocator getAllocator(int bufferSize) {
|
||||
CachedBufferAllocator result = null;
|
||||
|
||||
if (queueTable.containsKey(bufferSize)) {
|
||||
result = queueTable.get(bufferSize).get();
|
||||
}
|
||||
if (result == null) {
|
||||
result = new CachedBufferAllocator(bufferSize);
|
||||
queueTable.put(bufferSize, new SoftReference<CachedBufferAllocator>(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] allocate(int size) {
|
||||
synchronized(this) {
|
||||
if(bufferQueue.isEmpty()) {
|
||||
return new byte[size];
|
||||
}
|
||||
else {
|
||||
return bufferQueue.pollFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void release(byte[] buffer) {
|
||||
synchronized(this) {
|
||||
bufferQueue.addLast(buffer);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package org.xerial.snappy.buffer;
|
||||
|
||||
/**
|
||||
* Simple buffer allocator, which does not reuse the allocated buffer
|
||||
*/
|
||||
public class DefaultBufferAllocator implements BufferAllocator {
|
||||
|
||||
public static BufferAllocatorFactory factory = new BufferAllocatorFactory() {
|
||||
public BufferAllocator singleton = new DefaultBufferAllocator();
|
||||
@Override
|
||||
public BufferAllocator getBufferAllocator(int bufferSize) {
|
||||
return singleton;
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public byte[] allocate(int size) {
|
||||
return new byte[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(byte[] buffer) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
VERSION=1.1.2
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -35,6 +35,7 @@ import java.io.InputStream;
|
|||
import org.junit.Test;
|
||||
import org.xerial.util.FileResource;
|
||||
import org.xerial.util.log.Logger;
|
||||
import scala.Array;
|
||||
|
||||
public class SnappyInputStreamTest
|
||||
{
|
||||
|
@ -62,7 +63,7 @@ public class SnappyInputStreamTest
|
|||
}
|
||||
}
|
||||
|
||||
public static byte[] biteWiseReadFully(InputStream input) throws IOException {
|
||||
public static byte[] byteWiseReadFully(InputStream input) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[4096];
|
||||
for (int readData = 0; (readData = input.read()) != -1;) {
|
||||
|
@ -108,7 +109,7 @@ public class SnappyInputStreamTest
|
|||
byte[] compressed = Snappy.compress(orig);
|
||||
|
||||
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(compressed));
|
||||
byte[] uncompressed = biteWiseReadFully(in);
|
||||
byte[] uncompressed = byteWiseReadFully(in);
|
||||
|
||||
assertEquals(orig.length, uncompressed.length);
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
|
@ -129,4 +130,50 @@ public class SnappyInputStreamTest
|
|||
in.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyStream() throws Exception {
|
||||
try {
|
||||
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(new byte[0]));
|
||||
byte[] uncompressed = readFully(in);
|
||||
assertEquals(0, uncompressed.length);
|
||||
fail("should not reach here");
|
||||
}
|
||||
catch(SnappyIOException e) {
|
||||
assertEquals(SnappyErrorCode.EMPTY_INPUT, e.getErrorCode());
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] compressResource(String resourcePath) throws Exception {
|
||||
ByteArrayOutputStream compressedBuf = new ByteArrayOutputStream();
|
||||
SnappyOutputStream snappyOut = new SnappyOutputStream(compressedBuf);
|
||||
byte[] orig = readResourceFile(resourcePath);
|
||||
snappyOut.write(orig);
|
||||
snappyOut.close();
|
||||
return compressedBuf.toByteArray();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chunkRead() throws Exception {
|
||||
byte[] chunk1 = compressResource("alice29.txt");
|
||||
byte[] chunk2 = compressResource("testdata/calgary/paper6");
|
||||
|
||||
byte[] concatenated = new byte[chunk1.length + chunk2.length];
|
||||
System.arraycopy(chunk1, 0, concatenated, 0, chunk1.length);
|
||||
System.arraycopy(chunk2, 0, concatenated, chunk1.length, chunk2.length);
|
||||
|
||||
SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(concatenated));
|
||||
byte[] uncompressed = readFully(in);
|
||||
|
||||
byte[] orig1 = readResourceFile("alice29.txt");
|
||||
byte[] orig2 = readResourceFile("testdata/calgary/paper6");
|
||||
assertEquals(orig1.length + orig2.length, uncompressed.length);
|
||||
byte[] uncompressed1 = new byte[orig1.length];
|
||||
byte[] uncompressed2 = new byte[orig2.length];
|
||||
System.arraycopy(uncompressed, 0, uncompressed1, 0, orig1.length);
|
||||
System.arraycopy(uncompressed, orig1.length, uncompressed2, 0, orig2.length);
|
||||
|
||||
assertArrayEquals(orig1, uncompressed1);
|
||||
assertArrayEquals(orig2, uncompressed2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,188 +1,250 @@
|
|||
/*--------------------------------------------------------------------------
|
||||
* Copyright 2011 Taro L. Saito
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*--------------------------------------------------------------------------*/
|
||||
//--------------------------------------
|
||||
// XerialJ
|
||||
//
|
||||
// SnappyOutputStreamTest.java
|
||||
// Since: 2011/03/31 18:26:31
|
||||
//
|
||||
// $URL$
|
||||
// $Author$
|
||||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.xerial.util.FileResource;
|
||||
import org.xerial.util.log.Logger;
|
||||
|
||||
public class SnappyOutputStreamTest
|
||||
{
|
||||
private static Logger _logger = Logger.getLogger(SnappyOutputStreamTest.class);
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
SnappyOutputStream sout = new SnappyOutputStream(buf);
|
||||
|
||||
BufferedInputStream input = new BufferedInputStream(FileResource.find(SnappyOutputStreamTest.class,
|
||||
"alice29.txt").openStream());
|
||||
assertNotNull(input);
|
||||
|
||||
ByteArrayOutputStream orig = new ByteArrayOutputStream();
|
||||
byte[] tmp = new byte[1024];
|
||||
for (int readBytes = 0; (readBytes = input.read(tmp)) != -1;) {
|
||||
sout.write(tmp, 0, readBytes);
|
||||
orig.write(tmp, 0, readBytes); // preserve the original data
|
||||
}
|
||||
input.close();
|
||||
sout.flush();
|
||||
orig.flush();
|
||||
|
||||
int compressedSize = buf.size();
|
||||
_logger.debug("compressed size: " + compressedSize);
|
||||
|
||||
ByteArrayOutputStream decompressed = new ByteArrayOutputStream();
|
||||
byte[] compressed = buf.toByteArray();
|
||||
// decompress
|
||||
for (int cursor = SnappyCodec.headerSize(); cursor < compressed.length;) {
|
||||
int chunkSize = SnappyOutputStream.readInt(compressed, cursor);
|
||||
cursor += 4;
|
||||
byte[] tmpOut = new byte[Snappy.uncompressedLength(compressed, cursor, chunkSize)];
|
||||
int decompressedSize = Snappy.uncompress(compressed, cursor, chunkSize, tmpOut, 0);
|
||||
cursor += chunkSize;
|
||||
|
||||
decompressed.write(tmpOut);
|
||||
}
|
||||
decompressed.flush();
|
||||
assertEquals(orig.size(), decompressed.size());
|
||||
assertArrayEquals(orig.toByteArray(), decompressed.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bufferSize() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b, 500);
|
||||
final int bytesToWrite = 5000;
|
||||
byte[] orig = new byte[bytesToWrite];
|
||||
for (int i = 0; i < 5000; ++i) {
|
||||
byte v = (byte) (i % 128);
|
||||
orig[i] = v;
|
||||
os.write(v);
|
||||
}
|
||||
os.close();
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
byte[] buf = new byte[bytesToWrite / 101];
|
||||
while (is.read(buf) != -1) {}
|
||||
is.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longArrayCompress() throws Exception {
|
||||
long[] l = new long[10];
|
||||
for (int i = 0; i < l.length; ++i) {
|
||||
l[i] = i % 3 + i * 11;
|
||||
}
|
||||
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
os.write(l);
|
||||
os.close();
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
long[] l2 = new long[10];
|
||||
int readBytes = is.read(l2);
|
||||
is.close();
|
||||
|
||||
assertEquals(10 * 8, readBytes);
|
||||
assertArrayEquals(l, l2);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeDoubleArray() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
double[] orig = new double[] { 1.0, 2.0, 1.4, 0.00343430014, -4.4, 4e-20 };
|
||||
os.write(orig);
|
||||
os.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
double[] uncompressed = new double[orig.length];
|
||||
is.read(uncompressed);
|
||||
is.close();
|
||||
|
||||
assertArrayEquals(orig, uncompressed, 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeFloatArray() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
float[] orig = new float[] { 1.0f, 2.0f, 1.4f, 0.00343430014f, -4.4f, 4e-20f };
|
||||
os.write(orig);
|
||||
os.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
float[] uncompressed = new float[orig.length];
|
||||
is.read(uncompressed);
|
||||
is.close();
|
||||
|
||||
assertArrayEquals(orig, uncompressed, 0.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeIntArray() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
int[] orig = new int[] { 0, -1, -34, 43, 234, 34324, -234 };
|
||||
os.write(orig);
|
||||
os.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
int[] uncompressed = new int[orig.length];
|
||||
is.read(uncompressed);
|
||||
is.close();
|
||||
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeShortArray() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
short[] orig = new short[] { 0, -1, -34, 43, 234, 324, -234 };
|
||||
os.write(orig);
|
||||
os.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
short[] uncompressed = new short[orig.length];
|
||||
is.read(uncompressed);
|
||||
is.close();
|
||||
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
}
|
||||
|
||||
}
|
||||
/*--------------------------------------------------------------------------
|
||||
* Copyright 2011 Taro L. Saito
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*--------------------------------------------------------------------------*/
|
||||
//--------------------------------------
|
||||
// XerialJ
|
||||
//
|
||||
// SnappyOutputStreamTest.java
|
||||
// Since: 2011/03/31 18:26:31
|
||||
//
|
||||
// $URL$
|
||||
// $Author$
|
||||
//--------------------------------------
|
||||
package org.xerial.snappy;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.xerial.util.FileResource;
|
||||
import org.xerial.util.log.Logger;
|
||||
|
||||
public class SnappyOutputStreamTest
|
||||
{
|
||||
private static Logger _logger = Logger.getLogger(SnappyOutputStreamTest.class);
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||
SnappyOutputStream sout = new SnappyOutputStream(buf);
|
||||
|
||||
BufferedInputStream input = new BufferedInputStream(FileResource.find(SnappyOutputStreamTest.class,
|
||||
"alice29.txt").openStream());
|
||||
assertNotNull(input);
|
||||
|
||||
ByteArrayOutputStream orig = new ByteArrayOutputStream();
|
||||
byte[] tmp = new byte[1024];
|
||||
for (int readBytes = 0; (readBytes = input.read(tmp)) != -1;) {
|
||||
sout.write(tmp, 0, readBytes);
|
||||
orig.write(tmp, 0, readBytes); // preserve the original data
|
||||
}
|
||||
input.close();
|
||||
sout.flush();
|
||||
orig.flush();
|
||||
|
||||
int compressedSize = buf.size();
|
||||
_logger.debug("compressed size: " + compressedSize);
|
||||
|
||||
ByteArrayOutputStream decompressed = new ByteArrayOutputStream();
|
||||
byte[] compressed = buf.toByteArray();
|
||||
// decompress
|
||||
for (int cursor = SnappyCodec.headerSize(); cursor < compressed.length;) {
|
||||
int chunkSize = SnappyOutputStream.readInt(compressed, cursor);
|
||||
cursor += 4;
|
||||
byte[] tmpOut = new byte[Snappy.uncompressedLength(compressed, cursor, chunkSize)];
|
||||
int decompressedSize = Snappy.uncompress(compressed, cursor, chunkSize, tmpOut, 0);
|
||||
cursor += chunkSize;
|
||||
|
||||
decompressed.write(tmpOut);
|
||||
}
|
||||
decompressed.flush();
|
||||
assertEquals(orig.size(), decompressed.size());
|
||||
assertArrayEquals(orig.toByteArray(), decompressed.toByteArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bufferSize() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b, 1500);
|
||||
final int bytesToWrite = 5000;
|
||||
byte[] orig = new byte[bytesToWrite];
|
||||
for (int i = 0; i < 5000; ++i) {
|
||||
byte v = (byte) (i % 128);
|
||||
orig[i] = v;
|
||||
os.write(v);
|
||||
}
|
||||
os.close();
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
byte[] buf = new byte[bytesToWrite / 101];
|
||||
while (is.read(buf) != -1) {}
|
||||
is.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void smallWrites() throws Exception {
|
||||
|
||||
byte[] orig = CalgaryTest.readFile("alice29.txt");
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream out = new SnappyOutputStream(b);
|
||||
|
||||
for(byte c : orig) {
|
||||
out.write(c);
|
||||
}
|
||||
out.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
byte[] decompressed = new byte[orig.length];
|
||||
int cursor = 0;
|
||||
int readLen = 0;
|
||||
for(int i=0; i < decompressed.length && (readLen = is.read(decompressed, i, decompressed.length-i)) != -1; ) {
|
||||
i += readLen;
|
||||
}
|
||||
is.close();
|
||||
assertArrayEquals(orig, decompressed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the input array by passing it chunk-by-chunk to a SnappyOutputStream.
|
||||
* @param orig the data to compress
|
||||
* @param maxChunkSize the maximum chunk size, in bytes.
|
||||
* @return the compressed bytes
|
||||
*/
|
||||
private static byte[] compressAsChunks(byte[] orig, int maxChunkSize) throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream out = new SnappyOutputStream(b);
|
||||
|
||||
int remaining = orig.length;
|
||||
for (int start = 0; start < orig.length; start += maxChunkSize) {
|
||||
out.write(orig, start, remaining < maxChunkSize ? remaining : maxChunkSize);
|
||||
remaining -= maxChunkSize;
|
||||
}
|
||||
out.close();
|
||||
return b.toByteArray();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void batchingOfWritesShouldNotAffectCompressedDataSize() throws Exception {
|
||||
// Regression test for issue #100, a bug where the size of compressed data could be affected
|
||||
// by the batching of writes to the SnappyOutputStream rather than the total amount of data
|
||||
// written to the stream.
|
||||
byte[] orig = CalgaryTest.readFile("alice29.txt");
|
||||
// Compress the data once so that we know the expected size:
|
||||
byte[] expectedCompressedData = compressAsChunks(orig, Integer.MAX_VALUE);
|
||||
// Hardcoding an expected compressed size here will catch regressions that lower the
|
||||
// compression quality:
|
||||
assertEquals(91013, expectedCompressedData.length);
|
||||
// The chunk size should not affect the size of the compressed output:
|
||||
int[] chunkSizes = new int[] { 1, 100, 1023, 1024, 10000};
|
||||
for (int chunkSize : chunkSizes) {
|
||||
byte[] compressedData = compressAsChunks(orig, chunkSize);
|
||||
assertEquals(String.format("when chunk size = %,d", chunkSize), expectedCompressedData.length, compressedData.length);
|
||||
assertArrayEquals(expectedCompressedData, compressedData);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longArrayCompress() throws Exception {
|
||||
long[] l = new long[10];
|
||||
for (int i = 0; i < l.length; ++i) {
|
||||
l[i] = i % 3 + i * 11;
|
||||
}
|
||||
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
os.write(l);
|
||||
os.close();
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
long[] l2 = new long[10];
|
||||
int readBytes = is.read(l2);
|
||||
is.close();
|
||||
|
||||
assertEquals(10 * 8, readBytes);
|
||||
assertArrayEquals(l, l2);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeDoubleArray() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
double[] orig = new double[] { 1.0, 2.0, 1.4, 0.00343430014, -4.4, 4e-20 };
|
||||
os.write(orig);
|
||||
os.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
double[] uncompressed = new double[orig.length];
|
||||
is.read(uncompressed);
|
||||
is.close();
|
||||
|
||||
assertArrayEquals(orig, uncompressed, 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeFloatArray() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
float[] orig = new float[] { 1.0f, 2.0f, 1.4f, 0.00343430014f, -4.4f, 4e-20f };
|
||||
os.write(orig);
|
||||
os.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
float[] uncompressed = new float[orig.length];
|
||||
is.read(uncompressed);
|
||||
is.close();
|
||||
|
||||
assertArrayEquals(orig, uncompressed, 0.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeIntArray() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
int[] orig = new int[] { 0, -1, -34, 43, 234, 34324, -234 };
|
||||
os.write(orig);
|
||||
os.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
int[] uncompressed = new int[orig.length];
|
||||
is.read(uncompressed);
|
||||
is.close();
|
||||
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeShortArray() throws Exception {
|
||||
ByteArrayOutputStream b = new ByteArrayOutputStream();
|
||||
SnappyOutputStream os = new SnappyOutputStream(b);
|
||||
|
||||
short[] orig = new short[] { 0, -1, -34, 43, 234, 324, -234 };
|
||||
os.write(orig);
|
||||
os.close();
|
||||
|
||||
SnappyInputStream is = new SnappyInputStream(new ByteArrayInputStream(b.toByteArray()));
|
||||
short[] uncompressed = new short[orig.length];
|
||||
is.read(uncompressed);
|
||||
is.close();
|
||||
|
||||
assertArrayEquals(orig, uncompressed);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package org.xerial.snappy
|
||||
|
||||
import java.io.{ByteArrayOutputStream, ByteArrayInputStream}
|
||||
|
||||
import xerial.core.log.LogLevel
|
||||
|
||||
import scala.util.Random
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class SnappyPerformanceTest extends SnappySpec {
|
||||
|
||||
lazy val data = {
|
||||
val a = new Array[Byte](128 * 1024 * 1024)
|
||||
|
||||
for (i <- (0 until a.length).par) {
|
||||
a(i) = Math.sin(i * 0.01).toByte
|
||||
}
|
||||
a
|
||||
}
|
||||
|
||||
|
||||
"SnappyOutputStream" should {
|
||||
|
||||
"improve output performance" taggedAs("out") in {
|
||||
|
||||
val input = data
|
||||
|
||||
time("compression", repeat=100, logLevel = LogLevel.INFO) {
|
||||
// 0.037 sec. => 0.026
|
||||
block("default") {
|
||||
val out = new ByteArrayOutputStream()
|
||||
val sout = new SnappyOutputStream(out)
|
||||
sout.write(input)
|
||||
sout.close()
|
||||
out.close()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//info(f"compressed size: ${compressed.length}%,d, input: ${data.length}%,d")
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.xerial.snappy
|
||||
|
||||
import org.scalatest._
|
||||
import xerial.core.log.Logger
|
||||
import xerial.core.util.Timer
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
trait SnappySpec
|
||||
extends WordSpec
|
||||
with Matchers
|
||||
with GivenWhenThen
|
||||
with OptionValues
|
||||
with BeforeAndAfter
|
||||
with Timer
|
||||
with Logger
|
||||
{
|
||||
|
||||
implicit def toTag(s:String) : Tag = Tag(s)
|
||||
|
||||
}
|
|
@ -1 +1 @@
|
|||
version in ThisBuild := "1.1.1"
|
||||
version in ThisBuild := "1.1.2-SNAPSHOT"
|
Loading…
Reference in New Issue