diff --git a/.gitignore b/.gitignore
index 7eefa4456..dfe7ac089 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
*.iml
.idea/
-.gradle/
\ No newline at end of file
+.gradle/
diff --git a/build.third_step0.gradle b/build.third_step0.gradle
index 8fc464d7f..9b7bcd2cb 100644
--- a/build.third_step0.gradle
+++ b/build.third_step0.gradle
@@ -10,9 +10,9 @@ configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
//源码版本
-sourceCompatibility=1.6
+sourceCompatibility=1.7
//构建的class版本
-targetCompatibility=1.6
+targetCompatibility=1.7
//解压lib下的jar到classes文件夹
@@ -43,8 +43,10 @@ def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf (java.io.File.s
def branchName=buildDir.substring(buildDir.lastIndexOf (java.io.File.separator)+1)
def srcDir="."
+def MVN_BRANCH = branchVariable.toUpperCase()
+
// @branch - 分支信息
-def maven_version="${version}-FEATURE-SNAPSHOT"
+def maven_version="${version}-${MVN_BRANCH}-SNAPSHOT"
def jar_version = version
configurations {
@@ -53,8 +55,7 @@ configurations {
}
dependencies {
- // @branch - 分支信息
- thirdjar "com.fr.third:fine-third:10.0-FEATURE-SNAPSHOT"
+ thirdjar "com.fr.third:fine-third-base:10.0-BASE-SNAPSHOT"
sigar "com.fr.third:sigar:1.6.0"
testCompile 'junit:junit:4.12'
}
diff --git a/build.third_step1.gradle b/build.third_step1.gradle
index e545d8a7c..d035fd18d 100644
--- a/build.third_step1.gradle
+++ b/build.third_step1.gradle
@@ -6,9 +6,9 @@ tasks.withType(JavaCompile){
}
//源码版本
-sourceCompatibility=1.6
+sourceCompatibility=1.7
//构建的class版本
-targetCompatibility=1.6
+targetCompatibility=1.7
def jarname="fine-third-10.0.jar"
def classesDir='build/classes/1'
@@ -32,6 +32,8 @@ sourceSets{
main{
java{
srcDirs=[
+ "${srcDir}/fine-third-jdk11/src",
+ "${srcDir}/fine-objenesis/src",
"${srcDir}/fine-jetbrains/src",
"${srcDir}/fine-poi/src",
"${srcDir}/fine-quartz/src",
@@ -58,6 +60,7 @@ repositories{
FileTree files =fileTree(dir:'./',include:'build.*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf (java.io.File.separator))
def branchName=buildDir.substring(buildDir.lastIndexOf (java.io.File.separator)+1)
+def MVN_BRANCH = branchVariable.toUpperCase()
//指定依赖
dependencies{
@@ -65,7 +68,7 @@ dependencies{
compile fileTree(dir:"${srcDir}/fine-quartz/lib",include:'**/*.jar')
compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar')
// @branch - 分支信息
- compile "com.fr.third:fine-third:10.0-FEATURE-SNAPSHOT"
+ compile "com.fr.third:fine-third:10.0-${MVN_BRANCH}-SNAPSHOT"
compile fileTree(dir:"../../finereport-lib-other/${branchName}",include:'**/*.jar')
testCompile 'junit:junit:4.12'
}
@@ -85,6 +88,8 @@ def dataContent ={def dir ->
task copyFiles(type:Copy,dependsOn:'compileJava'){
copy{
println "------------------------------------------------copyfiles"
+ with dataContent.call("${srcDir}/fine-third-jdk11/src")
+ with dataContent.call("${srcDir}/fine-objenesis/src")
with dataContent.call("${srcDir}/fine-jetbrains/src")
with dataContent.call("${srcDir}/fine-poi/src")
with dataContent.call("${srcDir}/fine-quartz/src")
diff --git a/build.third_step2.gradle b/build.third_step2.gradle
index 576e44231..d65d684a4 100644
--- a/build.third_step2.gradle
+++ b/build.third_step2.gradle
@@ -46,6 +46,7 @@ repositories{
FileTree files =fileTree(dir:'./',include:'build.*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf (java.io.File.separator))
def branchName=buildDir.substring(buildDir.lastIndexOf (java.io.File.separator)+1)
+def MVN_BRANCH = branchVariable.toUpperCase()
//指定依赖
dependencies{
@@ -55,7 +56,7 @@ dependencies{
compile fileTree(dir:"${srcDir}/fine-antlr4/lib",include: '**/*.jar')
compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar')
// @branch - 分支信息
- compile "com.fr.third:fine-third:10.0-FEATURE-SNAPSHOT"
+ compile "com.fr.third:fine-third:10.0-${MVN_BRANCH}-SNAPSHOT"
compile fileTree(dir:"../../finereport-lib-other/${branchName}",include:'**/*.jar')
testCompile 'junit:junit:4.12'
}
diff --git a/build.third_step3.gradle b/build.third_step3.gradle
index 4e80a9326..702132f17 100644
--- a/build.third_step3.gradle
+++ b/build.third_step3.gradle
@@ -6,9 +6,9 @@ tasks.withType(JavaCompile){
}
//源码版本
-sourceCompatibility=1.6
+sourceCompatibility=1.7
//构建的class版本
-targetCompatibility=1.6
+targetCompatibility=1.7
def jarname="fine-third-10.0.jar"
def classesDir='build/classes/3'
@@ -45,13 +45,14 @@ repositories{
FileTree files =fileTree(dir:'./',include:'build.*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf (java.io.File.separator))
def branchName=buildDir.substring(buildDir.lastIndexOf (java.io.File.separator)+1)
+def MVN_BRANCH = branchVariable.toUpperCase()
//指定依赖
dependencies{
compile fileTree(dir:"${srcDir}/fine-jboss-logging/lib",include:'**/*.jar')
compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar')
// @branch - 分支信息
- compile "com.fr.third:fine-third:10.0-FEATURE-SNAPSHOT"
+ compile "com.fr.third:fine-third:10.0-${MVN_BRANCH}-SNAPSHOT"
compile fileTree(dir:"../../finereport-lib-other/${branchName}",include:'**/*.jar')
testCompile 'junit:junit:4.12'
}
diff --git a/build.third_step4.gradle b/build.third_step4.gradle
index 46de47c24..650c69b0a 100644
--- a/build.third_step4.gradle
+++ b/build.third_step4.gradle
@@ -6,9 +6,9 @@ tasks.withType(JavaCompile){
}
//源码版本
-sourceCompatibility=1.6
+sourceCompatibility=1.7
//构建的class版本
-targetCompatibility=1.6
+targetCompatibility=1.7
def jarname="fine-third-10.0.jar"
def classesDir='build/classes/4'
@@ -44,13 +44,14 @@ repositories{
FileTree files =fileTree(dir:'./',include:'build.*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf (java.io.File.separator))
def branchName=buildDir.substring(buildDir.lastIndexOf (java.io.File.separator)+1)
+def MVN_BRANCH = branchVariable.toUpperCase()
//指定依赖
dependencies{
compile fileTree(dir:"${srcDir}/fine-hibernate/lib",include:'**/*.jar')
compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar')
// @branch - 分支信息
- compile "com.fr.third:fine-third:10.0-FEATURE-SNAPSHOT"
+ compile "com.fr.third:fine-third:10.0-${MVN_BRANCH}-SNAPSHOT"
compile fileTree(dir:"../../finereport-lib-other/${branchName}",include:'**/*.jar')
testCompile 'junit:junit:4.12'
}
diff --git a/build.third_step5.gradle b/build.third_step5.gradle
index d45e1b48e..dd8d80fdd 100644
--- a/build.third_step5.gradle
+++ b/build.third_step5.gradle
@@ -6,9 +6,9 @@ tasks.withType(JavaCompile){
}
//源码版本
-sourceCompatibility=1.6
+sourceCompatibility=1.7
//构建的class版本
-targetCompatibility=1.6
+targetCompatibility=1.7
def jarname="fine-third-10.0.jar"
def classesDir='build/classes/5'
@@ -42,6 +42,7 @@ repositories{
FileTree files =fileTree(dir:'./',include:'build.*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf (java.io.File.separator))
def branchName=buildDir.substring(buildDir.lastIndexOf (java.io.File.separator)+1)
+def MVN_BRANCH = branchVariable.toUpperCase()
//指定依赖
dependencies{
@@ -49,7 +50,7 @@ dependencies{
compile fileTree(dir:"${srcDir}/fine-druid/lib",include:'**/*.jar')
compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar')
// @branch - 分支信息
- compile "com.fr.third:fine-third:10.0-FEATURE-SNAPSHOT"
+ compile "com.fr.third:fine-third:10.0-${MVN_BRANCH}-SNAPSHOT"
compile fileTree(dir:"../../finereport-lib-other/${branchName}",include:'**/*.jar')
testCompile 'junit:junit:4.12'
}
diff --git a/build.third_step6.gradle b/build.third_step6.gradle
index de18cbab9..8ef6d50ae 100644
--- a/build.third_step6.gradle
+++ b/build.third_step6.gradle
@@ -6,9 +6,9 @@ tasks.withType(JavaCompile){
}
//源码版本
-sourceCompatibility=1.6
+sourceCompatibility=1.7
//构建的class版本
-targetCompatibility=1.6
+targetCompatibility=1.7
def jarname="fine-third-10.0.jar"
def classesDir='build/classes/6'
@@ -68,6 +68,7 @@ repositories{
FileTree files =fileTree(dir:'./',include:'build*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf (java.io.File.separator))
def branchName=buildDir.substring(buildDir.lastIndexOf (java.io.File.separator)+1)
+def MVN_BRANCH = branchVariable.toUpperCase()
//指定依赖
dependencies{
@@ -83,7 +84,7 @@ dependencies{
compile fileTree(dir:"${srcDir}/fine-jgit/lib",include:'**/*.jar')
compile fileTree(dir:"${srcDir}/build/libs/",include:'**/*.jar')
// @branch - 分支信息
- compile "com.fr.third:fine-third:10.0-FEATURE-SNAPSHOT"
+ compile "com.fr.third:fine-third:10.0-${MVN_BRANCH}-SNAPSHOT"
compile fileTree(dir:"../../finereport-lib-other/${branchName}",include:'**/*.jar')
testCompile 'junit:junit:4.12'
}
diff --git a/fine-aspectj/src/com/fr/third/aspectj/apache/bcel/generic/TABLESWITCH.java b/fine-aspectj/src/com/fr/third/aspectj/apache/bcel/generic/TABLESWITCH.java
index bf1936f64..b726d1851 100644
--- a/fine-aspectj/src/com/fr/third/aspectj/apache/bcel/generic/TABLESWITCH.java
+++ b/fine-aspectj/src/com/fr/third/aspectj/apache/bcel/generic/TABLESWITCH.java
@@ -53,20 +53,16 @@
*/
package com.fr.third.aspectj.apache.bcel.generic;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-import com.fr.third.aspectj.apache.bcel.Constants;
import com.fr.third.aspectj.apache.bcel.util.ByteSequence;
-import com.sun.org.apache.bcel.internal.generic.SWITCH;
+import java.io.DataOutputStream;
+import java.io.IOException;
/**
* TABLESWITCH - Switch within given range of values, i.e., low..high
*
* @version $Id: TABLESWITCH.java,v 1.5 2008/08/28 00:05:29 aclement Exp $
* @author M. Dahm
- * @see SWITCH
*/
public class TABLESWITCH extends InstructionSelect {
diff --git a/fine-cglib/src/com/fr/third/net/sf/cglib/reflect/MethodDelegate.java b/fine-cglib/src/com/fr/third/net/sf/cglib/reflect/MethodDelegate.java
index 51279a17d..6f0dc85d0 100644
--- a/fine-cglib/src/com/fr/third/net/sf/cglib/reflect/MethodDelegate.java
+++ b/fine-cglib/src/com/fr/third/net/sf/cglib/reflect/MethodDelegate.java
@@ -15,9 +15,6 @@
*/
package com.fr.third.net.sf.cglib.reflect;
-import java.lang.reflect.*;
-import java.security.ProtectionDomain;
-
import com.fr.third.net.sf.cglib.core.AbstractClassGenerator;
import com.fr.third.net.sf.cglib.core.ClassEmitter;
import com.fr.third.net.sf.cglib.core.CodeEmitter;
@@ -28,11 +25,12 @@ import com.fr.third.net.sf.cglib.core.MethodInfo;
import com.fr.third.net.sf.cglib.core.ReflectUtils;
import com.fr.third.net.sf.cglib.core.Signature;
import com.fr.third.net.sf.cglib.core.TypeUtils;
-import com.fr.third.net.sf.cglib.*;
-import com.fr.third.net.sf.cglib.core.*;
import com.fr.third.org.objectweb.asm.ClassVisitor;
import com.fr.third.org.objectweb.asm.Type;
+import java.lang.reflect.Method;
+import java.security.ProtectionDomain;
+
// TODO: don't require exact match for return type
/**
diff --git a/fine-ehcache/src/com/fr/third/net/sf/ehcache/statistics/extended/ExtendedStatisticsImpl.java b/fine-ehcache/src/com/fr/third/net/sf/ehcache/statistics/extended/ExtendedStatisticsImpl.java
index f02c4a84f..e168d0cd4 100644
--- a/fine-ehcache/src/com/fr/third/net/sf/ehcache/statistics/extended/ExtendedStatisticsImpl.java
+++ b/fine-ehcache/src/com/fr/third/net/sf/ehcache/statistics/extended/ExtendedStatisticsImpl.java
@@ -66,7 +66,7 @@ import static org.terracotta.context.query.QueryBuilder.queryBuilder;
/**
* The Class ExtendedStatisticsImpl.
- *
+ *
* @author cschanck
*/
public class ExtendedStatisticsImpl implements ExtendedStatistics {
@@ -75,15 +75,15 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
private static final Logger LOGGER = LoggerFactory.getLogger(ExtendedStatisticsImpl.class);
/** The standard pass throughs. */
- private final ConcurrentMap> standardPassThroughs =
+ private final ConcurrentMap> standardPassThroughs =
new ConcurrentHashMap>();
/** The standard operations. */
- private final ConcurrentMap> standardOperations =
+ private final ConcurrentMap> standardOperations =
new ConcurrentHashMap>();
/** The custom operations. */
- private final ConcurrentMap, CompoundOperationImpl>> customOperations =
+ private final ConcurrentMap, CompoundOperationImpl>> customOperations =
new ConcurrentHashMap, CompoundOperationImpl>>();
/** custom pass thru stats*/
@@ -155,7 +155,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/**
* Instantiates a new extended statistics impl.
- *
+ *
* @param manager the manager
* @param executor the executor
* @param timeToDisable the time to disable
@@ -265,7 +265,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#setTimeToDisable(long, java.util.concurrent.TimeUnit)
*/
@Override
@@ -280,7 +280,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#setAlwaysOn(boolean)
*/
@Override
@@ -305,7 +305,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#get()
*/
@Override
@@ -315,7 +315,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#put()
*/
@Override
@@ -375,7 +375,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#search()
*/
@Override
@@ -385,7 +385,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#heapGet()
*/
@Override
@@ -395,7 +395,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#heapPut()
*/
@Override
@@ -405,7 +405,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#heapRemove()
*/
@Override
@@ -415,7 +415,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#offheapGet()
*/
@Override
@@ -425,7 +425,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#offheapPut()
*/
@Override
@@ -435,7 +435,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#offheapRemove()
*/
@Override
@@ -445,7 +445,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#diskGet()
*/
@Override
@@ -455,7 +455,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#diskPut()
*/
@Override
@@ -465,7 +465,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#diskRemove()
*/
@Override
@@ -475,7 +475,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#xaCommit()
*/
@Override
@@ -485,7 +485,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#xaRollback()
*/
@Override
@@ -495,7 +495,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#xaRecovery()
*/
@Override
@@ -505,7 +505,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#eviction()
*/
@Override
@@ -515,7 +515,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#expiry()
*/
@Override
@@ -525,7 +525,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getCacheHitRatio()
*/
@Override
@@ -535,7 +535,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#allGet()
*/
@Override
@@ -545,7 +545,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#allMiss()
*/
@Override
@@ -555,7 +555,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#allPut()
*/
@Override
@@ -565,7 +565,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#heapAllPut()
*/
@Override
@@ -575,7 +575,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#offHeapAllPut()
*/
@Override
@@ -585,7 +585,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#diskAllPut()
*/
@Override
@@ -595,7 +595,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#operations(java.lang.Class, java.lang.String, java.lang.String[])
*/
@Override
@@ -623,7 +623,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getLocalHeapSize()
*/
@Override
@@ -633,7 +633,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getLocalHeapSizeInBytes()
*/
@Override
@@ -643,7 +643,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getLocalOffHeapSize()
*/
@Override
@@ -653,7 +653,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getLocalOffHeapSizeInBytes()
*/
@Override
@@ -663,7 +663,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getLocalDiskSize()
*/
@Override
@@ -673,7 +673,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getLocalDiskSizeInBytes()
*/
@Override
@@ -683,7 +683,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getRemoteSize()
*/
@Override
@@ -693,7 +693,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getSize()
*/
@Override
@@ -703,7 +703,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#getWriterQueueLength()
*/
@Override
@@ -713,7 +713,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/**
* Gets the standard operation.
- *
+ *
* @param statistic the statistic
* @return the standard operation
*/
@@ -740,7 +740,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/**
* Gets the standard pass through.
- *
+ *
* @param statistic the statistic
* @return the standard pass through
*/
@@ -766,13 +766,13 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/**
* Find operation statistic.
- *
+ *
* @param manager the manager
* @param statistic the statistic
* @return the operation statistic
*/
private static OperationStatistic findOperationStatistic(StatisticsManager manager, StandardOperationStatistic statistic) {
- Set> results = findOperationStatistic(manager,
+ Set> results = (Set>)findOperationStatistic(manager,
statistic.context(),
statistic.type(),
statistic.operationName(),
@@ -789,7 +789,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/**
* Find pass through statistic.
- *
+ *
* @param manager the manager
* @param statistic the statistic
* @return the value statistic
@@ -808,7 +808,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/**
* Find operation statistic.
- *
+ *
* @param the generic type
* @param manager the manager
* @param contextQuery the context query
@@ -843,7 +843,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/**
* Find pass through statistic.
- *
+ *
* @param manager the manager
* @param contextQuery the context query
* @param name the name
@@ -876,7 +876,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#clusterEvent()
*/
@Override
@@ -886,7 +886,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#clusterEvent()
*/
@Override
@@ -896,7 +896,7 @@ public class ExtendedStatisticsImpl implements ExtendedStatistics {
/*
* (non-Javadoc)
- *
+ *
* @see ExtendedStatistics#lastRejoinTimeStampInNanos()
*/
@Override
diff --git a/fine-icu4j/src/com/fr/third/ibm/icu/text/RuleBasedBreakIterator.java b/fine-icu4j/src/com/fr/third/ibm/icu/text/RuleBasedBreakIterator.java
index b202510ca..ce06a7f7f 100644
--- a/fine-icu4j/src/com/fr/third/ibm/icu/text/RuleBasedBreakIterator.java
+++ b/fine-icu4j/src/com/fr/third/ibm/icu/text/RuleBasedBreakIterator.java
@@ -17,6 +17,7 @@ import java.nio.ByteBuffer;
import java.text.CharacterIterator;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.fr.third.ibm.icu.impl.CharacterIteration;
import com.fr.third.ibm.icu.impl.ICUBinary;
@@ -43,8 +44,11 @@ public class RuleBasedBreakIterator extends BreakIterator {
*/
private RuleBasedBreakIterator() {
fDictionaryCharCount = 0;
- synchronized(gAllBreakEngines) {
+ try {
+ rLock.lock();
fBreakEngines = new ArrayList(gAllBreakEngines);
+ } finally {
+ rLock.unlock();
}
}
@@ -131,8 +135,11 @@ public class RuleBasedBreakIterator extends BreakIterator {
if (fText != null) {
result.fText = (CharacterIterator)(fText.clone());
}
- synchronized (gAllBreakEngines) {
+ try {
+ rLock.lock();
result.fBreakEngines = new ArrayList(gAllBreakEngines);
+ } finally {
+ rLock.unlock();
}
result.fLookAheadMatches = new LookAheadResults();
result.fBreakCache = result.new BreakCache(fBreakCache);
@@ -294,10 +301,19 @@ public class RuleBasedBreakIterator extends BreakIterator {
*/
private static final List gAllBreakEngines;
+ private static final ReentrantReadWriteLock rwLock;
+
+ private static final ReentrantReadWriteLock.ReadLock rLock;
+
+ private static final ReentrantReadWriteLock.WriteLock wLock;
+
static {
gUnhandledBreakEngine = new UnhandledBreakEngine();
gAllBreakEngines = new ArrayList();
gAllBreakEngines.add(gUnhandledBreakEngine);
+ rwLock = new ReentrantReadWriteLock();
+ rLock = rwLock.readLock();
+ wLock = rwLock.writeLock();
}
/**
@@ -663,7 +679,8 @@ public class RuleBasedBreakIterator extends BreakIterator {
}
}
- synchronized (gAllBreakEngines) {
+ try {
+ wLock.lock();
// This break iterator's list of break engines didn't handle the character.
// Check the global list, another break iterator may have instantiated the
// desired engine.
@@ -717,7 +734,10 @@ public class RuleBasedBreakIterator extends BreakIterator {
fBreakEngines.add(eng);
}
return eng;
- } // end synchronized(gAllBreakEngines)
+ // end synchronized(gAllBreakEngines)
+ } finally {
+ wLock.unlock();
+ }
}
private static final int kMaxLookaheads = 8;
diff --git a/fine-itext-old/src/com/fr/third/com/lowagie/text/Row.java b/fine-itext-old/src/com/fr/third/com/lowagie/text/Row.java
index e6092dd96..a238628c1 100755
--- a/fine-itext-old/src/com/fr/third/com/lowagie/text/Row.java
+++ b/fine-itext-old/src/com/fr/third/com/lowagie/text/Row.java
@@ -93,7 +93,7 @@ public class Row implements Element {
/** This is the array of Objects (Cell or Table). */
protected Object[] cells;
- /** carl:ԼĴ룬ʲôṹ*/
+ /** carl:反正自己改代码,不管什么结构了*/
protected int height = 0;
/** This is the vertical alignment. */
diff --git a/fine-itext-old/src/com/fr/third/com/lowagie/text/html/simpleparser/HTMLWorker.java b/fine-itext-old/src/com/fr/third/com/lowagie/text/html/simpleparser/HTMLWorker.java
index 1399c6d20..f1ea48571 100644
--- a/fine-itext-old/src/com/fr/third/com/lowagie/text/html/simpleparser/HTMLWorker.java
+++ b/fine-itext-old/src/com/fr/third/com/lowagie/text/html/simpleparser/HTMLWorker.java
@@ -72,14 +72,10 @@ import com.fr.third.com.lowagie.text.pdf.PdfPTable;
import com.fr.third.com.lowagie.text.pdf.draw.LineSeparator;
import com.fr.third.com.lowagie.text.xml.simpleparser.SimpleXMLDocHandler;
import com.fr.third.com.lowagie.text.xml.simpleparser.SimpleXMLParser;
-import sun.misc.BASE64Decoder;
+import com.fr.third.sun.misc.BASE64Decoder;
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/fine-itext-old/src/com/fr/third/com/lowagie/text/rtf/table/RtfRow.java b/fine-itext-old/src/com/fr/third/com/lowagie/text/rtf/table/RtfRow.java
index 1fb95f795..2f36fff2f 100755
--- a/fine-itext-old/src/com/fr/third/com/lowagie/text/rtf/table/RtfRow.java
+++ b/fine-itext-old/src/com/fr/third/com/lowagie/text/rtf/table/RtfRow.java
@@ -232,7 +232,7 @@ public class RtfRow extends RtfElement {
this.cells = new ArrayList();
this.width = this.document.getDocumentHeader().getPageSetting().getPageWidth() - this.document.getDocumentHeader().getPageSetting().getMarginLeft() - this.document.getDocumentHeader().getPageSetting().getMarginRight();
this.width = (int) (this.width * this.parentTable.getTableWidthPercent() / 100);
- // carl: height
+ // carl: height
this.height = row.getHeight();
int cellRight = 0;
diff --git a/fine-itext-old/src/com/fr/third/com/lowagie/text/rtf/table/RtfTable.java b/fine-itext-old/src/com/fr/third/com/lowagie/text/rtf/table/RtfTable.java
index aaa3cb150..5a1b5e1cf 100755
--- a/fine-itext-old/src/com/fr/third/com/lowagie/text/rtf/table/RtfTable.java
+++ b/fine-itext-old/src/com/fr/third/com/lowagie/text/rtf/table/RtfTable.java
@@ -238,14 +238,14 @@ public class RtfTable extends RtfElement {
result.write(RtfFont.FONT_SIZE);
result.write(intToByteArray(this.offset));
}
- // carl:УиΪС 1
+ // carl:多出来的行,行高设为最小 1
result.write(RtfParagraph.PLAIN);
// result.write("\\s".getBytes());
// result.write(intToByteArray(0));
result.write(RtfPhrase.LINE_SPACING);
result.write(intToByteArray(0));
result.write(RtfParagraph.PLAIN);
- // ǹؼ1
+ // 这里是关键,把这破行设成1
result.write(RtfFont.FONT_SIZE);
result.write(intToByteArray(2));
result.write(RtfParagraph.PARAGRAPH);
@@ -258,14 +258,14 @@ public class RtfTable extends RtfElement {
}
result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
- // carl:УиΪС 1
+ // carl:多出来的行,行高设为最小 1
result.write(RtfParagraph.PLAIN);
// result.write("\\s".getBytes());
// result.write(intToByteArray(0));
result.write(RtfPhrase.LINE_SPACING);
result.write(intToByteArray(0));
result.write(RtfParagraph.PLAIN);
- // ǹؼ1
+ // 这里是关键,把这破行设成1
result.write(RtfFont.FONT_SIZE);
result.write(intToByteArray(2));
}
diff --git a/fine-itext/src/com/fr/third/v2/lowagie/text/html/Markup.java b/fine-itext/src/com/fr/third/v2/lowagie/text/html/Markup.java
index 763bbde5a..6a9cc97ff 100644
--- a/fine-itext/src/com/fr/third/v2/lowagie/text/html/Markup.java
+++ b/fine-itext/src/com/fr/third/v2/lowagie/text/html/Markup.java
@@ -209,6 +209,8 @@ public class Markup {
/** the CSS tag for the visibility of objects */
public static final String CSS_KEY_VISIBILITY = "visibility";
+ public static final String CSS_KEY_TEXTINDENT = "text-indent";
+
// CSS values
/**
@@ -341,7 +343,7 @@ public class Markup {
/**
* New method contributed by: Lubos Strapko
- *
+ *
* @since 2.1.3
*/
public static float parseLength(String string, float actualFontSize) {
diff --git a/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/FactoryProperties.java b/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/FactoryProperties.java
index 418bb954f..cf53266c4 100644
--- a/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/FactoryProperties.java
+++ b/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/FactoryProperties.java
@@ -374,14 +374,7 @@ public class FactoryProperties {
if (key.equals(Markup.CSS_KEY_FONTFAMILY)) {
h.put(ElementTags.FACE, prop.getProperty(key));
} else if (key.equals(Markup.CSS_KEY_FONTSIZE)) {
- float actualFontSize = Markup.parseLength(cprops
- .getProperty(ElementTags.SIZE),
- Markup.DEFAULT_FONT_SIZE);
- if (actualFontSize <= 0f)
- actualFontSize = Markup.DEFAULT_FONT_SIZE;
- h.put(ElementTags.SIZE, Float.toString(Markup.parseLength(prop
- .getProperty(key), actualFontSize))
- + "pt");
+ dealWithFontSizeOrTextIndent(h, cprops, prop, key);
} else if (key.equals(Markup.CSS_KEY_FONTSTYLE)) {
String ss = prop.getProperty(key).trim().toLowerCase();
if (ss.equals("italic") || ss.equals("oblique"))
@@ -429,14 +422,34 @@ public class FactoryProperties {
} else if (key.equals(Markup.CSS_KEY_BGCOLOR)) {
String ss = prop.getProperty(key).trim().toLowerCase();
h.put("background", ss);
- }
- else{
- String ss = prop.getProperty(key).trim();
- h.put(key, ss);
- }
+ } else if (key.equals(Markup.CSS_KEY_TEXTINDENT)) {
+ dealWithFontSizeOrTextIndent(h, cprops, prop, key);
+ } else {
+ String ss = prop.getProperty(key).trim();
+ h.put(key, ss);
+ }
}
}
+ /**
+ * 处理下字号和文本缩进
+ *
+ * @param h 当前标签内的属性Map
+ * @param cprops 一个list , 从左到右保存着父到子标签中的属性
+ * @param prop 当前标签内的style 属性Map
+ * @param key 当前 prop 中的 k
+ */
+ private static void dealWithFontSizeOrTextIndent(HashMap h, ChainedProperties cprops, Properties prop, String key) {
+ float actualFontSize = Markup.parseLength(cprops
+ .getProperty(ElementTags.SIZE),
+ Markup.DEFAULT_FONT_SIZE);
+ if (actualFontSize <= 0f)
+ actualFontSize = Markup.DEFAULT_FONT_SIZE;
+ h.put(key.equals(Markup.CSS_KEY_FONTSIZE) ? ElementTags.SIZE : key, Float.toString(Markup.parseLength(prop
+ .getProperty(key), actualFontSize))
+ + "pt");
+ }
+
public FontFactoryImp getFontImp() {
return fontImp;
}
diff --git a/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/HTMLWorker.java b/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/HTMLWorker.java
index ade85f5cf..5a4481ab7 100644
--- a/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/HTMLWorker.java
+++ b/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/HTMLWorker.java
@@ -58,8 +58,6 @@ import java.io.InputStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
import java.util.Stack;
import java.util.StringTokenizer;
@@ -85,7 +83,7 @@ import com.fr.third.v2.lowagie.text.Paragraph;
import com.fr.third.v2.lowagie.text.Phrase;
import com.fr.third.v2.lowagie.text.pdf.PdfPTable;
import com.fr.third.v2.lowagie.text.xml.simpleparser.SimpleXMLParser;
-import sun.misc.BASE64Decoder;
+import com.fr.third.sun.misc.BASE64Decoder;
import javax.imageio.ImageIO;
diff --git a/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/IncTable.java b/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/IncTable.java
index 2ea2a07f1..5da1eb4ca 100644
--- a/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/IncTable.java
+++ b/fine-itext/src/com/fr/third/v2/lowagie/text/html/simpleparser/IncTable.java
@@ -68,24 +68,25 @@ public class IncTable {
private ArrayList cols;
private ArrayList rowHeights = new ArrayList();
+ private ArrayList relativeColWidths = new ArrayList();
/** Creates a new instance of IncTable */
public IncTable(HashMap props) {
this.props.putAll(props);
}
-
+
public void addCol(PdfPCell cell) {
if (cols == null)
cols = new ArrayList();
cols.add(cell);
}
-
+
public void addCols(ArrayList ncols) {
if (cols == null)
cols = new ArrayList(ncols);
else
cols.addAll(ncols);
}
-
+
public void endRow(float rowHeight) {
rowHeights.add(rowHeight);
if (cols != null) {
@@ -94,34 +95,39 @@ public class IncTable {
cols = null;
}
}
-
+
public ArrayList getRows() {
return rows;
}
-
+
public PdfPTable buildTable() {
if (rows.isEmpty())
return new PdfPTable(1);
int ncol = 0;
- ArrayList c0 = (ArrayList)rows.get(0);
- ArrayList colWidths = new ArrayList();
+ ArrayList c0 = (ArrayList) rows.get(0);
+
for (int k = 0; k < c0.size(); ++k) {
- PdfPCell pCell = ((PdfPCell)c0.get(k));
- int cellCols = pCell.getColspan();
- ncol += cellCols;
- if(cellCols > 1){
- for(int a = 0; a < cellCols ; a++){
- colWidths.add(pCell.getStyleWidth()/cellCols);
- }
- }else {
- colWidths.add(pCell.getStyleWidth());
- }
+ ncol += ((PdfPCell) c0.get(k)).getColspan();
}
+ processColWidth(ncol);
+
PdfPTable table = new PdfPTable(ncol);
try {
TableProperties tableProperties = parseTableProperties();
table.setTableProperties(tableProperties);
+
+ //相对宽度
+ float[] floats = new float[relativeColWidths.size()];
+ for (int a = 0; a < relativeColWidths.size(); a++) {
+ floats[a] = relativeColWidths.get(a);
+ }
+ try {
+ table.setWidths(floats);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
String width = (String)props.get("width");
if (width == null)
table.setWidthPercentage(100);
@@ -130,18 +136,7 @@ public class IncTable {
table.setWidthPercentage(CSSUtils.parseFloat(width));
else {
//解析单元格宽度
- float totalWidth = CSSUtils.parseFloat(width);
- float[] floats = new float[colWidths.size()];
- for (int a = 0; a < colWidths.size(); a++){
- floats[a] = colWidths.get(a);
- }
- //解析px数值
- table.setTotalWidth(totalWidth);
- try {
- table.setWidths(floats);
- }catch (Exception e){
- e.printStackTrace();
- }
+ table.setTotalWidth(CSSUtils.parseFloat(width));
table.setLockedWidth(true);
}
}
@@ -153,19 +148,66 @@ public class IncTable {
}
processRowHeight(table);
-
-
}catch (Exception e){
e.printStackTrace();
}
return table;
}
- public void processRowHeight(PdfPTable table){
- Float height = CSSUtils.parseFloat((String)props.get("height"));
+ /**
+ * 调整列宽,每列取最大值
+ *
+ * @param colCount 列数
+ */
+ private void processColWidth(int colCount) {
+ if (null == rows || 0 == rows.size()) {
+ return;
+ }
+ //初始化一下
+ for (int i = 0; i < colCount; i++) {
+ relativeColWidths.add(0f);
+ }
+ for (int rowIndex = 0; rowIndex < rows.size(); rowIndex++) {
+ ArrayList cols = (ArrayList) rows.get(rowIndex);
+ for (int colIndex = 0; colIndex < cols.size(); colIndex++) {
+ PdfPCell pCell = ((PdfPCell) cols.get(colIndex));
+
+ int cellCols = pCell.getColspan();
+ float avgWidth = pCell.getStyleWidth() / cellCols;
+ for (int i = 0; i < cellCols && colIndex + i < colCount; i++) {
+ if (relativeColWidths.get(colIndex + i) < avgWidth) {
+ relativeColWidths.set(colIndex + i, avgWidth);
+ }
+ }
+ }
+ }
+ dealRelativeColWidthsWhenAllAreZero(relativeColWidths);
+ }
+
+ /**
+ * 全部为0,则全部赋值1
+ *
+ * @param relativeColWidths 相对宽度
+ */
+ private void dealRelativeColWidthsWhenAllAreZero(ArrayList relativeColWidths) {
+ if (0 == relativeColWidths.size()) {
+ return;
+ }
+ for (int i = 0; i < relativeColWidths.size(); i++) {
+ if (0 != relativeColWidths.get(i)) {
+ return;
+ }
+ }
+ for (int i = 0; i < relativeColWidths.size(); i++) {
+ relativeColWidths.set(i, 1f);
+ }
+ }
+
+ public void processRowHeight(PdfPTable table) {
+ Float height = CSSUtils.parseFloat((String) props.get("height"));
Float eachHeight = height / table.getRows().size();
//调整行高
- for(int a = 0; a < rowHeights.size(); a++){
+ for (int a = 0; a < rowHeights.size(); a++) {
table.getRow(a).setStyleHeight(Math.max(eachHeight, rowHeights.get(a)));
}
}
diff --git a/fine-itext/src/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java b/fine-itext/src/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java
index 09dce3311..f5b67439a 100644
--- a/fine-itext/src/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java
+++ b/fine-itext/src/com/fr/third/v2/lowagie/text/pdf/PdfChunk.java
@@ -788,10 +788,11 @@ public class PdfChunk {
public String toHtmlString() {
StringBuffer htmlString = new StringBuffer();
- if(this.isImage()){
- htmlString.append("");
+ if (this.isImage()) {
+ htmlString.append("");
return htmlString.toString();
-
}
//todo 需要添加其他样式属性
htmlString.append(" oldPacks,
- Collection newPacks) {
- oldPackLoop: for (PackFile oldPack : oldPacks) {
+ Collection newPacks) {
+ oldPackLoop:
+ for (PackFile oldPack : oldPacks) {
String oldName = oldPack.getPackName();
// check whether an old pack file is also among the list of new
// pack files. Then we must not delete it.
diff --git a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/InflatingBitSet.java b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/InflatingBitSet.java
index 096be5f33..ac1705f43 100755
--- a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/InflatingBitSet.java
+++ b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/InflatingBitSet.java
@@ -43,8 +43,8 @@
package com.fr.third.eclipse.jgit.internal.storage.file;
-import com.googlecode.javaewah.EWAHCompressedBitmap;
-import com.googlecode.javaewah.IntIterator;
+import com.fr.third.googlecode.javaewah.EWAHCompressedBitmap;
+import com.fr.third.googlecode.javaewah.IntIterator;
/**
* A wrapper around the EWAHCompressedBitmap optimized for the contains
diff --git a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndex.java b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndex.java
index 48c3c681f..ef5c5d15e 100755
--- a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndex.java
+++ b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndex.java
@@ -47,7 +47,7 @@ import com.fr.third.eclipse.jgit.errors.CorruptObjectException;
import com.fr.third.eclipse.jgit.internal.JGitText;
import com.fr.third.eclipse.jgit.lib.AnyObjectId;
import com.fr.third.eclipse.jgit.lib.ObjectId;
-import com.googlecode.javaewah.EWAHCompressedBitmap;
+import com.fr.third.googlecode.javaewah.EWAHCompressedBitmap;
import java.io.File;
import java.io.FileInputStream;
diff --git a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
index fec58ad7a..aa6c9f3c3 100755
--- a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
+++ b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexBuilder.java
@@ -50,7 +50,7 @@ import com.fr.third.eclipse.jgit.lib.Constants;
import com.fr.third.eclipse.jgit.lib.ObjectId;
import com.fr.third.eclipse.jgit.lib.ObjectIdOwnerMap;
import com.fr.third.eclipse.jgit.util.BlockList;
-import com.googlecode.javaewah.EWAHCompressedBitmap;
+import com.fr.third.googlecode.javaewah.EWAHCompressedBitmap;
import com.fr.third.eclipse.jgit.internal.storage.file.BitmapIndexImpl.CompressedBitmap;
import com.fr.third.eclipse.jgit.lib.BitmapIndex.Bitmap;
import com.fr.third.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
diff --git a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
index c896a5db5..20d5c79f6 100755
--- a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
+++ b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexRemapper.java
@@ -47,8 +47,8 @@ import com.fr.third.eclipse.jgit.lib.AnyObjectId;
import com.fr.third.eclipse.jgit.lib.BitmapIndex;
import com.fr.third.eclipse.jgit.lib.ObjectId;
import com.fr.third.eclipse.jgit.lib.ObjectIdOwnerMap;
-import com.googlecode.javaewah.EWAHCompressedBitmap;
-import com.googlecode.javaewah.IntIterator;
+import com.fr.third.googlecode.javaewah.EWAHCompressedBitmap;
+import com.fr.third.googlecode.javaewah.IntIterator;
import com.fr.third.eclipse.jgit.internal.storage.file.BasePackBitmapIndex.StoredBitmap;
import java.util.Collections;
diff --git a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java
index f103996d7..b099c004c 100755
--- a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java
+++ b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexV1.java
@@ -50,7 +50,7 @@ import com.fr.third.eclipse.jgit.lib.ObjectId;
import com.fr.third.eclipse.jgit.lib.ObjectIdOwnerMap;
import com.fr.third.eclipse.jgit.util.IO;
import com.fr.third.eclipse.jgit.util.NB;
-import com.googlecode.javaewah.EWAHCompressedBitmap;
+import com.fr.third.googlecode.javaewah.EWAHCompressedBitmap;
import java.io.DataInput;
import java.io.IOException;
diff --git a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexWriterV1.java b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexWriterV1.java
index 70c5d0457..13552f8f1 100755
--- a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexWriterV1.java
+++ b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/file/PackBitmapIndexWriterV1.java
@@ -46,7 +46,7 @@ package com.fr.third.eclipse.jgit.internal.storage.file;
import com.fr.third.eclipse.jgit.internal.JGitText;
import com.fr.third.eclipse.jgit.lib.Constants;
import com.fr.third.eclipse.jgit.util.io.SafeBufferedOutputStream;
-import com.googlecode.javaewah.EWAHCompressedBitmap;
+import com.fr.third.googlecode.javaewah.EWAHCompressedBitmap;
import com.fr.third.eclipse.jgit.internal.storage.file.PackBitmapIndexBuilder.StoredEntry;
import java.io.BufferedOutputStream;
diff --git a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
index 6f3d1fcd4..534d9c890 100755
--- a/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
+++ b/fine-jgit/src/com/fr/third/eclipse/jgit/internal/storage/pack/PackWriterBitmapPreparer.java
@@ -60,7 +60,7 @@ import com.fr.third.eclipse.jgit.revwalk.RevCommit;
import com.fr.third.eclipse.jgit.revwalk.RevObject;
import com.fr.third.eclipse.jgit.revwalk.RevWalk;
import com.fr.third.eclipse.jgit.util.BlockList;
-import com.googlecode.javaewah.EWAHCompressedBitmap;
+import com.fr.third.googlecode.javaewah.EWAHCompressedBitmap;
import com.fr.third.eclipse.jgit.lib.BitmapIndex.BitmapBuilder;
import java.io.IOException;
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/BitCounter.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/BitCounter.java
new file mode 100644
index 000000000..85df35fe5
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/BitCounter.java
@@ -0,0 +1,106 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * BitCounter is a fake bitset data structure. Instead of storing the actual
+ * data, it only records the number of set bits.
+ *
+ * @since 0.4.0
+ * @author David McIntosh
+ */
+
+public final class BitCounter implements BitmapStorage {
+
+ /**
+ * Virtually add words directly to the bitmap
+ *
+ * @param newdata
+ * the word
+ */
+ @Override
+ public void add(final long newdata) {
+ this.oneBits += Long.bitCount(newdata);
+ return;
+ }
+
+ /**
+ * virtually add several literal words.
+ *
+ * @param data
+ * the literal words
+ * @param start
+ * the starting point in the array
+ * @param number
+ * the number of literal words to add
+ */
+ @Override
+ public void addStreamOfLiteralWords(long[] data, int start, int number) {
+ for (int i = start; i < start + number; i++) {
+ add(data[i]);
+ }
+ return;
+ }
+
+ /**
+ * virtually add many zeroes or ones.
+ *
+ * @param v
+ * zeros or ones
+ * @param number
+ * how many to words add
+ */
+ @Override
+public void addStreamOfEmptyWords(boolean v, long number) {
+ if (v) {
+ this.oneBits += number * EWAHCompressedBitmap.wordinbits;
+ }
+ return;
+ }
+
+ /**
+ * virtually add several negated literal words.
+ *
+ * @param data
+ * the literal words
+ * @param start
+ * the starting point in the array
+ * @param number
+ * the number of literal words to add
+ */
+ // @Override : causes problems with Java 1.5
+ @Override
+public void addStreamOfNegatedLiteralWords(long[] data, int start, int number) {
+ for (int i = start; i < start + number; i++) {
+ add(~data[i]);
+ }
+ return;
+ }
+
+ /**
+ * As you act on this class, it records the number of set (true) bits.
+ *
+ * @return number of set bits
+ */
+ public int getCount() {
+ return this.oneBits;
+ }
+
+ /**
+ * should directly set the sizeinbits field, but is effectively ignored in
+ * this class.
+ *
+ * @param bits
+ * number of bits
+ */
+ // @Override : causes problems with Java 1.5
+ @Override
+public void setSizeInBits(int bits) {
+ // no action
+ }
+
+ private int oneBits;
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/BitmapStorage.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/BitmapStorage.java
new file mode 100644
index 000000000..929b2b8b3
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/BitmapStorage.java
@@ -0,0 +1,71 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * Low level bitset writing methods.
+ *
+ * @since 0.4.0
+ * @author David McIntosh
+ */
+public interface BitmapStorage {
+
+ /**
+ * Adding words directly to the bitmap (for expert use).
+ *
+ * This is normally how you add data to the array. So you add bits in streams
+ * of 8*8 bits.
+ *
+ * @param newdata
+ * the word
+ */
+ public void add(final long newdata);
+
+ /**
+ * if you have several literal words to copy over, this might be faster.
+ *
+ * @param data
+ * the literal words
+ * @param start
+ * the starting point in the array
+ * @param number
+ * the number of literal words to add
+ */
+ public void addStreamOfLiteralWords(final long[] data, final int start,
+ final int number);
+
+ /**
+ * For experts: You want to add many zeroes or ones? This is the method you
+ * use.
+ *
+ * @param v
+ * zeros or ones
+ * @param number
+ * how many to words add
+ */
+ public void addStreamOfEmptyWords(final boolean v, final long number);
+
+ /**
+ * Like "addStreamOfLiteralWords" but negates the words being added.
+ *
+ * @param data
+ * the literal words
+ * @param start
+ * the starting point in the array
+ * @param number
+ * the number of literal words to add
+ */
+ public void addStreamOfNegatedLiteralWords(long[] data, final int start,
+ final int number);
+
+ /**
+ * directly set the sizeinbits field
+ *
+ * @param bits
+ * number of bits
+ */
+ public void setSizeInBits(final int bits);
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/BufferedIterator.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/BufferedIterator.java
new file mode 100644
index 000000000..bf0e0c94a
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/BufferedIterator.java
@@ -0,0 +1,151 @@
+package com.fr.third.googlecode.javaewah;
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * This class can be used to iterate over blocks of bitmap data.
+ *
+ * @author Daniel Lemire
+ *
+ */
+public class BufferedIterator implements IteratingRLW {
+ /**
+ * Instantiates a new iterating buffered running length word.
+ *
+ * @param iterator iterator
+ */
+ public BufferedIterator(final CloneableIterator iterator) {
+ this.masteriterator = iterator;
+ if(this.masteriterator.hasNext()) {
+ this.iterator = this.masteriterator.next();
+ this.brlw = new BufferedRunningLengthWord(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords() + this.brlw.literalwordoffset;
+ this.buffer = this.iterator.buffer();
+ }
+ }
+
+
+ /**
+ * Discard first words, iterating to the next running length word if needed.
+ *
+ * @param x the number of words to be discarded
+ */
+ @Override
+ public void discardFirstWords(long x) {
+ while (x > 0) {
+ if (this.brlw.RunningLength > x) {
+ this.brlw.RunningLength -= x;
+ return;
+ }
+ x -= this.brlw.RunningLength;
+ this.brlw.RunningLength = 0;
+ long toDiscard = x > this.brlw.NumberOfLiteralWords ? this.brlw.NumberOfLiteralWords : x;
+
+ this.literalWordStartPosition += toDiscard;
+ this.brlw.NumberOfLiteralWords -= toDiscard;
+ x -= toDiscard;
+ if ((x > 0) || (this.brlw.size() == 0)) {
+ if (!this.next()) {
+ break;
+ }
+ }
+ }
+ }
+ /**
+ * Move to the next RunningLengthWord
+ * @return whether the move was possible
+ */
+ @Override
+ public boolean next() {
+ if (!this.iterator.hasNext()) {
+ if(!reload()) {
+ this.brlw.NumberOfLiteralWords = 0;
+ this.brlw.RunningLength = 0;
+ return false;
+ }
+ }
+ this.brlw.reset(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords(); // + this.brlw.literalwordoffset ==0
+ return true;
+ }
+ private boolean reload() {
+ if(!this.masteriterator.hasNext()) {
+ return false;
+ }
+ this.iterator = this.masteriterator.next();
+ this.buffer = this.iterator.buffer();
+ return true;
+ }
+
+
+ /**
+ * Get the nth literal word for the current running length word
+ * @param index zero based index
+ * @return the literal word
+ */
+ @Override
+ public long getLiteralWordAt(int index) {
+ return this.buffer[this.literalWordStartPosition + index];
+ }
+
+ /**
+ * Gets the number of literal words for the current running length word.
+ *
+ * @return the number of literal words
+ */
+ @Override
+ public int getNumberOfLiteralWords() {
+ return this.brlw.NumberOfLiteralWords;
+ }
+
+ /**
+ * Gets the running bit.
+ *
+ * @return the running bit
+ */
+ @Override
+ public boolean getRunningBit() {
+ return this.brlw.RunningBit;
+ }
+
+ /**
+ * Gets the running length.
+ *
+ * @return the running length
+ */
+ @Override
+ public long getRunningLength() {
+ return this.brlw.RunningLength;
+ }
+
+ /**
+ * Size in uncompressed words of the current running length word.
+ *
+ * @return the size
+ */
+ @Override
+ public long size() {
+ return this.brlw.size();
+ }
+
+
+ @Override
+ public BufferedIterator clone() throws CloneNotSupportedException {
+ BufferedIterator answer = (BufferedIterator) super.clone();
+ answer.brlw = this.brlw.clone();
+ answer.buffer = this.buffer;
+ answer.iterator = this.iterator.clone();
+ answer.literalWordStartPosition = this.literalWordStartPosition;
+ answer.masteriterator = this.masteriterator.clone();
+ return answer;
+ }
+
+ private BufferedRunningLengthWord brlw;
+ private long[] buffer;
+ private int literalWordStartPosition;
+ private EWAHIterator iterator;
+ private CloneableIterator masteriterator;
+ }
\ No newline at end of file
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/BufferedRunningLengthWord.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/BufferedRunningLengthWord.java
new file mode 100644
index 000000000..82afd2014
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/BufferedRunningLengthWord.java
@@ -0,0 +1,175 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+
+
+/**
+ * Mostly for internal use. Similar to RunningLengthWord, but can
+ * be modified without access to the array, and has faster access.
+ *
+ * @author Daniel Lemire
+ * @since 0.1.0
+ *
+ */
+public final class BufferedRunningLengthWord implements Cloneable {
+
+ /**
+ * Instantiates a new buffered running length word.
+ *
+ * @param a the word
+ */
+ public BufferedRunningLengthWord(final long a) {
+ this.NumberOfLiteralWords = (int) (a >>> (1 + RunningLengthWord.runninglengthbits));
+ this.RunningBit = (a & 1) != 0;
+ this.RunningLength = (int) ((a >>> 1) & RunningLengthWord.largestrunninglengthcount);
+ }
+
+ /**
+ * Instantiates a new buffered running length word.
+ *
+ * @param rlw the rlw
+ */
+ public BufferedRunningLengthWord(final RunningLengthWord rlw) {
+ this(rlw.parent.buffer[rlw.position]);
+ }
+
+ /**
+ * Discard first words.
+ *
+ * @param x the x
+ */
+ public void discardFirstWords(long x) {
+ if (this.RunningLength >= x) {
+ this.RunningLength -= x;
+ return;
+ }
+ x -= this.RunningLength;
+ this.RunningLength = 0;
+ this.literalwordoffset += x;
+ this.NumberOfLiteralWords -= x;
+ }
+
+ /**
+ * Gets the number of literal words.
+ *
+ * @return the number of literal words
+ */
+ public int getNumberOfLiteralWords() {
+ return this.NumberOfLiteralWords;
+ }
+
+ /**
+ * Gets the running bit.
+ *
+ * @return the running bit
+ */
+ public boolean getRunningBit() {
+ return this.RunningBit;
+ }
+
+ /**
+ * Gets the running length.
+ *
+ * @return the running length
+ */
+ public long getRunningLength() {
+ return this.RunningLength;
+ }
+
+ /**
+ * Reset the values using the provided word.
+ *
+ * @param a the word
+ */
+ public void reset(final long a) {
+ this.NumberOfLiteralWords = (int) (a >>> (1 + RunningLengthWord.runninglengthbits));
+ this.RunningBit = (a & 1) != 0;
+ this.RunningLength = (int) ((a >>> 1) & RunningLengthWord.largestrunninglengthcount);
+ this.literalwordoffset = 0;
+ }
+
+ /**
+ * Reset the values of this running length word so that it has the same values
+ * as the other running length word.
+ *
+ * @param rlw the other running length word
+ */
+ public void reset(final RunningLengthWord rlw) {
+ reset(rlw.parent.buffer[rlw.position]);
+ }
+
+ /**
+ * Sets the number of literal words.
+ *
+ * @param number the new number of literal words
+ */
+ public void setNumberOfLiteralWords(final int number) {
+ this.NumberOfLiteralWords = number;
+ }
+
+ /**
+ * Sets the running bit.
+ *
+ * @param b the new running bit
+ */
+ public void setRunningBit(final boolean b) {
+ this.RunningBit = b;
+ }
+
+ /**
+ * Sets the running length.
+ *
+ * @param number the new running length
+ */
+ public void setRunningLength(final long number) {
+ this.RunningLength = number;
+ }
+
+ /**
+ * Size in uncompressed words.
+ *
+ * @return the long
+ */
+ public long size() {
+ return this.RunningLength + this.NumberOfLiteralWords;
+ }
+
+ /*
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "running bit = " + getRunningBit() + " running length = "
+ + getRunningLength() + " number of lit. words "
+ + getNumberOfLiteralWords();
+ }
+
+ @Override
+public BufferedRunningLengthWord clone() throws CloneNotSupportedException {
+ BufferedRunningLengthWord answer = (BufferedRunningLengthWord) super.clone();
+ answer.literalwordoffset = this.literalwordoffset;
+ answer.NumberOfLiteralWords = this.NumberOfLiteralWords;
+ answer.RunningBit = this.RunningBit;
+ answer.RunningLength = this.RunningLength;
+ return answer;
+ }
+
+
+ /** how many literal words have we read so far? */
+ public int literalwordoffset = 0;
+
+ /** The Number of literal words. */
+ public int NumberOfLiteralWords;
+
+ /** The Running bit. */
+ public boolean RunningBit;
+
+ /** The Running length. */
+ public long RunningLength;
+
+
+}
\ No newline at end of file
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/CloneableIterator.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/CloneableIterator.java
new file mode 100644
index 000000000..a17eded16
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/CloneableIterator.java
@@ -0,0 +1,24 @@
+package com.fr.third.googlecode.javaewah;
+
+/**
+ * Like a standard Java iterator, except that you can clone it.
+ *
+ * @param the data type of the iterator
+ */
+public interface CloneableIterator extends Cloneable {
+
+ /**
+ * @return whether there is more
+ */
+ public boolean hasNext();
+ /**
+ * @return the next element
+ */
+ public E next();
+ /**
+ * @return a copy
+ * @throws CloneNotSupportedException this should never happen in practice
+ */
+ public CloneableIterator clone() throws CloneNotSupportedException;
+
+}
\ No newline at end of file
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/EWAHCompressedBitmap.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/EWAHCompressedBitmap.java
new file mode 100644
index 000000000..bc9397da9
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/EWAHCompressedBitmap.java
@@ -0,0 +1,1631 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+import java.util.*;
+import java.io.*;
+
+
+
+/**
+ *
+ * This implements the patent-free(1) EWAH scheme. Roughly speaking, it is a
+ * 64-bit variant of the BBC compression scheme used by Oracle for its bitmap
+ * indexes.
+ *
+ *
+ *
+ * The objective of this compression type is to provide some compression, while
+ * reducing as much as possible the CPU cycle usage.
+ *
+ *
+ *
+ *
+ * This implementation being 64-bit, it assumes a 64-bit CPU together with a
+ * 64-bit Java Virtual Machine. This same code on a 32-bit machine may not be as
+ * fast.
+ *
+ *
+ *
+ * There is also a 32-bit version of this code in the class
+ * javaewah32.EWAHCompressedBitmap32
+ *
+ * A 32-bit version of the compressed format was described by Wu et al. and
+ * named WBC:
+ *
+ *
+ *
+ *
K. Wu, E. J. Otoo, A. Shoshani, H. Nordberg, Notes on design and
+ * implementation of compressed bit vectors, Tech. Rep. LBNL/PUB-3161,
+ * Lawrence Berkeley National Laboratory, available from http://crd.lbl.
+ * gov/~kewu/ps/PUB-3161.html (2001).
+ *
+ *
+ *
+ * Probably, the best prior art is the Oracle bitmap compression scheme
+ * (BBC):
+ *
+ *
+ *
G. Antoshenkov, Byte-Aligned Bitmap Compression, DCC'95, 1995.
+ *
+ *
+ *
+ * 1- The authors do not know of any patent infringed by the following
+ * implementation. However, similar schemes, like WAH are covered by
+ * patents.
+ *
+ *
+ * @since 0.1.0
+ */
+public final class EWAHCompressedBitmap implements Cloneable, Externalizable,
+ Iterable, BitmapStorage, LogicalElement {
+
+ /**
+ * Creates an empty bitmap (no bit set to true).
+ */
+ public EWAHCompressedBitmap() {
+ this.buffer = new long[defaultbuffersize];
+ this.rlw = new RunningLengthWord(this, 0);
+ }
+
+ /**
+ * Sets explicitly the buffer size (in 64-bit words). The initial memory usage
+ * will be "buffersize * 64". For large poorly compressible bitmaps, using
+ * large values may improve performance.
+ *
+ * @param buffersize
+ * number of 64-bit words reserved when the object is created)
+ */
+ public EWAHCompressedBitmap(final int buffersize) {
+ this.buffer = new long[buffersize];
+ this.rlw = new RunningLengthWord(this, 0);
+ }
+
+ /**
+ * Adding words directly to the bitmap (for expert use).
+ *
+ * This is normally how you add data to the array. So you add bits in streams
+ * of 8*8 bits.
+ *
+ * Example: if you add 321, you are have added (in binary notation)
+ * 0b101000001, so you have effectively called set(0), set(6), set(8)
+ * in sequence.
+ *
+ * @param newdata
+ * the word
+ */
+ @Override
+public void add(final long newdata) {
+ add(newdata, wordinbits);
+ }
+
+ /**
+ * Adding words directly to the bitmap (for expert use).
+ *
+ * @param newdata
+ * the word
+ * @param bitsthatmatter
+ * the number of significant bits (by default it should be 64)
+ */
+ public void add(final long newdata, final int bitsthatmatter) {
+ this.sizeinbits += bitsthatmatter;
+ if (newdata == 0) {
+ addEmptyWord(false);
+ } else if (newdata == ~0l) {
+ addEmptyWord(true);
+ } else {
+ addLiteralWord(newdata);
+ }
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param v
+ * the boolean value
+ */
+ private void addEmptyWord(final boolean v) {
+ final boolean noliteralword = (this.rlw.getNumberOfLiteralWords() == 0);
+ final long runlen = this.rlw.getRunningLength();
+ if ((noliteralword) && (runlen == 0)) {
+ this.rlw.setRunningBit(v);
+ }
+ if ((noliteralword) && (this.rlw.getRunningBit() == v)
+ && (runlen < RunningLengthWord.largestrunninglengthcount)) {
+ this.rlw.setRunningLength(runlen + 1);
+ return;
+ }
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(1);
+ return;
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param newdata
+ * the literal word
+ */
+ private void addLiteralWord(final long newdata) {
+ final int numbersofar = this.rlw.getNumberOfLiteralWords();
+ if (numbersofar >= RunningLengthWord.largestliteralcount) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ this.rlw.setNumberOfLiteralWords(1);
+ push_back(newdata);
+ }
+ this.rlw.setNumberOfLiteralWords(numbersofar + 1);
+ push_back(newdata);
+ }
+
+ /**
+ * if you have several literal words to copy over, this might be faster.
+ *
+ *
+ * @param data
+ * the literal words
+ * @param start
+ * the starting point in the array
+ * @param number
+ * the number of literal words to add
+ */
+ @Override
+public void addStreamOfLiteralWords(final long[] data, final int start,
+ final int number) {
+ int leftovernumber = number;
+ while(leftovernumber > 0) {
+ final int NumberOfLiteralWords = this.rlw.getNumberOfLiteralWords();
+ final int whatwecanadd = leftovernumber < RunningLengthWord.largestliteralcount
+ - NumberOfLiteralWords ? leftovernumber : RunningLengthWord.largestliteralcount
+ - NumberOfLiteralWords;
+ this.rlw.setNumberOfLiteralWords(NumberOfLiteralWords + whatwecanadd);
+ leftovernumber -= whatwecanadd;
+ push_back(data, start, whatwecanadd);
+ this.sizeinbits += whatwecanadd * wordinbits;
+ if (leftovernumber > 0) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ }
+ }
+ }
+
+ /**
+ * For experts: You want to add many zeroes or ones? This is the method you
+ * use.
+ *
+ * @param v
+ * the boolean value
+ * @param number
+ * the number
+ */
+ @Override
+public void addStreamOfEmptyWords(final boolean v, long number) {
+ if (number == 0)
+ return;
+ this.sizeinbits += number * wordinbits;
+ if ((this.rlw.getRunningBit() != v) && (this.rlw.size() == 0)) {
+ this.rlw.setRunningBit(v);
+ } else if ((this.rlw.getNumberOfLiteralWords() != 0)
+ || (this.rlw.getRunningBit() != v)) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ }
+ final long runlen = this.rlw.getRunningLength();
+ final long whatwecanadd = number < RunningLengthWord.largestrunninglengthcount
+ - runlen ? number : RunningLengthWord.largestrunninglengthcount - runlen;
+ this.rlw.setRunningLength(runlen + whatwecanadd);
+ number -= whatwecanadd;
+ while (number >= RunningLengthWord.largestrunninglengthcount) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(RunningLengthWord.largestrunninglengthcount);
+ number -= RunningLengthWord.largestrunninglengthcount;
+ }
+ if (number > 0) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(number);
+ }
+ }
+
+ /**
+ * Same as addStreamOfLiteralWords, but the words are negated.
+ *
+ * @param data
+ * the literal words
+ * @param start
+ * the starting point in the array
+ * @param number
+ * the number of literal words to add
+ */
+ @Override
+ public void addStreamOfNegatedLiteralWords(final long[] data,
+ final int start, final int number) {
+ int leftovernumber = number;
+ while (leftovernumber > 0) {
+ final int NumberOfLiteralWords = this.rlw.getNumberOfLiteralWords();
+ final int whatwecanadd = leftovernumber < RunningLengthWord.largestliteralcount
+ - NumberOfLiteralWords ? leftovernumber
+ : RunningLengthWord.largestliteralcount
+ - NumberOfLiteralWords;
+ this.rlw.setNumberOfLiteralWords(NumberOfLiteralWords
+ + whatwecanadd);
+ leftovernumber -= whatwecanadd;
+ negative_push_back(data, start, whatwecanadd);
+ this.sizeinbits += whatwecanadd * wordinbits;
+ if (leftovernumber > 0) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ }
+ }
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise AND values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @since 0.4.3
+ * @param a
+ * the other bitmap
+ * @return the EWAH compressed bitmap
+ */
+ @Override
+public EWAHCompressedBitmap and(final EWAHCompressedBitmap a) {
+ final EWAHCompressedBitmap container = new EWAHCompressedBitmap();
+ container
+ .reserve(this.actualsizeinwords > a.actualsizeinwords ? this.actualsizeinwords
+ : a.actualsizeinwords);
+ andToContainer(a, container);
+ return container;
+ }
+ /**
+ * Computes new compressed bitmap containing the bitwise AND values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * @since 0.4.0
+ * @param a
+ * the other bitmap
+ * @param container
+ * where we store the result
+ */
+ public void andToContainer(final EWAHCompressedBitmap a, final BitmapStorage container) {
+ final EWAHIterator i = a.getEWAHIterator();
+ final EWAHIterator j = getEWAHIterator();
+ final IteratingBufferedRunningLengthWord rlwi = new IteratingBufferedRunningLengthWord(i);
+ final IteratingBufferedRunningLengthWord rlwj = new IteratingBufferedRunningLengthWord(j);
+ while ((rlwi.size()>0) && (rlwj.size()>0)) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingBufferedRunningLengthWord prey = i_is_prey ? rlwi : rlwj;
+ final IteratingBufferedRunningLengthWord predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ container.addStreamOfEmptyWords(false, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ final long index = prey.discharge(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) & rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ if(adjustContainerSizeWhenAggregating) {
+ final boolean i_remains = rlwi.size()>0;
+ final IteratingBufferedRunningLengthWord remaining = i_remains ? rlwi : rlwj;
+ remaining.dischargeAsEmpty(container);
+ container.setSizeInBits(Math.max(sizeInBits(), a.sizeInBits()));
+ }
+ }
+
+
+ /**
+ * Returns the cardinality of the result of a bitwise AND of the values of the
+ * current bitmap with some other bitmap. Avoids needing to allocate an
+ * intermediate bitmap to hold the result of the OR.
+ *
+ * @since 0.4.0
+ * @param a
+ * the other bitmap
+ * @return the cardinality
+ */
+ public int andCardinality(final EWAHCompressedBitmap a) {
+ final BitCounter counter = new BitCounter();
+ andToContainer(a, counter);
+ return counter.getCount();
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise AND NOT values of
+ * the current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param a
+ * the other bitmap
+ * @return the EWAH compressed bitmap
+ */
+ @Override
+public EWAHCompressedBitmap andNot(final EWAHCompressedBitmap a) {
+ final EWAHCompressedBitmap container = new EWAHCompressedBitmap();
+ container
+ .reserve(this.actualsizeinwords > a.actualsizeinwords ? this.actualsizeinwords
+ : a.actualsizeinwords);
+ andNotToContainer(a, container);
+ return container;
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise AND NOT values of
+ * the current bitmap with some other bitmap. This method is expected to
+ * be faster than doing A.and(B.clone().not()).
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * @since 0.4.0
+ * @param a the other bitmap
+ * @param container where to store the result
+ */
+ public void andNotToContainer(final EWAHCompressedBitmap a,
+ final BitmapStorage container) {
+ final EWAHIterator i = getEWAHIterator();
+ final EWAHIterator j = a.getEWAHIterator();
+ final IteratingBufferedRunningLengthWord rlwi = new IteratingBufferedRunningLengthWord(i);
+ final IteratingBufferedRunningLengthWord rlwj = new IteratingBufferedRunningLengthWord(j);
+ while ((rlwi.size()>0) && (rlwj.size()>0)) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingBufferedRunningLengthWord prey = i_is_prey ? rlwi : rlwj;
+ final IteratingBufferedRunningLengthWord predator = i_is_prey ? rlwj
+ : rlwi;
+ if ( ((predator.getRunningBit() == true) && (i_is_prey))
+ || ((predator.getRunningBit() == false) && (!i_is_prey))){
+ container.addStreamOfEmptyWords(false, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else if (i_is_prey) {
+ long index = prey.discharge(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ long index = prey.dischargeNegated(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(true, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) & (~rlwj.getLiteralWordAt(k)));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ final boolean i_remains = rlwi.size()>0;
+ final IteratingBufferedRunningLengthWord remaining = i_remains ? rlwi : rlwj;
+ if(i_remains)
+ remaining.discharge(container);
+ else if(adjustContainerSizeWhenAggregating)
+ remaining.dischargeAsEmpty(container);
+ if(adjustContainerSizeWhenAggregating)
+ container.setSizeInBits(Math.max(sizeInBits(), a.sizeInBits()));
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise AND NOT of the values of
+ * the current bitmap with some other bitmap. Avoids needing to allocate an
+ * intermediate bitmap to hold the result of the OR.
+ *
+ * @since 0.4.0
+ * @param a
+ * the other bitmap
+ * @return the cardinality
+ */
+ public int andNotCardinality(final EWAHCompressedBitmap a) {
+ final BitCounter counter = new BitCounter();
+ andNotToContainer(a, counter);
+ return counter.getCount();
+ }
+
+ /**
+ * reports the number of bits set to true. Running time is proportional to
+ * compressed size (as reported by sizeInBytes).
+ *
+ * @return the number of bits set to true
+ */
+ public int cardinality() {
+ int counter = 0;
+ final EWAHIterator i = new EWAHIterator(this, this.actualsizeinwords);
+ while (i.hasNext()) {
+ RunningLengthWord localrlw = i.next();
+ if (localrlw.getRunningBit()) {
+ counter += wordinbits * localrlw.getRunningLength();
+ }
+ for (int j = 0; j < localrlw.getNumberOfLiteralWords(); ++j) {
+ counter += Long.bitCount(i.buffer()[i.literalWords() + j]);
+ }
+ }
+ return counter;
+ }
+
+ /**
+ * Clear any set bits and set size in bits back to 0
+ */
+ public void clear() {
+ this.sizeinbits = 0;
+ this.actualsizeinwords = 1;
+ this.rlw.position = 0;
+ // buffer is not fully cleared but any new set operations should overwrite
+ // stale data
+ this.buffer[0] = 0;
+ }
+
+ /*
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public EWAHCompressedBitmap clone() throws CloneNotSupportedException {
+ final EWAHCompressedBitmap clone = (EWAHCompressedBitmap) super.clone();
+ clone.buffer = this.buffer.clone();
+ clone.rlw = new RunningLengthWord(clone, this.rlw.position);
+ clone.actualsizeinwords = this.actualsizeinwords;
+ clone.sizeinbits = this.sizeinbits;
+ return clone;
+ }
+
+ /**
+ * Deserialize.
+ *
+ * @param in
+ * the DataInput stream
+ * @throws IOException
+ * Signals that an I/O exception has occurred.
+ */
+ public void deserialize(DataInput in) throws IOException {
+ this.sizeinbits = in.readInt();
+ this.actualsizeinwords = in.readInt();
+ if (this.buffer.length < this.actualsizeinwords) {
+ this.buffer = new long[this.actualsizeinwords];
+ }
+ for (int k = 0; k < this.actualsizeinwords; ++k)
+ this.buffer[k] = in.readLong();
+ this.rlw = new RunningLengthWord(this, in.readInt());
+ }
+
+ /**
+ * Check to see whether the two compressed bitmaps contain the same set bits.
+ *
+ * @see Object#equals(Object)
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof EWAHCompressedBitmap) {
+ try {
+ this.xorToContainer((EWAHCompressedBitmap) o, new NonEmptyVirtualStorage());
+ return true;
+ } catch (NonEmptyVirtualStorage.NonEmptyException e) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * For experts: You want to add many zeroes or ones faster?
+ *
+ * This method does not update sizeinbits.
+ *
+ * @param v
+ * the boolean value
+ * @param number
+ * the number (must be greater than 0)
+ */
+ private void fastaddStreamOfEmptyWords(final boolean v, long number) {
+ if ((this.rlw.getRunningBit() != v) && (this.rlw.size() == 0)) {
+ this.rlw.setRunningBit(v);
+ } else if ((this.rlw.getNumberOfLiteralWords() != 0)
+ || (this.rlw.getRunningBit() != v)) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ }
+
+ final long runlen = this.rlw.getRunningLength();
+ final long whatwecanadd = number < RunningLengthWord.largestrunninglengthcount
+ - runlen ? number : RunningLengthWord.largestrunninglengthcount - runlen;
+ this.rlw.setRunningLength(runlen + whatwecanadd);
+ number -= whatwecanadd;
+
+ while (number >= RunningLengthWord.largestrunninglengthcount) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(RunningLengthWord.largestrunninglengthcount);
+ number -= RunningLengthWord.largestrunninglengthcount;
+ }
+ if (number > 0) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(number);
+ }
+ }
+
+ /**
+ * Gets an EWAHIterator over the data. This is a customized iterator which
+ * iterates over run length word. For experts only.
+ *
+ * @return the EWAHIterator
+ */
+ public EWAHIterator getEWAHIterator() {
+ return new EWAHIterator(this, this.actualsizeinwords);
+ }
+
+ /**
+ * @return the IteratingRLW iterator corresponding to this bitmap
+ */
+ public IteratingRLW getIteratingRLW() {
+ return new IteratingBufferedRunningLengthWord(this);
+ }
+ /**
+ * get the locations of the true values as one vector. (may use more memory
+ * than iterator())
+ *
+ * @return the positions
+ */
+ public List getPositions() {
+ final ArrayList v = new ArrayList();
+ final EWAHIterator i = new EWAHIterator(this, this.actualsizeinwords);
+ int pos = 0;
+ while (i.hasNext()) {
+ RunningLengthWord localrlw = i.next();
+ if (localrlw.getRunningBit()) {
+ for (int j = 0; j < localrlw.getRunningLength(); ++j) {
+ for (int c = 0; c < wordinbits; ++c)
+ v.add(new Integer(pos++));
+ }
+ } else {
+ pos += wordinbits * localrlw.getRunningLength();
+ }
+ for (int j = 0; j < localrlw.getNumberOfLiteralWords(); ++j) {
+ long data = i.buffer()[i.literalWords() + j];
+ while (data != 0) {
+ final int ntz = Long.numberOfTrailingZeros(data);
+ data ^= (1l << ntz);
+ v.add(new Integer(ntz + pos));
+ }
+ pos += wordinbits;
+ }
+ }
+ while ((v.size() > 0)
+ && (v.get(v.size() - 1).intValue() >= this.sizeinbits))
+ v.remove(v.size() - 1);
+ return v;
+ }
+
+ /**
+ * Returns a customized hash code (based on Karp-Rabin). Naturally, if the
+ * bitmaps are equal, they will hash to the same value.
+ *
+ */
+ @Override
+ public int hashCode() {
+ int karprabin = 0;
+ final int B = 31;
+ final EWAHIterator i = new EWAHIterator(this, this.actualsizeinwords);
+ while( i.hasNext() ) {
+ i.next();
+ if (i.rlw.getRunningBit() == true) {
+ karprabin += B * karprabin
+ + (i.rlw.getRunningLength() & ((1l << 32) - 1));
+ karprabin += B * karprabin + (i.rlw.getRunningLength() >>> 32);
+ }
+ for (int k = 0; k < i.rlw.getNumberOfLiteralWords(); ++k) {
+ karprabin += B * karprabin + (this.buffer[i.literalWords() + k] & ((1l << 32) - 1));
+ karprabin += B * karprabin + (this.buffer[i.literalWords() + k] >>> 32);
+ }
+ }
+ return karprabin;
+ }
+
+ /**
+ * Return true if the two EWAHCompressedBitmap have both at least one true bit
+ * in the same position. Equivalently, you could call "and" and check whether
+ * there is a set bit, but intersects will run faster if you don't need the
+ * result of the "and" operation.
+ *
+ * @since 0.3.2
+ * @param a
+ * the other bitmap
+ * @return whether they intersect
+ */
+ public boolean intersects(final EWAHCompressedBitmap a) {
+ NonEmptyVirtualStorage nevs = new NonEmptyVirtualStorage();
+ try {
+ this.andToContainer(a, nevs);
+ } catch (NonEmptyVirtualStorage.NonEmptyException nee) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Iterator over the set bits (this is what most people will want to use to
+ * browse the content if they want an iterator). The location of the set bits
+ * is returned, in increasing order.
+ *
+ * @return the int iterator
+ */
+ public IntIterator intIterator() {
+ return new IntIteratorImpl(
+ new EWAHIterator(this, this.actualsizeinwords));
+ }
+
+ /**
+ * iterate over the positions of the true values. This is similar to
+ * intIterator(), but it uses Java generics.
+ *
+ * @return the iterator
+ */
+ @Override
+public Iterator iterator() {
+ return new Iterator() {
+ @Override
+ public boolean hasNext() {
+ return this.under.hasNext();
+ }
+
+ @Override
+ public Integer next() {
+ return new Integer(this.under.next());
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("bitsets do not support remove");
+ }
+
+ final private IntIterator under = intIterator();
+ };
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param data
+ * the array of words to be added
+ * @param start
+ * the starting point
+ * @param number
+ * the number of words to add
+ */
+ private void negative_push_back(final long[] data, final int start,
+ final int number) {
+ while (this.actualsizeinwords + number >= this.buffer.length) {
+ final long oldbuffer[] = this.buffer;
+ if((this.actualsizeinwords + number) < 32768)
+ this.buffer = new long[ (this.actualsizeinwords + number) * 2];
+ else if((this.actualsizeinwords + number) * 3 / 2 < this.actualsizeinwords + number) // overflow
+ this.buffer = new long[Integer.MAX_VALUE];
+ else
+ this.buffer = new long[(this.actualsizeinwords + number) * 3 / 2];
+ System.arraycopy(oldbuffer, 0, this.buffer, 0, oldbuffer.length);
+ this.rlw.parent.buffer = this.buffer;
+ }
+ for (int k = 0; k < number; ++k)
+ this.buffer[this.actualsizeinwords + k] = ~data[start + k];
+ this.actualsizeinwords += number;
+ }
+
+ /**
+ * Negate (bitwise) the current bitmap. To get a negated copy, do
+ * EWAHCompressedBitmap x= ((EWAHCompressedBitmap) mybitmap.clone()); x.not();
+ *
+ * The running time is proportional to the compressed size (as reported by
+ * sizeInBytes()).
+ *
+ */
+ @Override
+public void not() {
+ final EWAHIterator i = new EWAHIterator(this, this.actualsizeinwords);
+ if (!i.hasNext())
+ return;
+
+ while (true) {
+ final RunningLengthWord rlw1 = i.next();
+ rlw1.setRunningBit(!rlw1.getRunningBit());
+ for (int j = 0; j < rlw1.getNumberOfLiteralWords(); ++j) {
+ i.buffer()[i.literalWords() + j] = ~i.buffer()[i.literalWords() + j];
+ }
+
+ if (!i.hasNext()) {// must potentially adjust the last literal word
+ final int usedbitsinlast = this.sizeinbits % wordinbits;
+ if (usedbitsinlast == 0)
+ return;
+
+ if (rlw1.getNumberOfLiteralWords() == 0) {
+ if((rlw1.getRunningLength()>0) && (rlw1.getRunningBit())) {
+ rlw1.setRunningLength(rlw1.getRunningLength()-1);
+ this.addLiteralWord((~0l) >>> (wordinbits - usedbitsinlast));
+ }
+ return;
+ }
+ i.buffer()[i.literalWords() + rlw1.getNumberOfLiteralWords() - 1] &= ((~0l) >>> (wordinbits - usedbitsinlast));
+ return;
+ }
+ }
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise OR values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param a
+ * the other bitmap
+ * @return the EWAH compressed bitmap
+ */
+ @Override
+public EWAHCompressedBitmap or(final EWAHCompressedBitmap a) {
+ final EWAHCompressedBitmap container = new EWAHCompressedBitmap();
+ container.reserve(this.actualsizeinwords + a.actualsizeinwords);
+ orToContainer(a, container);
+ return container;
+ }
+
+
+
+ /**
+ * Computes the bitwise or between the current bitmap and the bitmap "a".
+ * Stores the result in the container.
+ *
+ * @since 0.4.0
+ * @param a
+ * the other bitmap
+ * @param container
+ * where we store the result
+ */
+ public void orToContainer(final EWAHCompressedBitmap a, final BitmapStorage container) {
+ final EWAHIterator i = a.getEWAHIterator();
+ final EWAHIterator j = getEWAHIterator();
+ final IteratingBufferedRunningLengthWord rlwi = new IteratingBufferedRunningLengthWord(i);
+ final IteratingBufferedRunningLengthWord rlwj = new IteratingBufferedRunningLengthWord(j);
+ while ((rlwi.size()>0) && (rlwj.size()>0)) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingBufferedRunningLengthWord prey = i_is_prey ? rlwi
+ : rlwj;
+ final IteratingBufferedRunningLengthWord predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == true) {
+ container.addStreamOfEmptyWords(true, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ long index = prey.discharge(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k) {
+ container.add(rlwi.getLiteralWordAt(k) | rlwj.getLiteralWordAt(k));
+ }
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ final boolean i_remains = rlwi.size()>0;
+ final IteratingBufferedRunningLengthWord remaining = i_remains ? rlwi : rlwj;
+ remaining.discharge(container);
+ container.setSizeInBits(Math.max(sizeInBits(), a.sizeInBits()));
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise OR of the values of the
+ * current bitmap with some other bitmap. Avoids needing to allocate an
+ * intermediate bitmap to hold the result of the OR.
+ *
+ * @since 0.4.0
+ * @param a
+ * the other bitmap
+ * @return the cardinality
+ */
+ public int orCardinality(final EWAHCompressedBitmap a) {
+ final BitCounter counter = new BitCounter();
+ orToContainer(a, counter);
+ return counter.getCount();
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param data
+ * the word to be added
+ */
+ private void push_back(final long data) {
+ if (this.actualsizeinwords == this.buffer.length) {
+ final long oldbuffer[] = this.buffer;
+ if(oldbuffer.length < 32768)
+ this.buffer = new long[ oldbuffer.length * 2];
+ else if(oldbuffer.length * 3 / 2 < oldbuffer.length) // overflow
+ this.buffer = new long[Integer.MAX_VALUE];
+ else
+ this.buffer = new long[oldbuffer.length * 3 / 2];
+ System.arraycopy(oldbuffer, 0, this.buffer, 0, oldbuffer.length);
+ this.rlw.parent.buffer = this.buffer;
+ }
+ this.buffer[this.actualsizeinwords++] = data;
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param data
+ * the array of words to be added
+ * @param start
+ * the starting point
+ * @param number
+ * the number of words to add
+ */
+ private void push_back(final long[] data, final int start, final int number) {
+ if (this.actualsizeinwords + number >= this.buffer.length) {
+ final long oldbuffer[] = this.buffer;
+ if(this.actualsizeinwords + number < 32768)
+ this.buffer = new long[(this.actualsizeinwords + number) * 2];
+ else if ((this.actualsizeinwords + number) * 3 / 2 < this.actualsizeinwords + number) // overflow
+ this.buffer = new long[Integer.MAX_VALUE];
+ else
+ this.buffer = new long[( this.actualsizeinwords + number) * 3 / 2];
+ System.arraycopy(oldbuffer, 0, this.buffer, 0, oldbuffer.length);
+ this.rlw.parent.buffer = this.buffer;
+ }
+ System.arraycopy(data, start, this.buffer, this.actualsizeinwords, number);
+ this.actualsizeinwords += number;
+ }
+
+ /*
+ * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
+ */
+ @Override
+public void readExternal(ObjectInput in) throws IOException {
+ deserialize(in);
+ }
+
+ /**
+ * For internal use (trading off memory for speed).
+ *
+ * @param size
+ * the number of words to allocate
+ * @return True if the operation was a success.
+ */
+ private boolean reserve(final int size) {
+ if (size > this.buffer.length) {
+ final long oldbuffer[] = this.buffer;
+ this.buffer = new long[size];
+ System.arraycopy(oldbuffer, 0, this.buffer, 0, oldbuffer.length);
+ this.rlw.parent.buffer = this.buffer;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Serialize.
+ *
+ * @param out
+ * the DataOutput stream
+ * @throws IOException
+ * Signals that an I/O exception has occurred.
+ */
+ public void serialize(DataOutput out) throws IOException {
+ out.writeInt(this.sizeinbits);
+ out.writeInt(this.actualsizeinwords);
+ for (int k = 0; k < this.actualsizeinwords; ++k)
+ out.writeLong(this.buffer[k]);
+ out.writeInt(this.rlw.position);
+ }
+
+ /**
+ * Report the size required to serialize this bitmap
+ *
+ * @return the size in bytes
+ */
+ public int serializedSizeInBytes() {
+ return this.sizeInBytes() + 3 * 4;
+ }
+
+
+ /**
+ * Query the value of a single bit. Relying on this method when speed is
+ * needed is discouraged. The complexity is linear with the size of the
+ * bitmap.
+ *
+ * (This implementation is based on zhenjl's Go version of JavaEWAH.)
+ *
+ * @param i
+ * the bit we are interested in
+ * @return whether the bit is set to true
+ */
+ public boolean get(final int i) {
+ if ((i < 0) || (i >= this.sizeinbits))
+ return false;
+ int WordChecked = 0;
+ final IteratingRLW j = getIteratingRLW();
+ final int wordi = i/wordinbits;
+ while (WordChecked <= wordi ) {
+ WordChecked += j.getRunningLength();
+ if (wordi < WordChecked) {
+ return j.getRunningBit();
+ }
+ if (wordi < WordChecked + j.getNumberOfLiteralWords()) {
+ final long w = j.getLiteralWordAt(wordi - WordChecked);
+ return (w & (1l << i)) != 0;
+ }
+ WordChecked += j.getNumberOfLiteralWords();
+ j.next();
+ }
+ return false;
+ }
+
+ /**
+ * Set the bit at position i to true, the bits must be set in (strictly) increasing
+ * order. For example, set(15) and then set(7) will fail. You must do set(7)
+ * and then set(15).
+ *
+ * @param i
+ * the index
+ * @return true if the value was set (always true when i greater or equal to sizeInBits()).
+ * @throws IndexOutOfBoundsException
+ * if i is negative or greater than Integer.MAX_VALUE - 64
+ */
+ public boolean set(final int i) {
+ if ((i > Integer.MAX_VALUE - wordinbits) || (i < 0))
+ throw new IndexOutOfBoundsException("Set values should be between 0 and "
+ + (Integer.MAX_VALUE - wordinbits));
+ if (i < this.sizeinbits)
+ return false;
+ // distance in words:
+ final int dist = (i + wordinbits) / wordinbits
+ - (this.sizeinbits + wordinbits - 1) / wordinbits;
+ this.sizeinbits = i + 1;
+ if (dist > 0) {// easy
+ if (dist > 1)
+ fastaddStreamOfEmptyWords(false, dist - 1);
+ addLiteralWord(1l << (i % wordinbits));
+ return true;
+ }
+ if (this.rlw.getNumberOfLiteralWords() == 0) {
+ this.rlw.setRunningLength(this.rlw.getRunningLength() - 1);
+ addLiteralWord(1l << (i % wordinbits));
+ return true;
+ }
+ this.buffer[this.actualsizeinwords - 1] |= 1l << (i % wordinbits);
+ if (this.buffer[this.actualsizeinwords - 1] == ~0l) {
+ this.buffer[this.actualsizeinwords - 1] = 0;
+ --this.actualsizeinwords;
+ this.rlw.setNumberOfLiteralWords(this.rlw.getNumberOfLiteralWords() - 1);
+ // next we add one clean word
+ addEmptyWord(true);
+ }
+ return true;
+ }
+
+ /**
+ * Set the size in bits. This does not change the compressed bitmap.
+ *
+ * @since 0.4.0
+ */
+ @Override
+public void setSizeInBits(final int size) {
+ if((size+EWAHCompressedBitmap.wordinbits-1)/EWAHCompressedBitmap.wordinbits!= (this.sizeinbits+EWAHCompressedBitmap.wordinbits-1)/EWAHCompressedBitmap.wordinbits)
+ throw new RuntimeException("You can only reduce the size of the bitmap within the scope of the last word. To extend the bitmap, please call setSizeInbits(int,boolean).");
+ this.sizeinbits = size;
+ }
+
+ /**
+ * Change the reported size in bits of the *uncompressed* bitmap represented
+ * by this compressed bitmap. It may change the underlying compressed bitmap.
+ * It is not possible to reduce the sizeInBits, but
+ * it can be extended. The new bits are set to false or true depending on the
+ * value of defaultvalue.
+ *
+ * @param size
+ * the size in bits
+ * @param defaultvalue
+ * the default boolean value
+ * @return true if the update was possible
+ */
+ public boolean setSizeInBits(final int size, final boolean defaultvalue) {
+ if (size < this.sizeinbits)
+ return false;
+ if (defaultvalue == false)
+ extendEmptyBits(this, this.sizeinbits, size);
+ else {
+ // next bit could be optimized
+ while (((this.sizeinbits % wordinbits) != 0) && (this.sizeinbits < size)) {
+ this.set(this.sizeinbits);
+ }
+ this.addStreamOfEmptyWords(defaultvalue, (size / wordinbits)
+ - this.sizeinbits / wordinbits);
+ // next bit could be optimized
+ while (this.sizeinbits < size) {
+ this.set(this.sizeinbits);
+ }
+ }
+ this.sizeinbits = size;
+ return true;
+ }
+
+ /**
+ * Returns the size in bits of the *uncompressed* bitmap represented by this
+ * compressed bitmap. Initially, the sizeInBits is zero. It is extended
+ * automatically when you set bits to true.
+ *
+ * @return the size in bits
+ */
+ @Override
+public int sizeInBits() {
+ return this.sizeinbits;
+ }
+
+ /**
+ * Report the *compressed* size of the bitmap (equivalent to memory usage,
+ * after accounting for some overhead).
+ *
+ * @return the size in bytes
+ */
+ @Override
+public int sizeInBytes() {
+ return this.actualsizeinwords * (wordinbits / 8);
+ }
+
+ /**
+ * Populate an array of (sorted integers) corresponding to the location of the
+ * set bits.
+ *
+ * @return the array containing the location of the set bits
+ */
+ public int[] toArray() {
+ int[] ans = new int[this.cardinality()];
+ int inanspos = 0;
+ int pos = 0;
+ final EWAHIterator i = new EWAHIterator(this, this.actualsizeinwords);
+ while (i.hasNext()) {
+ RunningLengthWord localrlw = i.next();
+ if (localrlw.getRunningBit()) {
+ for (int j = 0; j < localrlw.getRunningLength(); ++j) {
+ for (int c = 0; c < wordinbits; ++c) {
+ ans[inanspos++] = pos++;
+ }
+ }
+ } else {
+ pos += wordinbits * localrlw.getRunningLength();
+ }
+ for (int j = 0; j < localrlw.getNumberOfLiteralWords(); ++j) {
+ long data = i.buffer()[i.literalWords() + j];
+ if (!usetrailingzeros) {
+ for (int c = 0; c < wordinbits; ++c) {
+ if ((data & (1l << c)) != 0)
+ ans[inanspos++] = c + pos;
+ }
+ pos += wordinbits;
+ } else {
+ while (data != 0) {
+ final int ntz = Long.numberOfTrailingZeros(data);
+ data ^= (1l << ntz);
+ ans[inanspos++] = ntz + pos;
+ }
+ pos += wordinbits;
+ }
+ }
+ }
+ return ans;
+
+ }
+
+ /**
+ * A more detailed string describing the bitmap (useful for debugging).
+ *
+ * @return the string
+ */
+ public String toDebugString() {
+ String ans = " EWAHCompressedBitmap, size in bits = " + this.sizeinbits
+ + " size in words = " + this.actualsizeinwords + "\n";
+ final EWAHIterator i = new EWAHIterator(this, this.actualsizeinwords);
+ while (i.hasNext()) {
+ RunningLengthWord localrlw = i.next();
+ if (localrlw.getRunningBit()) {
+ ans += localrlw.getRunningLength() + " 1x11\n";
+ } else {
+ ans += localrlw.getRunningLength() + " 0x00\n";
+ }
+ ans += localrlw.getNumberOfLiteralWords() + " dirties\n";
+ for (int j = 0; j < localrlw.getNumberOfLiteralWords(); ++j) {
+ long data = i.buffer()[i.literalWords() + j];
+ ans += "\t" + data + "\n";
+ }
+ }
+ return ans;
+ }
+
+ /**
+ * A string describing the bitmap.
+ *
+ * @return the string
+ */
+ @Override
+ public String toString() {
+ StringBuffer answer = new StringBuffer();
+ IntIterator i = this.intIterator();
+ answer.append("{");
+ if (i.hasNext())
+ answer.append(i.next());
+ while (i.hasNext()) {
+ answer.append(",");
+ answer.append(i.next());
+ }
+ answer.append("}");
+ return answer.toString();
+ }
+
+ /**
+ * swap the content of the bitmap with another.
+ * @param other bitmap to swap with
+ */
+public void swap(final EWAHCompressedBitmap other) {
+ long[] tmp = this.buffer;
+ this.buffer = other.buffer;
+ other.buffer = tmp;
+
+
+ int tmp2 = this.rlw.position;
+ this.rlw.position = other.rlw.position;
+ other.rlw.position = tmp2;
+
+ int tmp3 = this.actualsizeinwords;
+ this.actualsizeinwords = other.actualsizeinwords;
+ other.actualsizeinwords = tmp3;
+
+ int tmp4 = this.sizeinbits;
+ this.sizeinbits = other.sizeinbits;
+ other.sizeinbits = tmp4;
+ }
+
+ /**
+ * Reduce the internal buffer to its minimal allowable size (given
+ * by this.actualsizeinwords). This can free memory.
+ */
+ public void trim() {
+ this.buffer = Arrays.copyOf(this.buffer, this.actualsizeinwords);
+ }
+
+ /*
+ * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
+ */
+ @Override
+public void writeExternal(ObjectOutput out) throws IOException {
+ serialize(out);
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise XOR values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param a
+ * the other bitmap
+ * @return the EWAH compressed bitmap
+ */
+ @Override
+public EWAHCompressedBitmap xor(final EWAHCompressedBitmap a) {
+ final EWAHCompressedBitmap container = new EWAHCompressedBitmap();
+ container.reserve(this.actualsizeinwords + a.actualsizeinwords);
+ xorToContainer(a, container);
+ return container;
+ }
+
+ /**
+ * Computes a new compressed bitmap containing the bitwise XOR values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * @since 0.4.0
+ * @param a
+ * the other bitmap
+ * @param container
+ * where we store the result
+ */
+ public void xorToContainer(final EWAHCompressedBitmap a, final BitmapStorage container) {
+ final EWAHIterator i = a.getEWAHIterator();
+ final EWAHIterator j = getEWAHIterator();
+ final IteratingBufferedRunningLengthWord rlwi = new IteratingBufferedRunningLengthWord(i);
+ final IteratingBufferedRunningLengthWord rlwj = new IteratingBufferedRunningLengthWord(j);
+ while ((rlwi.size()>0) && (rlwj.size()>0)) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingBufferedRunningLengthWord prey = i_is_prey ? rlwi : rlwj;
+ final IteratingBufferedRunningLengthWord predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ long index = prey.discharge(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ long index = prey.dischargeNegated(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(true, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) ^ rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ final boolean i_remains = rlwi.size()>0;
+ final IteratingBufferedRunningLengthWord remaining = i_remains ? rlwi : rlwj;
+ remaining.discharge(container);
+ container.setSizeInBits(Math.max(sizeInBits(), a.sizeInBits()));
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise XOR of the values of the
+ * current bitmap with some other bitmap. Avoids needing to allocate an
+ * intermediate bitmap to hold the result of the OR.
+ *
+ * @since 0.4.0
+ * @param a
+ * the other bitmap
+ * @return the cardinality
+ */
+ public int xorCardinality(final EWAHCompressedBitmap a) {
+ final BitCounter counter = new BitCounter();
+ xorToContainer(a, counter);
+ return counter.getCount();
+ }
+
+ /**
+ * For internal use. Computes the bitwise and of the provided bitmaps and
+ * stores the result in the container.
+ *
+ * @param container
+ * where the result is stored
+ * @param bitmaps
+ * bitmaps to AND
+ * @since 0.4.3
+ */
+ public static void andWithContainer(final BitmapStorage container,
+ final EWAHCompressedBitmap... bitmaps) {
+ if(bitmaps.length == 1) throw new IllegalArgumentException("Need at least one bitmap");
+ if(bitmaps.length == 2) {
+ bitmaps[0].andToContainer(bitmaps[1],container);
+ return;
+ }
+ EWAHCompressedBitmap answer = new EWAHCompressedBitmap();
+ EWAHCompressedBitmap tmp = new EWAHCompressedBitmap();
+ bitmaps[0].andToContainer(bitmaps[1], answer);
+ for(int k = 2; k < bitmaps.length - 1; ++k) {
+ answer.andToContainer(bitmaps[k], tmp);
+ tmp.swap(answer);
+ tmp.clear();
+ }
+ answer.andToContainer(bitmaps[bitmaps.length - 1], container);
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise AND values of the
+ * provided bitmaps.
+ *
+ * It may or may not be faster than doing the aggregation two-by-two (A.and(B).and(C)).
+ *
+ * If only one bitmap is provided, it is returned as is.
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @since 0.4.3
+ * @param bitmaps
+ * bitmaps to AND together
+ * @return result of the AND
+ */
+ public static EWAHCompressedBitmap and(final EWAHCompressedBitmap... bitmaps) {
+ if(bitmaps.length == 1) return bitmaps[0];
+ if(bitmaps.length == 2) return bitmaps[0].and(bitmaps[1]);
+ EWAHCompressedBitmap answer = new EWAHCompressedBitmap();
+ EWAHCompressedBitmap tmp = new EWAHCompressedBitmap();
+ bitmaps[0].andToContainer(bitmaps[1], answer);
+ for(int k = 2; k < bitmaps.length; ++k) {
+ answer.andToContainer(bitmaps[k], tmp);
+ tmp.swap(answer);
+ tmp.clear();
+ }
+ return answer;
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise AND of the values of the
+ * provided bitmaps. Avoids needing to allocate an intermediate bitmap to hold
+ * the result of the AND.
+ *
+ * @since 0.4.3
+ * @param bitmaps
+ * bitmaps to AND
+ * @return the cardinality
+ */
+ public static int andCardinality(final EWAHCompressedBitmap... bitmaps) {
+ if(bitmaps.length == 1) return bitmaps[0].cardinality();
+ final BitCounter counter = new BitCounter();
+ andWithContainer(counter, bitmaps);
+ return counter.getCount();
+ }
+
+ /**
+ * Return a bitmap with the bit set to true at the given
+ * positions. The positions should be given in sorted order.
+ *
+ * (This is a convenience method.)
+ *
+ * @since 0.4.5
+ * @param setbits list of set bit positions
+ * @return the bitmap
+ */
+ public static EWAHCompressedBitmap bitmapOf(int ... setbits) {
+ EWAHCompressedBitmap a = new EWAHCompressedBitmap();
+ for (int k : setbits)
+ a.set(k);
+ return a;
+ }
+
+
+
+
+ /**
+ * For internal use. This simply adds a stream of words made of zeroes so that
+ * we pad to the desired size.
+ *
+ * @param storage
+ * bitmap to extend
+ * @param currentSize
+ * current size (in bits)
+ * @param newSize
+ * new desired size (in bits)
+ * @since 0.4.3
+ */
+ private static void extendEmptyBits(final BitmapStorage storage,
+ final int currentSize, final int newSize) {
+ final int currentLeftover = currentSize % wordinbits;
+ final int finalLeftover = newSize % wordinbits;
+ storage.addStreamOfEmptyWords(false, (newSize / wordinbits) - currentSize
+ / wordinbits + (finalLeftover != 0 ? 1 : 0)
+ + (currentLeftover != 0 ? -1 : 0));
+ }
+
+
+ /**
+ * Uses an adaptive technique to compute the logical OR.
+ * Mostly for internal use.
+ *
+ * @param container where the aggregate is written.
+ * @param bitmaps to be aggregated
+ */
+ public static void orWithContainer(final BitmapStorage container,
+ final EWAHCompressedBitmap... bitmaps) {
+ if (bitmaps.length < 2)
+ throw new IllegalArgumentException("You should provide at least two bitmaps, provided "+bitmaps.length);
+ long size = 0L;
+ long sinbits = 0L;
+ for (EWAHCompressedBitmap b : bitmaps) {
+ size += b.sizeInBytes();
+ if (sinbits < b.sizeInBits())
+ sinbits = b.sizeInBits();
+ }
+ if (size * 8 > sinbits) {
+ FastAggregation.bufferedorWithContainer(container, 65536, bitmaps);
+ } else {
+ FastAggregation.orToContainer(container, bitmaps);
+ }
+ }
+
+
+ /**
+ * Uses an adaptive technique to compute the logical XOR.
+ * Mostly for internal use.
+ *
+ * @param container where the aggregate is written.
+ * @param bitmaps to be aggregated
+ */
+ public static void xorWithContainer(final BitmapStorage container,
+ final EWAHCompressedBitmap... bitmaps) {
+ if (bitmaps.length < 2)
+ throw new IllegalArgumentException("You should provide at least two bitmaps, provided "+bitmaps.length);
+ long size = 0L;
+ long sinbits = 0L;
+ for (EWAHCompressedBitmap b : bitmaps) {
+ size += b.sizeInBytes();
+ if (sinbits < b.sizeInBits())
+ sinbits = b.sizeInBits();
+ }
+ if (size * 8 > sinbits) {
+ FastAggregation.bufferedxorWithContainer(container, 65536, bitmaps);
+ } else {
+ FastAggregation.xorToContainer(container, bitmaps);
+ }
+ }
+ /**
+ * Returns a new compressed bitmap containing the bitwise OR values of the
+ * provided bitmaps. This is typically faster than doing the aggregation
+ * two-by-two (A.or(B).or(C).or(D)).
+ *
+ * If only one bitmap is provided, it is returned as is.
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @since 0.4.0
+ * @param bitmaps
+ * bitmaps to OR together
+ * @return result of the OR
+ */
+ public static EWAHCompressedBitmap or(final EWAHCompressedBitmap... bitmaps) {
+ if(bitmaps.length == 1)
+ return bitmaps[0];
+ final EWAHCompressedBitmap container = new EWAHCompressedBitmap();
+ int largestSize = 0;
+ for (EWAHCompressedBitmap bitmap : bitmaps) {
+ largestSize = Math.max(bitmap.actualsizeinwords, largestSize);
+ }
+ container.reserve((int) (largestSize * 1.5));
+ orWithContainer(container, bitmaps);
+ return container;
+ }
+ /**
+ * Returns a new compressed bitmap containing the bitwise XOR values of the
+ * provided bitmaps. This is typically faster than doing the aggregation
+ * two-by-two (A.xor(B).xor(C).xor(D)).
+ *
+ * If only one bitmap is provided, it is returned as is.
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param bitmaps
+ * bitmaps to XOR together
+ * @return result of the XOR
+ */
+ public static EWAHCompressedBitmap xor(final EWAHCompressedBitmap... bitmaps) {
+ if(bitmaps.length == 1)
+ return bitmaps[0];
+ final EWAHCompressedBitmap container = new EWAHCompressedBitmap();
+ int largestSize = 0;
+ for (EWAHCompressedBitmap bitmap : bitmaps) {
+ largestSize = Math.max(bitmap.actualsizeinwords, largestSize);
+ }
+ container.reserve((int) (largestSize * 1.5));
+ xorWithContainer(container, bitmaps);
+ return container;
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise OR of the values of the
+ * provided bitmaps. Avoids needing to allocate an intermediate bitmap to hold
+ * the result of the OR.
+ *
+ * @since 0.4.0
+ * @param bitmaps
+ * bitmaps to OR
+ * @return the cardinality
+ */
+ public static int orCardinality(final EWAHCompressedBitmap... bitmaps) {
+ if(bitmaps.length == 1) return bitmaps[0].cardinality();
+ final BitCounter counter = new BitCounter();
+ orWithContainer(counter, bitmaps);
+ return counter.getCount();
+ }
+
+ /** The actual size in words. */
+ int actualsizeinwords = 1;
+
+ /** The buffer (array of 64-bit words) */
+ long buffer[] = null;
+
+ /** The current (last) running length word. */
+ RunningLengthWord rlw = null;
+
+ /** sizeinbits: number of bits in the (uncompressed) bitmap. */
+ int sizeinbits = 0;
+
+ /**
+ * The Constant defaultbuffersize: default memory allocation when the object
+ * is constructed.
+ */
+ static final int defaultbuffersize = 4;
+
+ /** optimization option **/
+ public static final boolean usetrailingzeros = true;
+
+ /** whether we adjust after some aggregation by adding in zeroes **/
+ public static final boolean adjustContainerSizeWhenAggregating = true;
+
+ /** The Constant wordinbits represents the number of bits in a long. */
+ public static final int wordinbits = 64;
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/EWAHIterator.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/EWAHIterator.java
new file mode 100644
index 000000000..991698814
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/EWAHIterator.java
@@ -0,0 +1,98 @@
+package com.fr.third.googlecode.javaewah;
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * The class EWAHIterator represents a special type of
+ * efficient iterator iterating over (uncompressed) words of bits.
+ * It is not meant for end users.
+ * @author Daniel Lemire
+ * @since 0.1.0
+ *
+ */
+public final class EWAHIterator implements Cloneable {
+
+ /**
+ * Instantiates a new EWAH iterator.
+ *
+ * @param a the array of words
+ * @param sizeinwords the number of words that are significant in the array of words
+ */
+ public EWAHIterator(final EWAHCompressedBitmap a, final int sizeinwords) {
+ this.rlw = new RunningLengthWord(a, 0);
+ this.size = sizeinwords;
+ this.pointer = 0;
+ }
+
+ /**
+ * Allow expert developers to instantiate an EWAHIterator.
+ *
+ * @param bitmap we want to iterate over
+ * @return an iterator
+ */
+ public static EWAHIterator getEWAHIterator(EWAHCompressedBitmap bitmap) {
+ return bitmap.getEWAHIterator();
+ }
+
+
+ /**
+ * Access to the array of words
+ *
+ * @return the long[]
+ */
+ public long[] buffer() {
+ return this.rlw.parent.buffer;
+ }
+
+ /**
+ * Position of the literal words represented by this running length word.
+ *
+ * @return the int
+ */
+ public int literalWords() {
+ return this.pointer - this.rlw.getNumberOfLiteralWords();
+ }
+
+ /**
+ * Checks for next.
+ *
+ * @return true, if successful
+ */
+ public boolean hasNext() {
+ return this.pointer < this.size;
+ }
+
+ /**
+ * Next running length word.
+ *
+ * @return the running length word
+ */
+ public RunningLengthWord next() {
+ this.rlw.position = this.pointer;
+ this.pointer += this.rlw.getNumberOfLiteralWords() + 1;
+ return this.rlw;
+ }
+
+ @Override
+ public EWAHIterator clone() throws CloneNotSupportedException {
+ EWAHIterator ans = (EWAHIterator) super.clone();
+ ans.rlw = this.rlw.clone();
+ ans.size = this.size;
+ ans.pointer = this.pointer;
+ return ans;
+ }
+ /** The pointer represent the location of the current running length
+ * word in the array of words (embedded in the rlw attribute). */
+ int pointer;
+
+ /** The current running length word. */
+ RunningLengthWord rlw;
+
+ /** The size in words. */
+ int size;
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/FastAggregation.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/FastAggregation.java
new file mode 100644
index 000000000..80d378469
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/FastAggregation.java
@@ -0,0 +1,436 @@
+package com.fr.third.googlecode.javaewah;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.PriorityQueue;
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * Fast algorithms to aggregate many bitmaps. These algorithms are just given as
+ * reference. They may not be faster than the corresponding methods in the
+ * EWAHCompressedBitmap class.
+ *
+ * @author Daniel Lemire
+ *
+ */
+public class FastAggregation {
+ /**
+ * Compute the and aggregate using a temporary uncompressed bitmap.
+ * @param bitmaps the source bitmaps
+ * @param bufsize buffer size used during the computation in 64-bit words (per input bitmap)
+ * @return the or aggregate.
+ */
+ public static EWAHCompressedBitmap bufferedand(final int bufsize,
+ final EWAHCompressedBitmap... bitmaps) {
+ EWAHCompressedBitmap answer = new EWAHCompressedBitmap();
+ bufferedandWithContainer(answer,bufsize, bitmaps);
+ return answer;
+ }
+ /**
+ * Compute the and aggregate using a temporary uncompressed bitmap.
+ *
+ * @param container where the aggregate is written
+ * @param bufsize buffer size used during the computation in 64-bit words (per input bitmap)
+ * @param bitmaps the source bitmaps
+ */
+ public static void bufferedandWithContainer(final BitmapStorage container,final int bufsize,
+ final EWAHCompressedBitmap... bitmaps) {
+
+ java.util.LinkedList al = new java.util.LinkedList();
+ for (EWAHCompressedBitmap bitmap : bitmaps) {
+ al.add(new IteratingBufferedRunningLengthWord(bitmap));
+ }
+
+ long[] hardbitmap = new long[bufsize*bitmaps.length];
+
+ for(IteratingRLW i : al)
+ if (i.size() == 0) {
+ al.clear();
+ break;
+ }
+
+ while (!al.isEmpty()) {
+ Arrays.fill(hardbitmap, ~0l);
+ long effective = Integer.MAX_VALUE;
+ for(IteratingRLW i : al) {
+ int eff = IteratorAggregation.inplaceand(hardbitmap, i);
+ if (eff < effective)
+ effective = eff;
+ }
+ for (int k = 0; k < effective; ++k)
+ container.add(hardbitmap[k]);
+ for(IteratingRLW i : al)
+ if (i.size() == 0) {
+ al.clear();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Compute the or aggregate using a temporary uncompressed bitmap.
+ * @param bitmaps the source bitmaps
+ * @param bufsize buffer size used during the computation in 64-bit words
+ * @return the or aggregate.
+ */
+ public static EWAHCompressedBitmap bufferedor(final int bufsize,
+ final EWAHCompressedBitmap... bitmaps) {
+ EWAHCompressedBitmap answer = new EWAHCompressedBitmap();
+ bufferedorWithContainer(answer, bufsize, bitmaps);
+ return answer;
+ }
+
+ /**
+ * Compute the or aggregate using a temporary uncompressed bitmap.
+ *
+ * @param container where the aggregate is written
+ * @param bufsize buffer size used during the computation in 64-bit words
+ * @param bitmaps the source bitmaps
+ */
+ public static void bufferedorWithContainer(final BitmapStorage container, final int bufsize,
+ final EWAHCompressedBitmap... bitmaps) {
+ int range = 0;
+ EWAHCompressedBitmap[] sbitmaps = bitmaps.clone();
+ Arrays.sort(sbitmaps, new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap a, EWAHCompressedBitmap b) {
+ return b.sizeinbits - a.sizeinbits;
+ }
+ });
+
+ java.util.ArrayList al = new java.util.ArrayList();
+ for (EWAHCompressedBitmap bitmap : sbitmaps) {
+ if (bitmap.sizeinbits > range)
+ range = bitmap.sizeinbits;
+ al.add(new IteratingBufferedRunningLengthWord(bitmap));
+ }
+ long[] hardbitmap = new long[bufsize];
+ int maxr = al.size();
+ while (maxr > 0) {
+ long effective = 0;
+ for (int k = 0; k < maxr; ++k) {
+ if (al.get(k).size() > 0) {
+ int eff = IteratorAggregation.inplaceor(hardbitmap, al.get(k));
+ if (eff > effective)
+ effective = eff;
+ } else
+ maxr = k;
+ }
+ for (int k = 0; k < effective; ++k)
+ container.add(hardbitmap[k]);
+ Arrays.fill(hardbitmap, 0);
+
+ }
+ container.setSizeInBits(range);
+ }
+
+ /**
+ * Compute the xor aggregate using a temporary uncompressed bitmap.
+ * @param bitmaps the source bitmaps
+ * @param bufsize buffer size used during the computation in 64-bit words
+ * @return the xor aggregate.
+ */
+ public static EWAHCompressedBitmap bufferedxor(final int bufsize,
+ final EWAHCompressedBitmap... bitmaps) {
+ EWAHCompressedBitmap answer = new EWAHCompressedBitmap();
+ bufferedxorWithContainer(answer, bufsize,bitmaps);
+ return answer;
+ }
+
+
+ /**
+ * Compute the xor aggregate using a temporary uncompressed bitmap.
+ *
+ * @param container where the aggregate is written
+ * @param bufsize buffer size used during the computation in 64-bit words
+ * @param bitmaps the source bitmaps
+ */
+ public static void bufferedxorWithContainer(final BitmapStorage container, final int bufsize,
+ final EWAHCompressedBitmap... bitmaps) {
+ int range = 0;
+ EWAHCompressedBitmap[] sbitmaps = bitmaps.clone();
+ Arrays.sort(sbitmaps, new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap a, EWAHCompressedBitmap b) {
+ return b.sizeinbits - a.sizeinbits;
+ }
+ });
+
+ java.util.ArrayList al = new java.util.ArrayList();
+ for (EWAHCompressedBitmap bitmap : sbitmaps) {
+ if (bitmap.sizeinbits > range)
+ range = bitmap.sizeinbits;
+ al.add(new IteratingBufferedRunningLengthWord(bitmap));
+ }
+ long[] hardbitmap = new long[bufsize];
+ int maxr = al.size();
+ while (maxr > 0) {
+ long effective = 0;
+ for (int k = 0; k < maxr; ++k) {
+ if (al.get(k).size() > 0) {
+ int eff = IteratorAggregation.inplacexor(hardbitmap, al.get(k));
+ if (eff > effective)
+ effective = eff;
+ } else
+ maxr = k;
+ }
+ for (int k = 0; k < effective; ++k)
+ container.add(hardbitmap[k]);
+ Arrays.fill(hardbitmap, 0);
+ }
+ container.setSizeInBits(range);
+ }
+
+ /**
+ * Uses a priority queue to compute the or aggregate.
+ * @param a class extending LogicalElement (like a compressed bitmap)
+ * @param bitmaps
+ * bitmaps to be aggregated
+ * @return the or aggregate
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static T or(T... bitmaps) {
+ PriorityQueue pq = new PriorityQueue(bitmaps.length,
+ new Comparator() {
+ @Override
+ public int compare(T a, T b) {
+ return a.sizeInBytes() - b.sizeInBytes();
+ }
+ });
+ for (T x : bitmaps) {
+ pq.add(x);
+ }
+ while (pq.size() > 1) {
+ T x1 = pq.poll();
+ T x2 = pq.poll();
+ pq.add((T) x1.or(x2));
+ }
+ return pq.poll();
+ }
+ /**
+ * Uses a priority queue to compute the or aggregate.
+ * @param container where we write the result
+ * @param bitmaps to be aggregated
+ */
+ public static void orToContainer(final BitmapStorage container,
+ final EWAHCompressedBitmap ... bitmaps) {
+ if(bitmaps.length < 2) throw new IllegalArgumentException("We need at least two bitmaps");
+ PriorityQueue pq = new PriorityQueue(bitmaps.length,
+ new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap a, EWAHCompressedBitmap b) {
+ return a.sizeInBytes() - b.sizeInBytes();
+ }
+ });
+ for (EWAHCompressedBitmap x : bitmaps) {
+ pq.add(x);
+ }
+ while (pq.size() > 2) {
+ EWAHCompressedBitmap x1 = pq.poll();
+ EWAHCompressedBitmap x2 = pq.poll();
+ pq.add(x1.or(x2));
+ }
+ pq.poll().orToContainer(pq.poll(), container);
+ }
+
+
+ /**
+ * Uses a priority queue to compute the xor aggregate.
+ *
+ * @param a class extending LogicalElement (like a compressed bitmap)
+ * @param bitmaps
+ * bitmaps to be aggregated
+ * @return the xor aggregate
+ */
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public static T xor(T... bitmaps) {
+ PriorityQueue pq = new PriorityQueue(bitmaps.length,
+ new Comparator() {
+
+ @Override
+ public int compare(T a, T b) {
+ return a.sizeInBytes() - b.sizeInBytes();
+ }
+ });
+ for (T x : bitmaps)
+ pq.add(x);
+ while (pq.size() > 1) {
+ T x1 = pq.poll();
+ T x2 = pq.poll();
+ pq.add((T) x1.xor(x2));
+ }
+ return pq.poll();
+ }
+
+ /**
+ * Uses a priority queue to compute the xor aggregate.
+ * @param container where we write the result
+ * @param bitmaps to be aggregated
+ */
+ public static void xorToContainer(final BitmapStorage container,
+ final EWAHCompressedBitmap ... bitmaps) {
+ if(bitmaps.length < 2) throw new IllegalArgumentException("We need at least two bitmaps");
+ PriorityQueue pq = new PriorityQueue(bitmaps.length,
+ new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap a, EWAHCompressedBitmap b) {
+ return a.sizeInBytes() - b.sizeInBytes();
+ }
+ });
+ for (EWAHCompressedBitmap x : bitmaps) {
+ pq.add(x);
+ }
+ while (pq.size() > 2) {
+ EWAHCompressedBitmap x1 = pq.poll();
+ EWAHCompressedBitmap x2 = pq.poll();
+ pq.add(x1.xor(x2));
+ }
+ pq.poll().xorToContainer(pq.poll(), container);
+ }
+
+ /**
+ * For internal use. Computes the bitwise or of the provided bitmaps and
+ * stores the result in the container. (This used to be the default.)
+ *
+ * @deprecated use EWAHCompressedBitmap.or instead
+ * @since 0.4.0
+ * @param container where store the result
+ * @param bitmaps to be aggregated
+ */
+ @Deprecated
+ public static void legacy_orWithContainer(final BitmapStorage container,
+ final EWAHCompressedBitmap... bitmaps) {
+ if (bitmaps.length == 2) {
+ // should be more efficient
+ bitmaps[0].orToContainer(bitmaps[1], container);
+ return;
+ }
+
+ // Sort the bitmaps in descending order by sizeinbits. We will exhaust the
+ // sorted bitmaps from right to left.
+ final EWAHCompressedBitmap[] sortedBitmaps = bitmaps.clone();
+ Arrays.sort(sortedBitmaps, new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap a, EWAHCompressedBitmap b) {
+ return a.sizeinbits < b.sizeinbits ? 1
+ : a.sizeinbits == b.sizeinbits ? 0 : -1;
+ }
+ });
+
+ final IteratingBufferedRunningLengthWord[] rlws = new IteratingBufferedRunningLengthWord[bitmaps.length];
+ int maxAvailablePos = 0;
+ for (EWAHCompressedBitmap bitmap : sortedBitmaps) {
+ EWAHIterator iterator = bitmap.getEWAHIterator();
+ if (iterator.hasNext()) {
+ rlws[maxAvailablePos++] = new IteratingBufferedRunningLengthWord(
+ iterator);
+ }
+ }
+
+ if (maxAvailablePos == 0) { // this never happens...
+ container.setSizeInBits(0);
+ return;
+ }
+
+ int maxSize = sortedBitmaps[0].sizeinbits;
+
+ while (true) {
+ long maxOneRl = 0;
+ long minZeroRl = Long.MAX_VALUE;
+ long minSize = Long.MAX_VALUE;
+ int numEmptyRl = 0;
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord rlw = rlws[i];
+ long size = rlw.size();
+ if (size == 0) {
+ maxAvailablePos = i;
+ break;
+ }
+ minSize = Math.min(minSize, size);
+
+ if (rlw.getRunningBit()) {
+ long rl = rlw.getRunningLength();
+ maxOneRl = Math.max(maxOneRl, rl);
+ minZeroRl = 0;
+ if (rl == 0 && size > 0) {
+ numEmptyRl++;
+ }
+ } else {
+ long rl = rlw.getRunningLength();
+ minZeroRl = Math.min(minZeroRl, rl);
+ if (rl == 0 && size > 0) {
+ numEmptyRl++;
+ }
+ }
+ }
+
+ if (maxAvailablePos == 0) {
+ break;
+ } else if (maxAvailablePos == 1) {
+ // only one bitmap is left so just write the rest of it out
+ rlws[0].discharge(container);
+ break;
+ }
+
+ if (maxOneRl > 0) {
+ container.addStreamOfEmptyWords(true, maxOneRl);
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord rlw = rlws[i];
+ rlw.discardFirstWords(maxOneRl);
+ }
+ } else if (minZeroRl > 0) {
+ container.addStreamOfEmptyWords(false, minZeroRl);
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord rlw = rlws[i];
+ rlw.discardFirstWords(minZeroRl);
+ }
+ } else {
+ int index = 0;
+
+ if (numEmptyRl == 1) {
+ // if one rlw has literal words to process and the rest have a run of
+ // 0's we can write them out here
+ IteratingBufferedRunningLengthWord emptyRl = null;
+ long minNonEmptyRl = Long.MAX_VALUE;
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord rlw = rlws[i];
+ long rl = rlw.getRunningLength();
+ if (rl == 0) {
+ assert emptyRl == null;
+ emptyRl = rlw;
+ } else {
+ minNonEmptyRl = Math.min(minNonEmptyRl, rl);
+ }
+ }
+ long wordsToWrite = minNonEmptyRl > minSize ? minSize : minNonEmptyRl;
+ if (emptyRl != null)
+ emptyRl.writeLiteralWords((int) wordsToWrite, container);
+ index += wordsToWrite;
+ }
+
+ while (index < minSize) {
+ long word = 0;
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord rlw = rlws[i];
+ if (rlw.getRunningLength() <= index) {
+ word |= rlw.getLiteralWordAt(index - (int) rlw.getRunningLength());
+ }
+ }
+ container.add(word);
+ index++;
+ }
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord rlw = rlws[i];
+ rlw.discardFirstWords(minSize);
+ }
+ }
+ }
+ container.setSizeInBits(maxSize);
+ }
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIterator.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIterator.java
new file mode 100644
index 000000000..2aa5ef020
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIterator.java
@@ -0,0 +1,31 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ *
+ * The IntIterator interface is used to iterate over a stream of integers.
+ *
+ * @author Daniel Lemire
+ * @since 0.2.0
+ *
+ */
+public interface IntIterator {
+
+ /**
+ * Is there more?
+ *
+ * @return true, if there is more, false otherwise
+ */
+ public boolean hasNext();
+
+ /**
+ * Return the next integer
+ *
+ * @return the integer
+ */
+ public int next();
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIteratorImpl.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIteratorImpl.java
new file mode 100644
index 000000000..0728ce643
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIteratorImpl.java
@@ -0,0 +1,87 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2012, Google Inc.
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+import static com.fr.third.googlecode.javaewah.EWAHCompressedBitmap.wordinbits;
+
+/**
+ * The IntIteratorImpl is the 64 bit implementation of the
+ * IntIterator interface, which efficiently returns the stream of integers
+ * represented by an EWAHIterator.
+ *
+ * @author Colby Ranger
+ * @since 0.5.6
+ */
+final class IntIteratorImpl implements IntIterator {
+
+ private final EWAHIterator ewahIter;
+ private final long[] ewahBuffer;
+ private int position;
+ private int runningLength;
+ private long word;
+ private int wordPosition;
+ private int wordLength;
+ private int literalPosition;
+ private boolean hasnext;
+
+ IntIteratorImpl(EWAHIterator ewahIter) {
+ this.ewahIter = ewahIter;
+ this.ewahBuffer = ewahIter.buffer();
+ this.hasnext = this.moveToNext();
+ }
+
+ public final boolean moveToNext() {
+ while (!runningHasNext() && !literalHasNext()) {
+ if (!this.ewahIter.hasNext()) {
+ return false;
+ }
+ setRunningLengthWord(this.ewahIter.next());
+ }
+ return true;
+ }
+
+ @Override
+public boolean hasNext() {
+ return this.hasnext;
+ }
+
+ @Override
+public final int next() {
+ final int answer;
+ if (runningHasNext()) {
+ answer = this.position++;
+ } else {
+ final int bit = Long.numberOfTrailingZeros(this.word);
+ this.word ^= (1l << bit);
+ answer = this.literalPosition + bit;
+ }
+ this.hasnext = this.moveToNext();
+ return answer;
+ }
+
+ private final void setRunningLengthWord(RunningLengthWord rlw) {
+ this.runningLength = wordinbits * (int) rlw.getRunningLength() + this.position;
+ if (!rlw.getRunningBit()) {
+ this.position = this.runningLength;
+ }
+
+ this.wordPosition = this.ewahIter.literalWords();
+ this.wordLength = this.wordPosition + rlw.getNumberOfLiteralWords();
+ }
+
+ private final boolean runningHasNext() {
+ return this.position < this.runningLength;
+ }
+
+ private final boolean literalHasNext() {
+ while (this.word == 0 && this.wordPosition < this.wordLength) {
+ this.word = this.ewahBuffer[this.wordPosition++];
+ this.literalPosition = this.position;
+ this.position += wordinbits;
+ }
+ return this.word != 0;
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIteratorOverIteratingRLW.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIteratorOverIteratingRLW.java
new file mode 100644
index 000000000..c4bf20f63
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/IntIteratorOverIteratingRLW.java
@@ -0,0 +1,89 @@
+package com.fr.third.googlecode.javaewah;
+
+import static com.fr.third.googlecode.javaewah.EWAHCompressedBitmap.wordinbits;
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * Implementation of an IntIterator over an IteratingRLW.
+ *
+ *
+ */
+public class IntIteratorOverIteratingRLW implements IntIterator {
+ IteratingRLW parent;
+ private int position;
+ private int runningLength;
+ private long word;
+ private int wordPosition;
+ private int wordLength;
+ private int literalPosition;
+ private boolean hasnext;
+
+ /**
+ * @param p iterator we wish to iterate over
+ */
+ public IntIteratorOverIteratingRLW(final IteratingRLW p) {
+ this.parent = p;
+ this.position = 0;
+ setupForCurrentRunningLengthWord();
+ this.hasnext = moveToNext();
+ }
+
+ /**
+ * @return whether we could find another set bit; don't move if there is an unprocessed value
+ */
+ private final boolean moveToNext() {
+ while (!runningHasNext() && !literalHasNext()) {
+ if (this.parent.next())
+ setupForCurrentRunningLengthWord();
+ else return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.hasnext;
+ }
+
+ @Override
+ public final int next() {
+ final int answer;
+ if (runningHasNext()) {
+ answer = this.position++;
+ } else {
+ final int bit = Long.numberOfTrailingZeros(this.word);
+ this.word ^= (1l << bit);
+ answer = this.literalPosition + bit;
+ }
+ this.hasnext = this.moveToNext();
+ return answer;
+ }
+
+ private final void setupForCurrentRunningLengthWord() {
+ this.runningLength = wordinbits * (int) this.parent.getRunningLength()
+ + this.position;
+
+ if (!this.parent.getRunningBit()) {
+ this.position = this.runningLength;
+ }
+ this.wordPosition = 0;
+ this.wordLength = this.parent.getNumberOfLiteralWords();
+ }
+
+ private final boolean runningHasNext() {
+ return this.position < this.runningLength;
+ }
+
+ private final boolean literalHasNext() {
+ while (this.word == 0 && this.wordPosition < this.wordLength) {
+ this.word = this.parent.getLiteralWordAt(this.wordPosition++);
+ this.literalPosition = this.position;
+ this.position += wordinbits;
+ }
+ return this.word != 0;
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratingBufferedRunningLengthWord.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratingBufferedRunningLengthWord.java
new file mode 100644
index 000000000..bb8f2edc5
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratingBufferedRunningLengthWord.java
@@ -0,0 +1,276 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * Mostly for internal use. Similar to BufferedRunningLengthWord, but automatically
+ * advances to the next BufferedRunningLengthWord as words are discarded.
+ *
+ * @since 0.4.0
+ * @author David McIntosh
+ */
+public final class IteratingBufferedRunningLengthWord implements IteratingRLW, Cloneable{
+ /**
+ * Instantiates a new iterating buffered running length word.
+ *
+ * @param iterator iterator
+ */
+ public IteratingBufferedRunningLengthWord(final EWAHIterator iterator) {
+ this.iterator = iterator;
+ this.brlw = new BufferedRunningLengthWord(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords() + this.brlw.literalwordoffset;
+ this.buffer = this.iterator.buffer();
+ }
+
+
+
+ /**
+ * Instantiates a new iterating buffered running length word.
+ * @param bitmap over which we want to iterate
+ *
+ */
+public IteratingBufferedRunningLengthWord(final EWAHCompressedBitmap bitmap) {
+ this.iterator = EWAHIterator.getEWAHIterator(bitmap);
+ this.brlw = new BufferedRunningLengthWord(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords() + this.brlw.literalwordoffset;
+ this.buffer = this.iterator.buffer();
+ }
+
+
+
+
+ /**
+ * Discard first words, iterating to the next running length word if needed.
+ *
+ * @param x the number of words to be discarded
+ */
+ @Override
+public void discardFirstWords(long x) {
+ while (x > 0) {
+ if (this.brlw.RunningLength > x) {
+ this.brlw.RunningLength -= x;
+ return;
+ }
+ x -= this.brlw.RunningLength;
+ this.brlw.RunningLength = 0;
+ long toDiscard = x > this.brlw.NumberOfLiteralWords ? this.brlw.NumberOfLiteralWords : x;
+
+ this.literalWordStartPosition += toDiscard;
+ this.brlw.NumberOfLiteralWords -= toDiscard;
+ x -= toDiscard;
+ if ((x > 0) || (this.brlw.size() == 0)) {
+ if (!this.iterator.hasNext()) {
+ break;
+ }
+ this.brlw.reset(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords(); // + this.brlw.literalwordoffset ==0
+ }
+ }
+ }
+ /**
+ * Move to the next RunningLengthWord
+ * @return whether the move was possible
+ */
+ @Override
+public boolean next() {
+ if (!this.iterator.hasNext()) {
+ this.brlw.NumberOfLiteralWords = 0;
+ this.brlw.RunningLength = 0;
+ return false;
+ }
+ this.brlw.reset(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords(); // + this.brlw.literalwordoffset ==0
+ return true;
+ }
+
+ /**
+ * Write out up to max words, returns how many were written
+ * @param container target for writes
+ * @param max maximal number of writes
+ * @return how many written
+ */
+ public long discharge(BitmapStorage container, long max) {
+ long index = 0;
+ while ((index < max) && (size() > 0)) {
+ // first run
+ long pl = getRunningLength();
+ if (index + pl > max) {
+ pl = max - index;
+ }
+ container.addStreamOfEmptyWords(getRunningBit(), pl);
+ index += pl;
+ int pd = getNumberOfLiteralWords();
+ if (pd + index > max) {
+ pd = (int) (max - index);
+ }
+ writeLiteralWords(pd, container);
+ discardFirstWords(pl+pd);
+ index += pd;
+ }
+ return index;
+ }
+
+ /**
+ * Write out up to max words (negated), returns how many were written
+ * @param container target for writes
+ * @param max maximal number of writes
+ * @return how many written
+ */
+ public long dischargeNegated(BitmapStorage container, long max) {
+ long index = 0;
+ while ((index < max) && (size() > 0)) {
+ // first run
+ long pl = getRunningLength();
+ if (index + pl > max) {
+ pl = max - index;
+ }
+ container.addStreamOfEmptyWords(!getRunningBit(), pl);
+ index += pl;
+ int pd = getNumberOfLiteralWords();
+ if (pd + index > max) {
+ pd = (int) (max - index);
+ }
+ writeNegatedLiteralWords(pd, container);
+ discardFirstWords(pl+pd);
+ index += pd;
+ }
+ return index;
+ }
+
+
+ /**
+ * Write out the remain words, transforming them to zeroes.
+ * @param container target for writes
+ */
+ public void dischargeAsEmpty(BitmapStorage container) {
+ while(size()>0) {
+ container.addStreamOfEmptyWords(false, size());
+ discardFirstWords(size());
+ }
+ }
+
+
+
+ /**
+ * Write out the remaining words
+ * @param container target for writes
+ */
+ public void discharge(BitmapStorage container) {
+ this.brlw.literalwordoffset = this.literalWordStartPosition - this.iterator.literalWords();
+ discharge(this.brlw, this.iterator, container);
+ }
+
+ /**
+ * Get the nth literal word for the current running length word
+ * @param index zero based index
+ * @return the literal word
+ */
+ @Override
+public long getLiteralWordAt(int index) {
+ return this.buffer[this.literalWordStartPosition + index];
+ }
+
+ /**
+ * Gets the number of literal words for the current running length word.
+ *
+ * @return the number of literal words
+ */
+ @Override
+public int getNumberOfLiteralWords() {
+ return this.brlw.NumberOfLiteralWords;
+ }
+
+ /**
+ * Gets the running bit.
+ *
+ * @return the running bit
+ */
+ @Override
+public boolean getRunningBit() {
+ return this.brlw.RunningBit;
+ }
+
+ /**
+ * Gets the running length.
+ *
+ * @return the running length
+ */
+ @Override
+public long getRunningLength() {
+ return this.brlw.RunningLength;
+ }
+
+ /**
+ * Size in uncompressed words of the current running length word.
+ *
+ * @return the long
+ */
+ @Override
+public long size() {
+ return this.brlw.size();
+ }
+
+ /**
+ * write the first N literal words to the target bitmap. Does not discard the words or perform iteration.
+ * @param numWords number of words to be written
+ * @param container where we write
+ */
+ public void writeLiteralWords(int numWords, BitmapStorage container) {
+ container.addStreamOfLiteralWords(this.buffer, this.literalWordStartPosition, numWords);
+ }
+
+ /**
+ * write the first N literal words (negated) to the target bitmap. Does not discard the words or perform iteration.
+ * @param numWords number of words to be written
+ * @param container where we write
+ */
+ public void writeNegatedLiteralWords(int numWords, BitmapStorage container) {
+ container.addStreamOfNegatedLiteralWords(this.buffer, this.literalWordStartPosition, numWords);
+ }
+
+ /**
+ * For internal use. (One could use the non-static discharge method instead,
+ * but we expect them to be slower.)
+ *
+ * @param initialWord
+ * the initial word
+ * @param iterator
+ * the iterator
+ * @param container
+ * the container
+ */
+ private static void discharge(final BufferedRunningLengthWord initialWord,
+ final EWAHIterator iterator, final BitmapStorage container) {
+ BufferedRunningLengthWord runningLengthWord = initialWord;
+ for (;;) {
+ final long runningLength = runningLengthWord.getRunningLength();
+ container.addStreamOfEmptyWords(runningLengthWord.getRunningBit(),
+ runningLength);
+ container.addStreamOfLiteralWords(iterator.buffer(), iterator.literalWords()
+ + runningLengthWord.literalwordoffset,
+ runningLengthWord.getNumberOfLiteralWords());
+ if (!iterator.hasNext())
+ break;
+ runningLengthWord = new BufferedRunningLengthWord(iterator.next());
+ }
+ }
+
+
+ @Override
+ public IteratingBufferedRunningLengthWord clone() throws CloneNotSupportedException {
+ IteratingBufferedRunningLengthWord answer = (IteratingBufferedRunningLengthWord) super.clone();
+ answer.brlw = this.brlw.clone();
+ answer.buffer = this.buffer;
+ answer.iterator = this.iterator.clone();
+ answer.literalWordStartPosition = this.literalWordStartPosition;
+ return answer;
+ }
+
+
+ private BufferedRunningLengthWord brlw;
+ private long[] buffer;
+ private int literalWordStartPosition;
+ private EWAHIterator iterator;
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratingRLW.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratingRLW.java
new file mode 100644
index 000000000..868b93c5e
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratingRLW.java
@@ -0,0 +1,49 @@
+package com.fr.third.googlecode.javaewah;
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * High-level iterator over a compressed bitmap.
+ *
+ */
+public interface IteratingRLW {
+ /**
+ * @return whether there is more
+ */
+ public boolean next() ;
+ /**
+ * @param index where the literal word is
+ * @return the literal word at the given index.
+ */
+ public long getLiteralWordAt(int index);
+ /**
+ * @return the number of literal (non-fill) words
+ */
+ public int getNumberOfLiteralWords() ;
+ /**
+ * @return the bit used for the fill bits
+ */
+ public boolean getRunningBit() ;
+ /**
+ * @return sum of getRunningLength() and getNumberOfLiteralWords()
+ */
+ public long size() ;
+ /**
+ * @return length of the run of fill words
+ */
+ public long getRunningLength() ;
+ /**
+ * @param x the number of words to discard
+ */
+ public void discardFirstWords(long x);
+
+ /**
+ * @return a copy of the iterator
+ * @throws CloneNotSupportedException this should not be thrown in theory
+ */
+ public IteratingRLW clone() throws CloneNotSupportedException;
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratorAggregation.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratorAggregation.java
new file mode 100644
index 000000000..87386625a
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratorAggregation.java
@@ -0,0 +1,616 @@
+package com.fr.third.googlecode.javaewah;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * Set of helper functions to aggregate bitmaps.
+ *
+ */
+public class IteratorAggregation {
+
+ /**
+ * @param x iterator to negate
+ * @return negated version of the iterator
+ */
+ public static IteratingRLW not(final IteratingRLW x) {
+ return new IteratingRLW() {
+
+ @Override
+ public boolean next() {
+ return x.next();
+ }
+
+ @Override
+ public long getLiteralWordAt(int index) {
+ return ~x.getLiteralWordAt(index);
+ }
+
+ @Override
+ public int getNumberOfLiteralWords() {
+ return x.getNumberOfLiteralWords();
+ }
+
+ @Override
+ public boolean getRunningBit() {
+ return ! x.getRunningBit();
+ }
+
+ @Override
+ public long size() {
+ return x.size();
+ }
+
+ @Override
+ public long getRunningLength() {
+ return x.getRunningLength();
+ }
+
+ @Override
+ public void discardFirstWords(long y) {
+ x.discardFirstWords(y);
+ }
+
+ @Override
+ public IteratingRLW clone() throws CloneNotSupportedException {
+ throw new CloneNotSupportedException();
+ }
+
+
+ };
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al set of iterators to aggregate
+ * @return and aggregate
+ */
+ public static IteratingRLW bufferedand(final IteratingRLW... al) {
+ return bufferedand(DEFAULTMAXBUFSIZE,al);
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al set of iterators to aggregate
+ * @param bufsize size of the internal buffer used by the iterator in 64-bit words (per input iterator)
+ * @return and aggregate
+ */
+ public static IteratingRLW bufferedand(final int bufsize, final IteratingRLW... al) {
+ if (al.length == 0)
+ throw new IllegalArgumentException("Need at least one iterator");
+ if (al.length == 1)
+ return al[0];
+ final LinkedList basell = new LinkedList();
+ for (IteratingRLW i : al)
+ basell.add(i);
+ return new BufferedIterator(new BufferedAndIterator(basell,bufsize));
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al set of iterators to aggregate
+ * @return or aggregate
+ */
+ public static IteratingRLW bufferedor(final IteratingRLW... al) {
+ return bufferedor(DEFAULTMAXBUFSIZE,al);
+ }
+
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al iterators to aggregate
+ * @param bufsize size of the internal buffer used by the iterator in 64-bit words
+ * @return or aggregate
+ */
+ public static IteratingRLW bufferedor(final int bufsize, final IteratingRLW... al) {
+ if (al.length == 0)
+ throw new IllegalArgumentException("Need at least one iterator");
+ if (al.length == 1)
+ return al[0];
+
+ final LinkedList basell = new LinkedList();
+ for (IteratingRLW i : al)
+ basell.add(i);
+ return new BufferedIterator(new BufferedORIterator(basell,bufsize));
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al set of iterators to aggregate
+ * @return xor aggregate
+ */
+ public static IteratingRLW bufferedxor(final IteratingRLW... al) {
+ return bufferedxor(DEFAULTMAXBUFSIZE,al);
+ }
+
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al iterators to aggregate
+ * @param bufsize size of the internal buffer used by the iterator in 64-bit words
+ * @return xor aggregate
+ */
+ public static IteratingRLW bufferedxor(final int bufsize, final IteratingRLW... al) {
+ if (al.length == 0)
+ throw new IllegalArgumentException("Need at least one iterator");
+ if (al.length == 1)
+ return al[0];
+
+
+ final LinkedList basell = new LinkedList();
+ for (IteratingRLW i : al)
+ basell.add(i);
+
+ return new BufferedIterator(new BufferedXORIterator(basell, bufsize));
+ }
+
+
+ /**
+ * Write out the content of the iterator, but as if it were all zeros.
+ *
+ * @param container
+ * where we write
+ * @param i
+ * the iterator
+ */
+ protected static void dischargeAsEmpty(final BitmapStorage container,
+ final IteratingRLW i) {
+ while (i.size() > 0) {
+ container.addStreamOfEmptyWords(false, i.size());
+ i.next();
+
+ }
+ }
+
+ /**
+ * Write out up to max words, returns how many were written
+ * @param container target for writes
+ * @param i source of data
+ * @param max maximal number of writes
+ * @return how many written
+ */
+
+ protected static long discharge(final BitmapStorage container, IteratingRLW i, long max) {
+ long counter = 0;
+ while (i.size() > 0 && counter < max) {
+ long L1 = i.getRunningLength();
+ if (L1 > 0) {
+ if (L1 + counter > max)
+ L1 = max - counter;
+ container.addStreamOfEmptyWords(i.getRunningBit(), L1);
+ counter += L1;
+ }
+ long L = i.getNumberOfLiteralWords();
+ if(L + counter > max) L = max - counter;
+ for (int k = 0; k < L; ++k) {
+ container.add(i.getLiteralWordAt(k));
+ }
+ counter += L;
+ i.discardFirstWords(L+L1);
+ }
+ return counter;
+ }
+
+
+ /**
+ * Write out up to max negated words, returns how many were written
+ * @param container target for writes
+ * @param i source of data
+ * @param max maximal number of writes
+ * @return how many written
+ */
+ protected static long dischargeNegated(final BitmapStorage container, IteratingRLW i, long max) {
+ long counter = 0;
+ while (i.size() > 0 && counter < max) {
+ long L1 = i.getRunningLength();
+ if (L1 > 0) {
+ if (L1 + counter > max)
+ L1 = max - counter;
+ container.addStreamOfEmptyWords(!i.getRunningBit(), L1);
+ counter += L1;
+ }
+ long L = i.getNumberOfLiteralWords();
+ if(L + counter > max) L = max - counter;
+ for (int k = 0; k < L; ++k) {
+ container.add(~i.getLiteralWordAt(k));
+ }
+ counter += L;
+ i.discardFirstWords(L+L1);
+ }
+ return counter;
+ }
+
+ static void andToContainer(final BitmapStorage container,
+ int desiredrlwcount, final IteratingRLW rlwi, IteratingRLW rlwj) {
+ while ((rlwi.size()>0) && (rlwj.size()>0) && (desiredrlwcount-- >0) ) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingRLW prey = i_is_prey ? rlwi : rlwj;
+ final IteratingRLW predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ container.addStreamOfEmptyWords(false, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ final long index = discharge(container, prey, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ desiredrlwcount -= nbre_literal;
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) & rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ }
+
+ static void andToContainer(final BitmapStorage container,
+ final IteratingRLW rlwi, IteratingRLW rlwj) {
+ while ((rlwi.size()>0) && (rlwj.size()>0) ) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingRLW prey = i_is_prey ? rlwi : rlwj;
+ final IteratingRLW predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ container.addStreamOfEmptyWords(false, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ final long index = discharge(container, prey, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) & rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ }
+
+
+ /**
+ * Compute the first few words of the XOR aggregate between two iterators.
+ *
+ * @param container where to write
+ * @param desiredrlwcount number of words to be written (max)
+ * @param rlwi first iterator to aggregate
+ * @param rlwj second iterator to aggregate
+ */
+ public static void xorToContainer(final BitmapStorage container,
+ int desiredrlwcount, final IteratingRLW rlwi, final IteratingRLW rlwj) {
+ while ((rlwi.size()>0) && (rlwj.size()>0) && (desiredrlwcount-- >0) ) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingRLW prey = i_is_prey ? rlwi : rlwj;
+ final IteratingRLW predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ long index = discharge(container, prey, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ long index = dischargeNegated(container, prey, predator.getRunningLength());
+ container.addStreamOfEmptyWords(true, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ desiredrlwcount -= nbre_literal;
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) ^ rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ }
+
+ protected static int inplaceor(long[] bitmap,
+ IteratingRLW i) {
+
+ int pos = 0;
+ long s;
+ while ((s = i.size()) > 0) {
+ if (pos + s < bitmap.length) {
+ final int L = (int) i.getRunningLength();
+ if (i.getRunningBit())
+ Arrays.fill(bitmap, pos, pos + L, ~0l);
+ pos += L;
+ final int LR = i.getNumberOfLiteralWords();
+
+ for (int k = 0; k < LR; ++k)
+ bitmap[pos++] |= i.getLiteralWordAt(k);
+ if (!i.next()) {
+ return pos;
+ }
+ } else {
+ int howmany = bitmap.length - pos;
+ int L = (int) i.getRunningLength();
+
+ if (pos + L > bitmap.length) {
+ if (i.getRunningBit()) {
+ Arrays.fill(bitmap, pos, bitmap.length, ~0l);
+ }
+ i.discardFirstWords(howmany);
+ return bitmap.length;
+ }
+ if (i.getRunningBit())
+ Arrays.fill(bitmap, pos, pos + L, ~0l);
+ pos += L;
+ for (int k = 0; pos < bitmap.length; ++k)
+ bitmap[pos++] |= i.getLiteralWordAt(k);
+ i.discardFirstWords(howmany);
+ return pos;
+ }
+ }
+ return pos;
+ }
+
+ protected static int inplacexor(long[] bitmap,
+ IteratingRLW i) {
+ int pos = 0;
+ long s;
+ while ((s = i.size()) > 0) {
+ if (pos + s < bitmap.length) {
+ final int L = (int) i.getRunningLength();
+ if (i.getRunningBit()) {
+ for(int k = pos ; k < pos + L; ++k)
+ bitmap[k] = ~bitmap[k];
+ }
+ pos += L;
+ final int LR = i.getNumberOfLiteralWords();
+ for (int k = 0; k < LR; ++k)
+ bitmap[pos++] ^= i.getLiteralWordAt(k);
+ if (!i.next()) {
+ return pos;
+ }
+ } else {
+ int howmany = bitmap.length - pos;
+ int L = (int) i.getRunningLength();
+ if (pos + L > bitmap.length) {
+ if (i.getRunningBit()) {
+ for(int k = pos ; k < bitmap.length; ++k)
+ bitmap[k] = ~bitmap[k];
+ }
+ i.discardFirstWords(howmany);
+ return bitmap.length;
+ }
+ if (i.getRunningBit())
+ for(int k = pos ; k < pos + L; ++k)
+ bitmap[k] = ~bitmap[k];
+ pos += L;
+ for (int k = 0; pos < bitmap.length; ++k)
+ bitmap[pos++] ^= i.getLiteralWordAt(k);
+ i.discardFirstWords(howmany);
+ return pos;
+ }
+ }
+ return pos;
+ }
+ protected static int inplaceand(long[] bitmap,
+ IteratingRLW i) {
+ int pos = 0;
+ long s;
+ while ((s = i.size()) > 0) {
+ if (pos + s < bitmap.length) {
+ final int L = (int) i.getRunningLength();
+ if (!i.getRunningBit()) {
+ for(int k = pos ; k < pos + L; ++k)
+ bitmap[k] = 0;
+ }
+ pos += L;
+ final int LR = i.getNumberOfLiteralWords();
+ for (int k = 0; k < LR; ++k)
+ bitmap[pos++] &= i.getLiteralWordAt(k);
+ if (!i.next()) {
+ return pos;
+ }
+ } else {
+ int howmany = bitmap.length - pos;
+ int L = (int) i.getRunningLength();
+ if (pos + L > bitmap.length) {
+ if (!i.getRunningBit()) {
+ for(int k = pos ; k < bitmap.length; ++k)
+ bitmap[k] = 0;
+ }
+ i.discardFirstWords(howmany);
+ return bitmap.length;
+ }
+ if (!i.getRunningBit())
+ for(int k = pos ; k < pos + L; ++k)
+ bitmap[k] = 0;
+ pos += L;
+ for (int k = 0; pos < bitmap.length; ++k)
+ bitmap[pos++] &= i.getLiteralWordAt(k);
+ i.discardFirstWords(howmany);
+ return pos;
+ }
+ }
+ return pos;
+ }
+
+ /**
+ * An optimization option. Larger values may improve speed, but at
+ * the expense of memory.
+ */
+ public final static int DEFAULTMAXBUFSIZE = 65536;
+}
+class BufferedORIterator implements CloneableIterator {
+ EWAHCompressedBitmap buffer = new EWAHCompressedBitmap();
+ long[] hardbitmap;
+ LinkedList ll;
+ int buffersize;
+
+ BufferedORIterator(LinkedList basell, int bufsize) {
+ this.ll = basell;
+ this.hardbitmap = new long[bufsize];
+ }
+
+ @Override
+ public BufferedXORIterator clone() throws CloneNotSupportedException {
+ BufferedXORIterator answer = (BufferedXORIterator) super.clone();
+ answer.buffer = this.buffer.clone();
+ answer.hardbitmap = this.hardbitmap.clone();
+ answer.ll = (LinkedList) this.ll.clone();
+ return answer;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !this.ll.isEmpty();
+ }
+
+ @Override
+ public EWAHIterator next() {
+ this.buffer.clear();
+ long effective = 0;
+ Iterator i = this.ll.iterator();
+ while (i.hasNext()) {
+ IteratingRLW rlw = i.next();
+ if (rlw.size() > 0) {
+ int eff = IteratorAggregation.inplaceor(this.hardbitmap, rlw);
+ if (eff > effective)
+ effective = eff;
+ } else
+ i.remove();
+ }
+ for (int k = 0; k < effective; ++k) {
+ this.buffer.add(this.hardbitmap[k]);
+ }
+
+ Arrays.fill(this.hardbitmap, 0);
+ return this.buffer.getEWAHIterator();
+ }
+}
+
+class BufferedXORIterator implements CloneableIterator {
+ EWAHCompressedBitmap buffer = new EWAHCompressedBitmap();
+ long[] hardbitmap;
+ LinkedList ll;
+ int buffersize;
+
+ BufferedXORIterator(LinkedList basell, int bufsize) {
+ this.ll = basell;
+ this.hardbitmap = new long[bufsize];
+ }
+
+ @Override
+ public BufferedXORIterator clone() throws CloneNotSupportedException {
+ BufferedXORIterator answer = (BufferedXORIterator) super.clone();
+ answer.buffer = this.buffer.clone();
+ answer.hardbitmap = this.hardbitmap.clone();
+ answer.ll = (LinkedList) this.ll.clone();
+ return answer;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !this.ll.isEmpty();
+ }
+
+ @Override
+ public EWAHIterator next() {
+ this.buffer.clear();
+ long effective = 0;
+ Iterator i = this.ll.iterator();
+ while (i.hasNext()) {
+ IteratingRLW rlw = i.next();
+ if (rlw.size() > 0) {
+ int eff = IteratorAggregation.inplacexor(this.hardbitmap, rlw);
+ if (eff > effective)
+ effective = eff;
+ } else
+ i.remove();
+ }
+ for (int k = 0; k < effective; ++k)
+ this.buffer.add(this.hardbitmap[k]);
+ Arrays.fill(this.hardbitmap, 0);
+ return this.buffer.getEWAHIterator();
+ }
+}
+
+
+class BufferedAndIterator implements CloneableIterator {
+ EWAHCompressedBitmap buffer = new EWAHCompressedBitmap();
+ LinkedList ll;
+ int buffersize;
+
+ public BufferedAndIterator(LinkedList basell, int bufsize) {
+ this.ll = basell;
+ this.buffersize = bufsize;
+
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !this.ll.isEmpty();
+ }
+
+ @Override
+ public BufferedAndIterator clone() throws CloneNotSupportedException {
+ BufferedAndIterator answer = (BufferedAndIterator) super.clone();
+ answer.buffer = this.buffer.clone();
+ answer.ll = (LinkedList) this.ll.clone();
+ return answer;
+ }
+
+ @Override
+ public EWAHIterator next() {
+ this.buffer.clear();
+ IteratorAggregation.andToContainer(this.buffer, this.buffersize * this.ll.size(),
+ this.ll.get(0), this.ll.get(1));
+ if (this.ll.size() > 2) {
+ Iterator i = this.ll.iterator();
+ i.next();
+ i.next();
+ EWAHCompressedBitmap tmpbuffer = new EWAHCompressedBitmap();
+ while (i.hasNext() && this.buffer.sizeInBytes() > 0) {
+ IteratorAggregation.andToContainer(tmpbuffer,
+ this.buffer.getIteratingRLW(), i.next());
+ this.buffer.swap(tmpbuffer);
+ tmpbuffer.clear();
+ }
+ }
+ Iterator i = this.ll.iterator();
+ while(i.hasNext()) {
+ if(i.next().size() == 0) {
+ this.ll.clear();
+ break;
+ }
+ }
+ return this.buffer.getEWAHIterator();
+ }
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratorUtil.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratorUtil.java
new file mode 100644
index 000000000..628ae46a8
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/IteratorUtil.java
@@ -0,0 +1,132 @@
+package com.fr.third.googlecode.javaewah;
+
+import java.util.Iterator;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * Convenience functions for working over iterators
+ *
+ */
+public class IteratorUtil {
+
+ /**
+ * @param i iterator we wish to iterate over
+ * @return an iterator over the set bits corresponding to the iterator
+ */
+ public static IntIterator toSetBitsIntIterator(final IteratingRLW i) {
+ return new IntIteratorOverIteratingRLW(i);
+ }
+
+ /**
+ * @param i iterator we wish to iterate over
+ * @return an iterator over the set bits corresponding to the iterator
+ */
+ public static Iterator toSetBitsIterator(final IteratingRLW i) {
+ return new Iterator() {
+ @Override
+ public boolean hasNext() {
+ return this.under.hasNext();
+ }
+
+ @Override
+ public Integer next() {
+ return new Integer(this.under.next());
+ }
+
+ @Override
+ public void remove() {
+ }
+
+ final private IntIterator under = toSetBitsIntIterator(i);
+ };
+
+ }
+
+ /**
+ * Generate a bitmap from an iterator
+ *
+ * @param i iterator we wish to materialize
+ * @param c where we write
+ */
+ public static void materialize(final IteratingRLW i, final BitmapStorage c) {
+ while (true) {
+ if (i.getRunningLength() > 0) {
+ c.addStreamOfEmptyWords(i.getRunningBit(), i.getRunningLength());
+ }
+ for (int k = 0; k < i.getNumberOfLiteralWords(); ++k)
+ c.add(i.getLiteralWordAt(k));
+ if (!i.next())
+ break;
+ }
+ }
+
+ /**
+ * @param i iterator we wish to iterate over
+ * @return the cardinality (number of set bits) corresponding to the iterator
+ */
+ public static int cardinality(final IteratingRLW i) {
+ int answer = 0;
+ while (true) {
+ if(i.getRunningBit()) answer += i.getRunningLength() * EWAHCompressedBitmap.wordinbits;
+ for (int k = 0; k < i.getNumberOfLiteralWords(); ++k)
+ answer += Long.bitCount(i.getLiteralWordAt(k));
+ if(!i.next()) break;
+ }
+ return answer;
+ }
+
+ /**
+ * @param x set of bitmaps
+ * @return an array of iterators corresponding to the array of bitmaps
+ */
+ public static IteratingRLW[] toIterators(final EWAHCompressedBitmap... x) {
+ IteratingRLW[] X = new IteratingRLW[x.length];
+ for (int k = 0; k < X.length; ++k) {
+ X[k] = new IteratingBufferedRunningLengthWord(x[k]);
+ }
+ return X;
+ }
+ /**
+ * Turn an iterator into a bitmap.
+ *
+ * @param i iterator we wish to materialize
+ * @param c where we write
+ * @param Max maximum number of words we wish to materialize
+ * @return how many words were actually materialized
+ */
+ public static long materialize(final IteratingRLW i, final BitmapStorage c, long Max) {
+ final long origMax = Max;
+ while (true) {
+ if (i.getRunningLength() > 0) {
+ long L = i.getRunningLength();
+ if(L > Max) L = Max;
+ c.addStreamOfEmptyWords(i.getRunningBit(), L);
+ Max -= L;
+ }
+ long L = i.getNumberOfLiteralWords();
+ for (int k = 0; k < L; ++k)
+ c.add(i.getLiteralWordAt(k));
+ if(Max>0) {
+ if (!i.next())
+ break;
+ }
+ else break;
+ }
+ return origMax - Max;
+ }
+ /**
+ * Turn an iterator into a bitmap
+ *
+ * @param i iterator we wish to materialize
+ * @return materialized version of the iterator
+ */
+ public static EWAHCompressedBitmap materialize(final IteratingRLW i) {
+ EWAHCompressedBitmap ewah = new EWAHCompressedBitmap();
+ materialize(i, ewah);
+ return ewah;
+ }
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/LogicalElement.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/LogicalElement.java
new file mode 100644
index 000000000..b6300410c
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/LogicalElement.java
@@ -0,0 +1,61 @@
+package com.fr.third.googlecode.javaewah;
+
+/**
+ * A prototypical model for bitmaps. Used by the
+ * class FastAggregation. Users should probably not
+ * be concerned by this class.
+ *
+ * @author Daniel Lemire
+ * @param the type of element (e.g., a bitmap class)
+ *
+ */
+public interface LogicalElement {
+ /**
+ * Compute the bitwise logical and
+ * @param le element
+ * @return the result of the operation
+ */
+ public T and(T le);
+
+ /**
+ * Compute the bitwise logical and not
+ * @param le element
+ * @return the result of the operation
+ */
+ public T andNot(T le);
+
+ /**
+ * Compute the bitwise logical not (in place)
+ */
+ public void not();
+
+
+ @SuppressWarnings({ "rawtypes", "javadoc" })
+ /**
+ * Compute the bitwise logical or
+ * @param le another element
+ * @return the result of the operation
+ */
+ public LogicalElement or(T le);
+
+ /**
+ * How many logical bits does this element represent?
+ *
+ * @return the number of bits represented by this element
+ */
+ public int sizeInBits();
+
+ /**
+ * Should report the storage requirement
+ * @return How many bytes
+ * @since 0.6.2
+ */
+ public int sizeInBytes();
+
+ /**
+ * Compute the bitwise logical Xor
+ * @param le element
+ * @return the results of the operation
+ */
+ public T xor(T le);
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/NonEmptyVirtualStorage.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/NonEmptyVirtualStorage.java
new file mode 100644
index 000000000..96ea6cfea
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/NonEmptyVirtualStorage.java
@@ -0,0 +1,92 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * This is a BitmapStorage that can be used to determine quickly if the result
+ * of an operation is non-trivial... that is, whether there will be at least on
+ * set bit.
+ *
+ * @since 0.4.2
+ * @author Daniel Lemire and Veronika Zenz
+ *
+ */
+public class NonEmptyVirtualStorage implements BitmapStorage {
+ static class NonEmptyException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Do not fill in the stack trace for this exception
+ * for performance reasons.
+ *
+ * @return this instance
+ * @see Throwable#fillInStackTrace()
+ */
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ return this;
+ }
+ }
+
+ private static final NonEmptyException nonEmptyException = new NonEmptyException();
+
+ /**
+ * If the word to be added is non-zero, a NonEmptyException exception is
+ * thrown.
+ *
+ * @see com.googlecode.javaewah.BitmapStorage#add(long)
+ */
+ @Override
+public void add(long newdata) {
+ if (newdata != 0)
+ throw nonEmptyException;
+ return;
+ }
+
+ /**
+ * throws a NonEmptyException exception when number is greater than 0
+ *
+ */
+ @Override
+public void addStreamOfLiteralWords(long[] data, int start, int number) {
+ if(number>0){
+ throw nonEmptyException;
+ }
+ }
+
+ /**
+ * If the boolean value is true and number is greater than 0, then it throws a NonEmptyException exception,
+ * otherwise, nothing happens.
+ *
+ * @see com.googlecode.javaewah.BitmapStorage#addStreamOfEmptyWords(boolean, long)
+ */
+ @Override
+public void addStreamOfEmptyWords(boolean v, long number) {
+ if (v && (number>0))
+ throw nonEmptyException;
+ return;
+ }
+
+ /**
+ * throws a NonEmptyException exception when number is greater than 0
+ *
+ */
+ @Override
+public void addStreamOfNegatedLiteralWords(long[] data, int start, int number) {
+ if(number>0){
+ throw nonEmptyException;
+ }
+ }
+
+ /**
+ * Does nothing.
+ *
+ * @see com.googlecode.javaewah.BitmapStorage#setSizeInBits(int)
+ */
+ @Override
+public void setSizeInBits(int bits) {
+ }
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/RunningLengthWord.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/RunningLengthWord.java
new file mode 100644
index 000000000..969a78c48
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/RunningLengthWord.java
@@ -0,0 +1,152 @@
+package com.fr.third.googlecode.javaewah;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * Mostly for internal use.
+ *
+ * @since 0.1.0
+ * @author Daniel Lemire
+ */
+public final class RunningLengthWord implements Cloneable {
+
+ /**
+ * Instantiates a new running length word.
+ *
+ * @param a
+ * an array of 64-bit words
+ * @param p
+ * position in the array where the running length word is
+ * located.
+ */
+ RunningLengthWord(final EWAHCompressedBitmap a, final int p) {
+ this.parent = a;
+ this.position = p;
+ }
+
+ /**
+ * Gets the number of literal words.
+ *
+ * @return the number of literal words
+ */
+ public int getNumberOfLiteralWords() {
+ return (int) (this.parent.buffer[this.position] >>> (1 + runninglengthbits));
+ }
+
+ /**
+ * Gets the running bit.
+ *
+ * @return the running bit
+ */
+ public boolean getRunningBit() {
+ return (this.parent.buffer[this.position] & 1) != 0;
+ }
+
+ /**
+ * Gets the running length.
+ *
+ * @return the running length
+ */
+ public long getRunningLength() {
+ return (this.parent.buffer[this.position] >>> 1)
+ & largestrunninglengthcount;
+ }
+
+ /**
+ * Sets the number of literal words.
+ *
+ * @param number
+ * the new number of literal words
+ */
+ public void setNumberOfLiteralWords(final long number) {
+ this.parent.buffer[this.position] |= notrunninglengthplusrunningbit;
+ this.parent.buffer[this.position] &= (number << (runninglengthbits + 1))
+ | runninglengthplusrunningbit;
+ }
+
+ /**
+ * Sets the running bit.
+ *
+ * @param b
+ * the new running bit
+ */
+ public void setRunningBit(final boolean b) {
+ if (b)
+ this.parent.buffer[this.position] |= 1l;
+ else
+ this.parent.buffer[this.position] &= ~1l;
+ }
+
+ /**
+ * Sets the running length.
+ *
+ * @param number
+ * the new running length
+ */
+ public void setRunningLength(final long number) {
+ this.parent.buffer[this.position] |= shiftedlargestrunninglengthcount;
+ this.parent.buffer[this.position] &= (number << 1)
+ | notshiftedlargestrunninglengthcount;
+ }
+
+ /**
+ * Return the size in uncompressed words represented by this running
+ * length word.
+ *
+ * @return the size
+ */
+ public long size() {
+ return getRunningLength() + getNumberOfLiteralWords();
+ }
+
+ /*
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "running bit = " + getRunningBit()
+ + " running length = " + getRunningLength()
+ + " number of lit. words " + getNumberOfLiteralWords();
+ }
+
+ @Override
+ public RunningLengthWord clone() throws CloneNotSupportedException {
+ RunningLengthWord answer;
+ answer = (RunningLengthWord) super.clone();
+ answer.parent = this.parent;
+ answer.position = this.position;
+ return answer;
+ }
+
+ /** The array of words. */
+ public EWAHCompressedBitmap parent;
+
+ /** The position in array. */
+ public int position;
+
+ /**
+ * number of bits dedicated to marking of the running length of clean
+ * words
+ */
+ public static final int runninglengthbits = 32;
+
+ private static final int literalbits = 64 - 1 - runninglengthbits;
+
+ /** largest number of literal words in a run. */
+ public static final int largestliteralcount = (1 << literalbits) - 1;
+
+ /** largest number of clean words in a run */
+ public static final long largestrunninglengthcount = (1l << runninglengthbits) - 1;
+
+ private static final long runninglengthplusrunningbit = (1l << (runninglengthbits + 1)) - 1;
+
+ private static final long shiftedlargestrunninglengthcount = largestrunninglengthcount << 1;
+
+ private static final long notrunninglengthplusrunningbit = ~runninglengthplusrunningbit;
+
+ private static final long notshiftedlargestrunninglengthcount = ~shiftedlargestrunninglengthcount;
+
+}
\ No newline at end of file
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/Benchmark.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/Benchmark.java
new file mode 100644
index 000000000..e2ffb8fe4
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/Benchmark.java
@@ -0,0 +1,284 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+import java.text.DecimalFormat;
+import java.util.Arrays;
+import java.util.List;
+import com.fr.third.googlecode.javaewah.EWAHCompressedBitmap;
+import com.fr.third.googlecode.javaewah.FastAggregation;
+import com.fr.third.googlecode.javaewah.IntIterator;
+import com.fr.third.googlecode.javaewah.IteratingRLW;
+import com.fr.third.googlecode.javaewah.IteratorAggregation;
+import com.fr.third.googlecode.javaewah.IteratorUtil;
+
+/**
+ * This class is used to benchmark the performance EWAH.
+ *
+ * @author Daniel Lemire
+ */
+public class Benchmark {
+
+ /**
+ * Compute the union between two sorted arrays
+ * @param set1 first sorted array
+ * @param set2 second sorted array
+ * @return merged array
+ */
+ static public int[] unite2by2(final int[] set1, final int[] set2) {
+ int pos = 0;
+ int k1 = 0, k2 = 0;
+ if (0 == set1.length)
+ return Arrays.copyOf(set2, set2.length);
+ if (0 == set2.length)
+ return Arrays.copyOf(set1, set1.length);
+ int[] buffer = new int[set1.length + set2.length];
+ while (true) {
+ if (set1[k1] < set2[k2]) {
+ buffer[pos++] = set1[k1];
+ ++k1;
+ if (k1 >= set1.length) {
+ for (; k2 < set2.length; ++k2)
+ buffer[pos++] = set2[k2];
+ break;
+ }
+ } else if (set1[k1] == set2[k2]) {
+ buffer[pos++] = set1[k1];
+ ++k1;
+ ++k2;
+ if (k1 >= set1.length) {
+ for (; k2 < set2.length; ++k2)
+ buffer[pos++] = set2[k2];
+ break;
+ }
+ if (k2 >= set2.length) {
+ for (; k1 < set1.length; ++k1)
+ buffer[pos++] = set1[k1];
+ break;
+ }
+ } else {// if (set1[k1]>set2[k2]) {
+ buffer[pos++] = set2[k2];
+ ++k2;
+ if (k2 >= set2.length) {
+ for (; k1 < set1.length; ++k1)
+ buffer[pos++] = set1[k1];
+ break;
+ }
+ }
+ }
+ return Arrays.copyOf(buffer, pos);
+ }
+
+
+ @SuppressWarnings("javadoc")
+ public static void main(String args[]) {
+ //test(2, 24, 1);
+ test(100, 16, 1);
+ }
+
+ @SuppressWarnings("javadoc")
+ public static void test(int N, int nbr, int repeat) {
+ DecimalFormat df = new DecimalFormat("0.###");
+ ClusteredDataGenerator cdg = new ClusteredDataGenerator();
+ for (int sparsity = 1; sparsity < 30 - nbr; sparsity += 2) {
+ long bogus = 0;
+ String line = "";
+ long bef, aft;
+ line += sparsity;
+ int[][] data = new int[N][];
+ int Max = (1 << (nbr + sparsity));
+ System.out.println("# generating random data...");
+ int[] inter = cdg.generateClustered(1 << (nbr/2), Max);
+ for (int k = 0; k < N; ++k)
+ data[k] = unite2by2(cdg.generateClustered(1 << nbr, Max),inter);
+ System.out.println("# generating random data... ok.");
+ // building
+ bef = System.currentTimeMillis();
+ EWAHCompressedBitmap[] ewah = new EWAHCompressedBitmap[N];
+ int size = 0;
+ for (int r = 0; r < repeat; ++r) {
+ size = 0;
+ for (int k = 0; k < N; ++k) {
+ ewah[k] = new EWAHCompressedBitmap();
+ for (int x = 0; x < data[k].length; ++x) {
+ ewah[k].set(data[k][x]);
+ }
+ size += ewah[k].sizeInBytes();
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + size;
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // uncompressing
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ int[] array = ewah[k].toArray();
+ bogus += array.length;
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // uncompressing
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ int[] array = new int[ewah[k].cardinality()];
+ int c = 0;
+ for (int x : ewah[k])
+ array[c++] = x;
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // uncompressing
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ List L = ewah[k].getPositions();
+ int[] array = new int[L.size()];
+ int c = 0;
+ for (int x : L)
+ array[c++] = x;
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // uncompressing
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IntIterator iter = ewah[k].intIterator();
+ while (iter.hasNext()) {
+ bogus += iter.next();
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ line += "\t\t\t";
+ // logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap ewahor = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahor = ewahor.or(ewah[j]);
+ }
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = EWAHCompressedBitmap
+ .or(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = FastAggregation.or(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ // run sanity check
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW[] ewahcp = new IteratingRLW[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j].getIteratingRLW();
+ }
+ IteratingRLW ewahor = IteratorAggregation.bufferedor(ewahcp);
+ EWAHCompressedBitmap ewahorp = EWAHCompressedBitmap.or(Arrays.copyOf(ewah, k+1));
+ EWAHCompressedBitmap mewahor = IteratorUtil.materialize(ewahor);
+ if(!ewahorp.equals(mewahor)) throw new RuntimeException("bug");
+ }
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW[] ewahcp = new IteratingRLW[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j].getIteratingRLW();
+ }
+ IteratingRLW ewahor = IteratorAggregation.bufferedor(ewahcp);
+ bogus += IteratorUtil.materialize(ewahor).sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ line += "\t\t\t";
+ // logical and
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap ewahand = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahand = ewahand.and(ewah[j]);
+ }
+ bogus += ewahand.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical and
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahand = EWAHCompressedBitmap
+ .and(ewahcp);
+ bogus += ewahand.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW[] ewahcp = new IteratingRLW[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j].getIteratingRLW();
+ }
+ IteratingRLW ewahand = IteratorAggregation.bufferedand(ewahcp);
+ EWAHCompressedBitmap ewahandp = EWAHCompressedBitmap.and(Arrays.copyOf(ewah, k+1));
+ EWAHCompressedBitmap mewahand = IteratorUtil.materialize(ewahand);
+ if(!ewahandp.equals(mewahand)) throw new RuntimeException("bug");
+ }
+ // fast logical and
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW[] ewahcp = new IteratingRLW[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j].getIteratingRLW();
+ }
+ IteratingRLW ewahand = IteratorAggregation.bufferedand(ewahcp);
+ bogus += IteratorUtil.materialize(ewahand).sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ System.out
+ .println("time for building, toArray(), Java iterator, intIterator,\t\t\t logical or (2-by-2), logical or (grouped), FastAggregation.or, iterator-based or, \t\t\t (2-by-2) and, logical and (grouped), iterator-based and");
+ System.out.println(line);
+ System.out.println("# bogus =" + bogus);
+ }
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/Benchmark32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/Benchmark32.java
new file mode 100644
index 000000000..b221b911c
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/Benchmark32.java
@@ -0,0 +1,212 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+import java.text.DecimalFormat;
+import java.util.List;
+import com.fr.third.googlecode.javaewah32.EWAHCompressedBitmap32;
+import com.fr.third.googlecode.javaewah.FastAggregation;
+import com.fr.third.googlecode.javaewah.IntIterator;
+import com.fr.third.googlecode.javaewah32.IteratingRLW32;
+import com.fr.third.googlecode.javaewah32.IteratorAggregation32;
+import com.fr.third.googlecode.javaewah32.IteratorUtil32;
+
+/**
+ * This class is used to benchmark the performance EWAH.
+ *
+ * @author Daniel Lemire
+ */
+public class Benchmark32 {
+
+ @SuppressWarnings("javadoc")
+ public static void main(String args[]) {
+ test(100, 16, 1);
+// test(2, 24, 1);
+ }
+
+ @SuppressWarnings("javadoc")
+ public static void test(int N, int nbr, int repeat) {
+ DecimalFormat df = new DecimalFormat("0.###");
+ ClusteredDataGenerator cdg = new ClusteredDataGenerator();
+ for (int sparsity = 1; sparsity < 30 - nbr; sparsity += 2) {
+ long bogus = 0;
+ String line = "";
+ long bef, aft;
+ line += sparsity;
+ int[][] data = new int[N][];
+ int Max = (1 << (nbr + sparsity));
+ System.out.println("# generating random data...");
+ int[] inter = cdg.generateClustered(1 << (nbr/2), Max);
+ for (int k = 0; k < N; ++k)
+ data[k] = Benchmark.unite2by2(cdg.generateClustered(1 << nbr, Max),inter);
+ System.out.println("# generating random data... ok.");
+ // building
+ bef = System.currentTimeMillis();
+ EWAHCompressedBitmap32[] ewah = new EWAHCompressedBitmap32[N];
+ int size = 0;
+ for (int r = 0; r < repeat; ++r) {
+ size = 0;
+ for (int k = 0; k < N; ++k) {
+ ewah[k] = new EWAHCompressedBitmap32();
+ for (int x = 0; x < data[k].length; ++x) {
+ ewah[k].set(data[k][x]);
+ }
+ size += ewah[k].sizeInBytes();
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + size;
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // uncompressing
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ int[] array = ewah[k].toArray();
+ bogus += array.length;
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // uncompressing
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ int[] array = new int[ewah[k].cardinality()];
+ int c = 0;
+ for (int x : ewah[k])
+ array[c++] = x;
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // uncompressing
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ List L = ewah[k].getPositions();
+ int[] array = new int[L.size()];
+ int c = 0;
+ for (int x : L)
+ array[c++] = x;
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // uncompressing
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IntIterator iter = ewah[k].intIterator();
+ while (iter.hasNext()) {
+ bogus += iter.next();
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ line += "\t\t\t";
+ // logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32 ewahor = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahor = ewahor.or(ewah[j]);
+ }
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = EWAHCompressedBitmap32
+ .or(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = FastAggregation.or(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW32[] ewahcp = new IteratingRLW32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j].getIteratingRLW();
+ }
+ IteratingRLW32 ewahor = IteratorAggregation32.bufferedor(ewahcp);
+ bogus += IteratorUtil32.materialize(ewahor).sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ line += "\t\t\t";
+ // logical and
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32 ewahand = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahand = ewahand.and(ewah[j]);
+ }
+ bogus += ewahand.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical and
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahand = EWAHCompressedBitmap32
+ .and(ewahcp);
+ bogus += ewahand.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ // fast logical and
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW32[] ewahcp = new IteratingRLW32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j].getIteratingRLW();
+ }
+ IteratingRLW32 ewahand = IteratorAggregation32.bufferedand(ewahcp);
+ bogus += IteratorUtil32.materialize(ewahand).sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ System.out
+ .println("time for building, toArray(), Java iterator, intIterator,\t\t\t logical or (2-by-2), logical or (grouped), FastAggregation.or, iterator-based or, \t\t\t (2-by-2) and, logical and (grouped), iterator-based and");
+ System.out.println(line);
+ System.out.println("# bogus =" + bogus);
+ }
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkIntersection.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkIntersection.java
new file mode 100644
index 000000000..943c76bc6
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkIntersection.java
@@ -0,0 +1,130 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+import java.text.DecimalFormat;
+import com.fr.third.googlecode.javaewah.*;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * To benchmark the logical and (intersection) aggregate.
+ */
+public class BenchmarkIntersection {
+
+ @SuppressWarnings("javadoc")
+ public static void main(String args[]) {
+ test(10, 18, 1);
+ }
+
+ @SuppressWarnings({ "javadoc"})
+ public static void test(int N, int nbr, int repeat) {
+ long bogus = 0;
+
+ DecimalFormat df = new DecimalFormat("0.###");
+ ClusteredDataGenerator cdg = new ClusteredDataGenerator();
+ for (int sparsity = 1; sparsity < 30 - nbr; sparsity++) {
+ for (int times = 0; times < 2; ++times) {
+ String line = "";
+ long bef, aft;
+ line += sparsity;
+ int[][] data = new int[N][];
+ int Max = (1 << (nbr + sparsity));
+ int[] inter = cdg.generateClustered(1 << (nbr/2), Max);
+ for (int k = 0; k < N; ++k)
+ data[k] = Benchmark.unite2by2(cdg.generateClustered(1 << nbr, Max),inter);
+ // building
+ EWAHCompressedBitmap[] ewah = new EWAHCompressedBitmap[N];
+ for (int k = 0; k < N; ++k) {
+ ewah[k] = new EWAHCompressedBitmap();
+ for (int x = 0; x < data[k].length; ++x) {
+ ewah[k].set(data[k][x]);
+ }
+ data[k] = null;
+ }
+ // sanity check
+ if (true) {
+ EWAHCompressedBitmap answer = ewah[0].and(ewah[1]);
+ for (int k = 2; k < ewah.length; ++k)
+ answer = answer.and(ewah[k]);
+
+ EWAHCompressedBitmap ewahand = EWAHCompressedBitmap.and(ewah);
+ if (!answer.equals(ewahand))
+ throw new RuntimeException(
+ "bug EWAHCompressedBitmap.and");
+ EWAHCompressedBitmap ewahand2 = FastAggregation
+ .bufferedand(65536,ewah);
+ if (!ewahand.equals(ewahand2))
+ throw new RuntimeException(
+ "bug FastAggregation.bufferedand ");
+
+ }
+
+ // logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap ewahor = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahor = ewahor.and(ewah[j]);
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = EWAHCompressedBitmap
+ .and(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = FastAggregation
+ .bufferedand(65536,ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW[] ewahcp = new IteratingRLW[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = new IteratingBufferedRunningLengthWord(
+ ewah[j]);
+ }
+ IteratingRLW ewahor = IteratorAggregation.bufferedand(ewahcp);
+ int wordcounter = IteratorUtil.cardinality(ewahor);
+ bogus += wordcounter;
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ System.out
+ .println("# times for: 2by2 EWAHCompressedBitmap.and bufferedand iterator-bufferedand");
+
+ System.out.println(line);
+ }
+ System.out.println("# bogus =" + bogus);
+
+ }
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkIntersection32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkIntersection32.java
new file mode 100644
index 000000000..a36ba889b
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkIntersection32.java
@@ -0,0 +1,130 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+import java.text.DecimalFormat;
+import com.fr.third.googlecode.javaewah32.*;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * To benchmark the logical and (intersection) aggregate.
+ */
+public class BenchmarkIntersection32 {
+
+ @SuppressWarnings("javadoc")
+ public static void main(String args[]) {
+ test(10, 18, 1);
+ }
+
+ @SuppressWarnings({ "javadoc" })
+ public static void test(int N, int nbr, int repeat) {
+ long bogus = 0;
+
+ DecimalFormat df = new DecimalFormat("0.###");
+ ClusteredDataGenerator cdg = new ClusteredDataGenerator();
+ for (int sparsity = 1; sparsity < 30 - nbr; sparsity++) {
+ for (int times = 0; times < 2; ++times) {
+ String line = "";
+ long bef, aft;
+ line += sparsity;
+ int[][] data = new int[N][];
+ int Max = (1 << (nbr + sparsity));
+ int[] inter = cdg.generateClustered(1 << (nbr/2), Max);
+ for (int k = 0; k < N; ++k)
+ data[k] = Benchmark.unite2by2(cdg.generateClustered(1 << nbr, Max),inter);
+ // building
+ EWAHCompressedBitmap32[] ewah = new EWAHCompressedBitmap32[N];
+ for (int k = 0; k < N; ++k) {
+ ewah[k] = new EWAHCompressedBitmap32();
+ for (int x = 0; x < data[k].length; ++x) {
+ ewah[k].set(data[k][x]);
+ }
+ data[k] = null;
+ }
+ // sanity check
+ if (true) {
+ EWAHCompressedBitmap32 answer = ewah[0].and(ewah[1]);
+ for (int k = 2; k < ewah.length; ++k)
+ answer = answer.and(ewah[k]);
+
+ EWAHCompressedBitmap32 ewahand = EWAHCompressedBitmap32.and(ewah);
+ if (!answer.equals(ewahand))
+ throw new RuntimeException(
+ "bug EWAHCompressedBitmap.and");
+ EWAHCompressedBitmap32 ewahand2 = FastAggregation32
+ .bufferedand(65536,ewah);
+ if (!ewahand.equals(ewahand2))
+ throw new RuntimeException(
+ "bug FastAggregation.bufferedand ");
+
+ }
+
+ // logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32 ewahor = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahor = ewahor.and(ewah[j]);
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = EWAHCompressedBitmap32
+ .and(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = FastAggregation32
+ .bufferedand(65536,ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW32[] ewahcp = new IteratingRLW32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = new IteratingBufferedRunningLengthWord32(
+ ewah[j]);
+ }
+ IteratingRLW32 ewahor = IteratorAggregation32.bufferedand(ewahcp);
+ int wordcounter = IteratorUtil32.cardinality(ewahor);
+ bogus += wordcounter;
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ System.out
+ .println("# times for: 2by2 EWAHCompressedBitmap.and bufferedand iterator-bufferedand");
+
+ System.out.println(line);
+ }
+ System.out.println("# bogus =" + bogus);
+
+ }
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkUnion.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkUnion.java
new file mode 100644
index 000000000..55453bbe8
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkUnion.java
@@ -0,0 +1,164 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+import java.text.DecimalFormat;
+import com.fr.third.googlecode.javaewah.*;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * To benchmark the logical or (union) aggregate.
+ */
+public class BenchmarkUnion {
+
+ @SuppressWarnings("javadoc")
+ public static void main(String args[]) {
+ test(10, 18, 1);
+ }
+
+ @SuppressWarnings({ "javadoc", "deprecation" })
+ public static void test(int N, int nbr, int repeat) {
+ long bogus = 0;
+
+ DecimalFormat df = new DecimalFormat("0.###");
+ ClusteredDataGenerator cdg = new ClusteredDataGenerator();
+ for (int sparsity = 1; sparsity < 30 - nbr; sparsity++) {
+ for (int times = 0; times < 2; ++times) {
+ String line = "";
+ long bef, aft;
+ line += sparsity;
+ int[][] data = new int[N][];
+ int Max = (1 << (nbr + sparsity));
+ for (int k = 0; k < N; ++k)
+ data[k] = cdg.generateClustered(1 << nbr, Max);
+ // building
+ EWAHCompressedBitmap[] ewah = new EWAHCompressedBitmap[N];
+ for (int k = 0; k < N; ++k) {
+ ewah[k] = new EWAHCompressedBitmap();
+ for (int x = 0; x < data[k].length; ++x) {
+ ewah[k].set(data[k][x]);
+ }
+ data[k] = null;
+ }
+ // sanity check
+ if (true) {
+ EWAHCompressedBitmap answer = ewah[0].or(ewah[1]);
+ for (int k = 2; k < ewah.length; ++k)
+ answer = answer.or(ewah[k]);
+
+ EWAHCompressedBitmap ewahor = EWAHCompressedBitmap.or(ewah);
+ if (!answer.equals(ewahor))
+ throw new RuntimeException(
+ "bug EWAHCompressedBitmap.or");
+ EWAHCompressedBitmap ewahor3 = FastAggregation.or(ewah);
+ if (!ewahor.equals(ewahor3))
+ throw new RuntimeException("bug FastAggregation.or");
+ EWAHCompressedBitmap ewahor2 = FastAggregation
+ .bufferedor(65536,ewah);
+ if (!ewahor.equals(ewahor2))
+ throw new RuntimeException(
+ "bug FastAggregation.bufferedor ");
+
+ }
+
+ // logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap ewahor = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahor = ewahor.or(ewah[j]);
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = EWAHCompressedBitmap
+ .or(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = FastAggregation
+ .or(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = FastAggregation
+ .bufferedor(65536,ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap x = new EWAHCompressedBitmap();
+ FastAggregation.legacy_orWithContainer(x, ewahcp);
+ bogus += x.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW[] ewahcp = new IteratingRLW[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = new IteratingBufferedRunningLengthWord(
+ ewah[j]);
+ }
+ IteratingRLW ewahor = IteratorAggregation.bufferedor(ewahcp);
+ int wordcounter = IteratorUtil.cardinality(ewahor);
+ bogus += wordcounter;
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ System.out
+ .println("# times for: 2by2 EWAHCompressedBitmap.or FastAggregation.or experimentalor bufferedor legacygroupedor iterator-bufferedor");
+
+ System.out.println(line);
+ }
+ System.out.println("# bogus =" + bogus);
+
+ }
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkUnion32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkUnion32.java
new file mode 100644
index 000000000..249354944
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkUnion32.java
@@ -0,0 +1,165 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+import java.text.DecimalFormat;
+
+import com.fr.third.googlecode.javaewah.FastAggregation;
+import com.fr.third.googlecode.javaewah32.*;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * To benchmark the logical or (union) aggregate.
+ */
+public class BenchmarkUnion32 {
+
+ @SuppressWarnings("javadoc")
+ public static void main(String args[]) {
+ test(10, 18, 1);
+ }
+
+ @SuppressWarnings({ "javadoc", "deprecation" })
+ public static void test(int N, int nbr, int repeat) {
+ long bogus = 0;
+
+ DecimalFormat df = new DecimalFormat("0.###");
+ ClusteredDataGenerator cdg = new ClusteredDataGenerator();
+ for (int sparsity = 1; sparsity < 30 - nbr; sparsity++) {
+ for (int times = 0; times < 2; ++times) {
+ String line = "";
+ long bef, aft;
+ line += sparsity;
+ int[][] data = new int[N][];
+ int Max = (1 << (nbr + sparsity));
+ for (int k = 0; k < N; ++k)
+ data[k] = cdg.generateClustered(1 << nbr, Max);
+ // building
+ EWAHCompressedBitmap32[] ewah = new EWAHCompressedBitmap32[N];
+ for (int k = 0; k < N; ++k) {
+ ewah[k] = new EWAHCompressedBitmap32();
+ for (int x = 0; x < data[k].length; ++x) {
+ ewah[k].set(data[k][x]);
+ }
+ data[k] = null;
+ }
+ // sanity check
+ if(true){
+ EWAHCompressedBitmap32 answer = ewah[0].or(ewah[1]);
+ for(int k = 2; k < ewah.length; ++k)
+ answer = answer.or(ewah[k]);
+
+ EWAHCompressedBitmap32 ewahor = EWAHCompressedBitmap32
+ .or(ewah);
+ if(!answer.equals(ewahor)) throw new RuntimeException("bug EWAHCompressedBitmap.or");
+ EWAHCompressedBitmap32 ewahor3 = FastAggregation
+ .or(ewah);
+ if(!ewahor.equals(ewahor3)) throw new RuntimeException("bug FastAggregation.or");
+ EWAHCompressedBitmap32 ewahor2 = FastAggregation32
+ .bufferedor(65536,ewah);
+ if(!ewahor.equals(ewahor2)) throw new RuntimeException("bug FastAggregation.bufferedor ");
+
+ }
+
+ // logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32 ewahor = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahor = ewahor.or(ewah[j]);
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = EWAHCompressedBitmap32
+ .or(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = FastAggregation
+ .or(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = FastAggregation32
+ .bufferedor(65536,ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 x = new EWAHCompressedBitmap32();
+ FastAggregation32.legacy_orWithContainer(x, ewahcp);
+ bogus += x.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical or
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW32[] ewahcp = new IteratingRLW32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = new IteratingBufferedRunningLengthWord32(ewah[j]);
+ }
+ IteratingRLW32 ewahor = IteratorAggregation32
+ .bufferedor(ewahcp);
+ int wordcounter = IteratorUtil32.cardinality(ewahor);
+ bogus += wordcounter;
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ System.out
+ .println("# times for: 2by2 EWAHCompressedBitmap.or FastAggregation.or experimentalor bufferedor legacygroupedor iterator-bufferedor");
+
+ System.out.println(line);
+ }
+ System.out.println("# bogus =" + bogus);
+
+ }
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkXOR.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkXOR.java
new file mode 100644
index 000000000..7f036d690
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkXOR.java
@@ -0,0 +1,134 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+import java.text.DecimalFormat;
+import com.fr.third.googlecode.javaewah.*;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * To benchmark the logical xor aggregate.
+ */
+public class BenchmarkXOR {
+
+ @SuppressWarnings("javadoc")
+ public static void main(String args[]) {
+ //test(10, 18, 1);
+ test(2, 22, 1);
+ }
+
+ @SuppressWarnings({ "javadoc" })
+ public static void test(int N, int nbr, int repeat) {
+ long bogus = 0;
+
+ DecimalFormat df = new DecimalFormat("0.###");
+ ClusteredDataGenerator cdg = new ClusteredDataGenerator();
+ for (int sparsity = 1; sparsity < 30 - nbr; sparsity++) {
+ for (int times = 0; times < 2; ++times) {
+ String line = "";
+ long bef, aft;
+ line += sparsity;
+ int[][] data = new int[N][];
+ int Max = (1 << (nbr + sparsity));
+ for (int k = 0; k < N; ++k)
+ data[k] = cdg.generateClustered(1 << nbr, Max);
+ // building
+ EWAHCompressedBitmap[] ewah = new EWAHCompressedBitmap[N];
+ for (int k = 0; k < N; ++k) {
+ ewah[k] = new EWAHCompressedBitmap();
+ for (int x = 0; x < data[k].length; ++x) {
+ ewah[k].set(data[k][x]);
+ }
+ data[k] = null;
+ }
+ // sanity check
+ if (true) {
+ EWAHCompressedBitmap answer = ewah[0].xor(ewah[1]);
+ for (int k = 2; k < ewah.length; ++k)
+ answer = answer.xor(ewah[k]);
+ EWAHCompressedBitmap ewahor3 = FastAggregation.xor(ewah);
+ if (!answer.equals(ewahor3))
+ throw new RuntimeException("bug FastAggregation.xor");
+ EWAHCompressedBitmap ewahor2 = FastAggregation
+ .bufferedxor(65536,ewah);
+ if (!answer.equals(ewahor2))
+ throw new RuntimeException(
+ "bug FastAggregation.bufferedxor ");
+ EWAHCompressedBitmap iwah = IteratorUtil.materialize(IteratorAggregation.bufferedxor(IteratorUtil.toIterators(ewah)));
+ if (!answer.equals(iwah))
+ throw new RuntimeException(
+ "bug xor it ");
+
+
+ }
+
+ // logical xor
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap ewahor = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahor = ewahor.xor(ewah[j]);
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical xor
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = FastAggregation
+ .xor(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ // fast logical xor
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap[] ewahcp = new EWAHCompressedBitmap[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap ewahor = FastAggregation
+ .bufferedxor(65536,ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+ // fast logical xor
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW[] ewahcp = new IteratingRLW[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = new IteratingBufferedRunningLengthWord(
+ ewah[j]);
+ }
+ IteratingRLW ewahor = IteratorAggregation.bufferedxor(ewahcp);
+ int wordcounter = IteratorUtil.cardinality(ewahor);
+ bogus += wordcounter;
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ System.out
+ .println("# times for: 2by2 FastAggregation.xor bufferedxor iterator-based");
+
+ System.out.println(line);
+ }
+ System.out.println("# bogus =" + bogus);
+
+ }
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkXOR32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkXOR32.java
new file mode 100644
index 000000000..4fb057fab
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/BenchmarkXOR32.java
@@ -0,0 +1,137 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+import java.text.DecimalFormat;
+
+import com.fr.third.googlecode.javaewah.FastAggregation;
+import com.fr.third.googlecode.javaewah32.*;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * To benchmark the logical xor aggregate.
+ */
+public class BenchmarkXOR32 {
+
+ @SuppressWarnings("javadoc")
+ public static void main(String args[]) {
+ test(10, 18, 1);
+ //test(2, 22, 1);
+ }
+
+ @SuppressWarnings({ "javadoc" })
+ public static void test(int N, int nbr, int repeat) {
+ long bogus = 0;
+
+ DecimalFormat df = new DecimalFormat("0.###");
+ ClusteredDataGenerator cdg = new ClusteredDataGenerator();
+ for (int sparsity = 1; sparsity < 30 - nbr; sparsity++) {
+ for (int times = 0; times < 2; ++times) {
+ String line = "";
+ long bef, aft;
+ line += sparsity;
+ int[][] data = new int[N][];
+ int Max = (1 << (nbr + sparsity));
+ for (int k = 0; k < N; ++k)
+ data[k] = cdg.generateClustered(1 << nbr, Max);
+ // building
+ EWAHCompressedBitmap32[] ewah = new EWAHCompressedBitmap32[N];
+ for (int k = 0; k < N; ++k) {
+ ewah[k] = new EWAHCompressedBitmap32();
+ for (int x = 0; x < data[k].length; ++x) {
+ ewah[k].set(data[k][x]);
+ }
+ data[k] = null;
+ }
+ // sanity check
+ if (true) {
+ EWAHCompressedBitmap32 answer = ewah[0].xor(ewah[1]);
+ for (int k = 2; k < ewah.length; ++k)
+ answer = answer.xor(ewah[k]);
+ EWAHCompressedBitmap32 ewahor3 = FastAggregation.xor(ewah);
+ if (!answer.equals(ewahor3))
+ throw new RuntimeException("bug FastAggregation.xor");
+ EWAHCompressedBitmap32 ewahor2 = FastAggregation32
+ .bufferedxor(65536,ewah);
+ if (!answer.equals(ewahor2))
+ throw new RuntimeException(
+ "bug FastAggregation.bufferedxor ");
+ EWAHCompressedBitmap32 iwah = IteratorUtil32.materialize(IteratorAggregation32.bufferedxor(IteratorUtil32.toIterators(ewah)));
+ if (!answer.equals(iwah))
+ throw new RuntimeException(
+ "bug xor it ");
+
+ }
+
+ // logical xor
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32 ewahor = ewah[0];
+ for (int j = 1; j < k + 1; ++j) {
+ ewahor = ewahor.xor(ewah[j]);
+ }
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical xor
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = FastAggregation
+ .xor(ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ // fast logical xor
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ EWAHCompressedBitmap32[] ewahcp = new EWAHCompressedBitmap32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = ewah[j];
+ }
+ EWAHCompressedBitmap32 ewahor = FastAggregation32
+ .bufferedxor(65536,ewahcp);
+ bogus += ewahor.sizeInBits();
+ }
+ aft = System.currentTimeMillis();
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+ // fast logical xor
+ bef = System.currentTimeMillis();
+ for (int r = 0; r < repeat; ++r)
+ for (int k = 0; k < N; ++k) {
+ IteratingRLW32[] ewahcp = new IteratingRLW32[k + 1];
+ for (int j = 0; j < k + 1; ++j) {
+ ewahcp[j] = new IteratingBufferedRunningLengthWord32(
+ ewah[j]);
+ }
+ IteratingRLW32 ewahor = IteratorAggregation32.bufferedxor(ewahcp);
+ int wordcounter = IteratorUtil32.cardinality(ewahor);
+ bogus += wordcounter;
+ }
+ aft = System.currentTimeMillis();
+
+ line += "\t" + df.format((aft - bef) / 1000.0);
+
+
+ System.out
+ .println("# times for: 2by2 FastAggregation.xor bufferedxor iterator-based");
+
+ System.out.println(line);
+ }
+ System.out.println("# bogus =" + bogus);
+
+ }
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/ClusteredDataGenerator.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/ClusteredDataGenerator.java
new file mode 100644
index 000000000..29078ca21
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/ClusteredDataGenerator.java
@@ -0,0 +1,78 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+
+/**
+ * This class will generate lists of random integers with a "clustered" distribution.
+ * Reference:
+ * Anh VN, Moffat A. Index compression using 64-bit words. Software: Practice and Experience 2010; 40(2):131-147.
+ *
+ * @author Daniel Lemire
+ */
+public class ClusteredDataGenerator {
+
+ /**
+ *
+ */
+public ClusteredDataGenerator() {
+ this.unidg = new UniformDataGenerator();
+ }
+
+ /**
+ * @param seed random seed
+ */
+public ClusteredDataGenerator(final int seed) {
+ this.unidg = new UniformDataGenerator(seed);
+}
+
+/**
+ * generates randomly N distinct integers from 0 to Max.
+ * @param N number of integers
+ * @param Max maximum integer value
+ * @return a randomly generated array
+ */
+ public int[] generateClustered(int N, int Max) {
+ int[] array = new int[N];
+ fillClustered(array, 0, N, 0, Max);
+ return array;
+ }
+
+ void fillClustered(int[] array, int offset, int length, int Min, int Max) {
+ final int range = Max - Min;
+ if ((range == length) || (length <= 10)) {
+ fillUniform(array, offset, length, Min, Max);
+ return;
+ }
+ final int cut = length / 2
+ + ((range - length - 1 > 0) ? this.unidg.rand.nextInt(range - length - 1) : 0);
+ final double p = this.unidg.rand.nextDouble();
+ if (p < 0.25) {
+ fillUniform(array, offset, length / 2, Min, Min + cut);
+ fillClustered(array, offset + length / 2, length - length / 2, Min + cut,
+ Max);
+ } else if (p < 0.5) {
+ fillClustered(array, offset, length / 2, Min, Min + cut);
+ fillUniform(array, offset + length / 2, length - length / 2, Min + cut,
+ Max);
+ } else {
+ fillClustered(array, offset, length / 2, Min, Min + cut);
+ fillClustered(array, offset + length / 2, length - length / 2, Min + cut,
+ Max);
+ }
+ }
+
+ void fillUniform(int[] array, int offset, int length, int Min, int Max) {
+ int[] v = this.unidg.generateUniform(length, Max - Min);
+ for (int k = 0; k < v.length; ++k)
+ array[k + offset] = Min + v[k];
+ }
+
+ UniformDataGenerator unidg;
+
+}
+
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/UniformDataGenerator.java b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/UniformDataGenerator.java
new file mode 100644
index 000000000..6c91ea67e
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah/benchmark/UniformDataGenerator.java
@@ -0,0 +1,114 @@
+package com.fr.third.googlecode.javaewah.benchmark;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Random;
+
+/**
+ * This class will generate "uniform" lists of random integers.
+ *
+ * @author Daniel Lemire
+ */
+public class UniformDataGenerator {
+ /**
+ * construct generator of random arrays.
+ */
+ public UniformDataGenerator() {
+ this.rand = new Random();
+ }
+
+ /**
+ * @param seed random seed
+ */
+ public UniformDataGenerator(final int seed) {
+ this.rand = new Random(seed);
+ }
+
+ /**
+ * generates randomly N distinct integers from 0 to Max.
+ */
+ int[] generateUniformHash(int N, int Max) {
+ if (N > Max)
+ throw new RuntimeException("not possible");
+ int[] ans = new int[N];
+ HashSet s = new HashSet();
+ while (s.size() < N)
+ s.add(new Integer(this.rand.nextInt(Max)));
+ Iterator i = s.iterator();
+ for (int k = 0; k < N; ++k)
+ ans[k] = i.next().intValue();
+ Arrays.sort(ans);
+ return ans;
+ }
+
+ /**
+ * output all integers from the range [0,Max) that are not
+ * in the array
+ */
+ static int[] negate(int[] x, int Max) {
+ int[] ans = new int[Max - x.length];
+ int i = 0;
+ int c = 0;
+ for (int j = 0; j < x.length; ++j) {
+ int v = x[j];
+ for (; i < v; ++i)
+ ans[c++] = i;
+ ++i;
+ }
+ while (c < ans.length)
+ ans[c++] = i++;
+ return ans;
+ }
+
+
+ /**
+ * generates randomly N distinct integers from 0 to Max.
+ * @param N Number of integers to generate
+ * @param Max Maximum value of the integers
+ * @return array containing random integers
+ */
+ public int[] generateUniform(int N, int Max) {
+ if(N * 2 > Max) {
+ return negate( generateUniform(Max - N, Max), Max );
+ }
+ if (2048 * N > Max)
+ return generateUniformBitmap(N, Max);
+ return generateUniformHash(N, Max);
+ }
+
+ /**
+ * generates randomly N distinct integers from 0 to Max using a bitmap.
+ * @param N Number of integers to generate
+ * @param Max Maximum value of the integers
+ * @return array containing random integers
+ */
+ int[] generateUniformBitmap(int N, int Max) {
+ if (N > Max)
+ throw new RuntimeException("not possible");
+ int[] ans = new int[N];
+ BitSet bs = new BitSet(Max);
+ int cardinality = 0;
+ while (cardinality < N) {
+ int v = this.rand.nextInt(Max);
+ if (!bs.get(v)) {
+ bs.set(v);
+ cardinality++;
+ }
+ }
+ int pos = 0;
+ for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
+ ans[pos++] = i;
+ }
+ return ans;
+ }
+
+ Random rand = new Random();
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/BitCounter32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/BitCounter32.java
new file mode 100644
index 000000000..53a9a0ee5
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/BitCounter32.java
@@ -0,0 +1,102 @@
+package com.fr.third.googlecode.javaewah32;
+
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc. and Veronika Zenz
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * BitCounter is a fake bitset data structure. Instead of storing the actual data,
+ * it only records the number of set bits.
+ *
+ * @since 0.5.0
+ * @author Daniel Lemire and David McIntosh
+ */
+
+public final class BitCounter32 implements BitmapStorage32 {
+
+ /**
+ * Virtually add words directly to the bitmap
+ *
+ * @param newdata the word
+ */
+ // @Override : causes problems with Java 1.5
+ @Override
+public void add(final int newdata) {
+ this.oneBits += Integer.bitCount(newdata);
+ }
+
+
+ /**
+ * virtually add several literal words.
+ *
+ * @param data the literal words
+ * @param start the starting point in the array
+ * @param number the number of literal words to add
+ */
+ // @Override : causes problems with Java 1.5
+ @Override
+public void addStreamOfLiteralWords(int[] data, int start, int number) {
+ for(int i=start;i iterator) {
+ this.masteriterator = iterator;
+ if(this.masteriterator.hasNext()) {
+ this.iterator = this.masteriterator.next();
+ this.brlw = new BufferedRunningLengthWord32(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords() + this.brlw.literalwordoffset;
+ this.buffer = this.iterator.buffer();
+ }
+ }
+
+
+ /**
+ * Discard first words, iterating to the next running length word if needed.
+ *
+ * @param x the number of words to be discarded
+ */
+ @Override
+ public void discardFirstWords(int x) {
+ while (x > 0) {
+ if (this.brlw.RunningLength > x) {
+ this.brlw.RunningLength -= x;
+ return;
+ }
+ x -= this.brlw.RunningLength;
+ this.brlw.RunningLength = 0;
+ int toDiscard = x > this.brlw.NumberOfLiteralWords ? this.brlw.NumberOfLiteralWords : x;
+
+ this.literalWordStartPosition += toDiscard;
+ this.brlw.NumberOfLiteralWords -= toDiscard;
+ x -= toDiscard;
+ if ((x > 0) || (this.brlw.size() == 0)) {
+ if (!this.next()) {
+ break;
+ }
+ }
+ }
+ }
+ /**
+ * Move to the next RunningLengthWord
+ * @return whether the move was possible
+ */
+ @Override
+ public boolean next() {
+ if (!this.iterator.hasNext()) {
+ if(!reload()) {
+ this.brlw.NumberOfLiteralWords = 0;
+ this.brlw.RunningLength = 0;
+ return false;
+ }
+ }
+ this.brlw.reset(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords(); // + this.brlw.literalwordoffset ==0
+ return true;
+ }
+ private boolean reload() {
+ if(!this.masteriterator.hasNext()) {
+ return false;
+ }
+ this.iterator = this.masteriterator.next();
+ this.buffer = this.iterator.buffer();
+ return true;
+ }
+
+
+ /**
+ * Get the nth literal word for the current running length word
+ * @param index zero based index
+ * @return the literal word
+ */
+ @Override
+ public int getLiteralWordAt(int index) {
+ return this.buffer[this.literalWordStartPosition + index];
+ }
+
+ /**
+ * Gets the number of literal words for the current running length word.
+ *
+ * @return the number of literal words
+ */
+ @Override
+ public int getNumberOfLiteralWords() {
+ return this.brlw.NumberOfLiteralWords;
+ }
+
+ /**
+ * Gets the running bit.
+ *
+ * @return the running bit
+ */
+ @Override
+ public boolean getRunningBit() {
+ return this.brlw.RunningBit;
+ }
+
+ /**
+ * Gets the running length.
+ *
+ * @return the running length
+ */
+ @Override
+ public int getRunningLength() {
+ return this.brlw.RunningLength;
+ }
+
+ /**
+ * Size in uncompressed words of the current running length word.
+ *
+ * @return the size
+ */
+ @Override
+ public int size() {
+ return this.brlw.size();
+ }
+
+ @Override
+ public BufferedIterator32 clone() throws CloneNotSupportedException {
+ BufferedIterator32 answer = (BufferedIterator32) super.clone();
+ answer.brlw = this.brlw.clone();
+ answer.buffer = this.buffer;
+ answer.iterator = this.iterator.clone();
+ answer.literalWordStartPosition = this.literalWordStartPosition;
+ answer.masteriterator = this.masteriterator.clone();
+ return answer;
+ }
+
+ private BufferedRunningLengthWord32 brlw;
+ private int[] buffer;
+ private int literalWordStartPosition;
+ private EWAHIterator32 iterator;
+ private CloneableIterator masteriterator;
+ }
\ No newline at end of file
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/BufferedRunningLengthWord32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/BufferedRunningLengthWord32.java
new file mode 100644
index 000000000..80b665e81
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/BufferedRunningLengthWord32.java
@@ -0,0 +1,174 @@
+package com.fr.third.googlecode.javaewah32;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+
+
+/**
+ * Mostly for internal use. Similar to RunningLengthWord, but can
+ * be modified without access to the array, and has faster access.
+ *
+ * @author Daniel Lemire
+ * @since 0.5.0
+ *
+ */
+public final class BufferedRunningLengthWord32 implements Cloneable {
+
+ /**
+ * Instantiates a new buffered running length word.
+ *
+ * @param a the word
+ */
+ public BufferedRunningLengthWord32(final int a) {
+ this.NumberOfLiteralWords = (a >>> (1 + RunningLengthWord32.runninglengthbits));
+ this.RunningBit = (a & 1) != 0;
+ this.RunningLength = ((a >>> 1) & RunningLengthWord32.largestrunninglengthcount);
+ }
+
+ /**
+ * Instantiates a new buffered running length word.
+ *
+ * @param rlw the rlw
+ */
+ public BufferedRunningLengthWord32(final RunningLengthWord32 rlw) {
+ this(rlw.parent.buffer[rlw.position]);
+ }
+
+ /**
+ * Discard first words.
+ *
+ * @param x the number of words to be discarded
+ */
+ public void discardFirstWords(int x) {
+ if (this.RunningLength >= x) {
+ this.RunningLength -= x;
+ return;
+ }
+ x -= this.RunningLength;
+ this.RunningLength = 0;
+ this.literalwordoffset += x;
+ this.NumberOfLiteralWords -= x;
+ }
+
+ /**
+ * Gets the number of literal words.
+ *
+ * @return the number of literal words
+ */
+ public int getNumberOfLiteralWords() {
+ return this.NumberOfLiteralWords;
+ }
+
+ /**
+ * Gets the running bit.
+ *
+ * @return the running bit
+ */
+ public boolean getRunningBit() {
+ return this.RunningBit;
+ }
+
+ /**
+ * Gets the running length.
+ *
+ * @return the running length
+ */
+ public int getRunningLength() {
+ return this.RunningLength;
+ }
+
+ /**
+ * Reset the values using the provided word.
+ *
+ * @param a the word
+ */
+ public void reset(final int a) {
+ this.NumberOfLiteralWords = (a >>> (1 + RunningLengthWord32.runninglengthbits));
+ this.RunningBit = (a & 1) != 0;
+ this.RunningLength = ((a >>> 1) & RunningLengthWord32.largestrunninglengthcount);
+ this.literalwordoffset = 0;
+ }
+
+ /**
+ * Reset the values of this running length word so that it has the same values
+ * as the other running length word.
+ *
+ * @param rlw the other running length word
+ */
+ public void reset(final RunningLengthWord32 rlw) {
+ reset(rlw.parent.buffer[rlw.position]);
+ }
+
+ /**
+ * Sets the number of literal words.
+ *
+ * @param number the new number of literal words
+ */
+ public void setNumberOfLiteralWords(final int number) {
+ this.NumberOfLiteralWords = number;
+ }
+
+ /**
+ * Sets the running bit.
+ *
+ * @param b the new running bit
+ */
+ public void setRunningBit(final boolean b) {
+ this.RunningBit = b;
+ }
+
+ /**
+ * Sets the running length.
+ *
+ * @param number the new running length
+ */
+ public void setRunningLength(final int number) {
+ this.RunningLength = number;
+ }
+
+ /**
+ * Size in uncompressed words.
+ *
+ * @return the int
+ */
+ public int size() {
+ return this.RunningLength + this.NumberOfLiteralWords;
+ }
+
+ /*
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "running bit = " + getRunningBit() + " running length = "
+ + getRunningLength() + " number of lit. words "
+ + getNumberOfLiteralWords();
+ }
+
+ @Override
+public BufferedRunningLengthWord32 clone() throws CloneNotSupportedException {
+ BufferedRunningLengthWord32 answer = (BufferedRunningLengthWord32) super.clone();
+ answer.literalwordoffset = this.literalwordoffset;
+ answer.NumberOfLiteralWords = this.NumberOfLiteralWords;
+ answer.RunningBit = this.RunningBit;
+ answer.RunningLength = this.RunningLength;
+ return answer;
+ }
+
+ /** how many literal words have we read so far? */
+ public int literalwordoffset = 0;
+
+ /** The Number of literal words. */
+ public int NumberOfLiteralWords;
+
+ /** The Running bit. */
+ public boolean RunningBit;
+
+ /** The Running length. */
+ public int RunningLength;
+
+
+}
\ No newline at end of file
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/EWAHCompressedBitmap32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/EWAHCompressedBitmap32.java
new file mode 100644
index 000000000..56259ffee
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/EWAHCompressedBitmap32.java
@@ -0,0 +1,1608 @@
+package com.fr.third.googlecode.javaewah32;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+import java.util.*;
+import java.io.*;
+
+import com.fr.third.googlecode.javaewah.IntIterator;
+import com.fr.third.googlecode.javaewah.LogicalElement;
+
+
+/**
+ *
+ * This implements the patent-free EWAH scheme. Roughly speaking, it is a 32-bit
+ * variant of the BBC compression scheme used by Oracle for its bitmap indexes.
+ *
+ *
+ *
+ * In contrast with the 64-bit EWAH scheme (javaewah.EWAHCompressedBitmap), you
+ * can expect this class to compress better, but to be slower at processing the
+ * data. In effect, there is a trade-off between memory usage and performances.
+ *
+ *
+ * @since 0.5.0
+ */
+public final class EWAHCompressedBitmap32 implements Cloneable, Externalizable,
+ Iterable, BitmapStorage32, LogicalElement {
+
+ /**
+ * Creates an empty bitmap (no bit set to true).
+ */
+ public EWAHCompressedBitmap32() {
+ this.buffer = new int[defaultbuffersize];
+ this.rlw = new RunningLengthWord32(this, 0);
+ }
+
+ /**
+ * Sets explicitly the buffer size (in 32-bit words). The initial memory usage
+ * will be "buffersize * 32". For large poorly compressible bitmaps, using
+ * large values may improve performance.
+ *
+ * @param buffersize
+ * number of 32-bit words reserved when the object is created)
+ */
+ public EWAHCompressedBitmap32(final int buffersize) {
+ this.buffer = new int[buffersize];
+ this.rlw = new RunningLengthWord32(this, 0);
+ }
+
+ /**
+ * Adding words directly to the bitmap (for expert use).
+ *
+ * This is normally how you add data to the array. So you add bits in streams
+ * of 4*8 bits.
+ *
+ * Example: if you add 321, you are have added (in binary notation)
+ * 0b101000001, so you have effectively called set(0), set(6), set(8)
+ * in sequence.
+ *
+ * @param newdata
+ * the word
+ */
+ @Override
+public void add(final int newdata) {
+ add(newdata, wordinbits);
+ }
+
+ /**
+ * Adding words directly to the bitmap (for expert use).
+ *
+ * @param newdata
+ * the word
+ * @param bitsthatmatter
+ * the number of significant bits (by default it should be 32)
+ */
+ public void add(final int newdata, final int bitsthatmatter) {
+ this.sizeinbits += bitsthatmatter;
+ if (newdata == 0) {
+ addEmptyWord(false);
+ } else if (newdata == ~0) {
+ addEmptyWord(true);
+ } else {
+ addLiteralWord(newdata);
+ }
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param v
+ * the boolean value
+ * @return the storage cost of the addition
+ */
+ private int addEmptyWord(final boolean v) {
+ final boolean noliteralword = (this.rlw.getNumberOfLiteralWords() == 0);
+ final int runlen = this.rlw.getRunningLength();
+ if ((noliteralword) && (runlen == 0)) {
+ this.rlw.setRunningBit(v);
+ }
+ if ((noliteralword) && (this.rlw.getRunningBit() == v)
+ && (runlen < RunningLengthWord32.largestrunninglengthcount)) {
+ this.rlw.setRunningLength(runlen + 1);
+ return 0;
+ }
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(1);
+ return 1;
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param newdata
+ * the literal word
+ * @return the storage cost of the addition
+ */
+ private int addLiteralWord(final int newdata) {
+ final int numbersofar = this.rlw.getNumberOfLiteralWords();
+ if (numbersofar >= RunningLengthWord32.largestliteralcount) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ this.rlw.setNumberOfLiteralWords(1);
+ push_back(newdata);
+ return 2;
+ }
+ this.rlw.setNumberOfLiteralWords(numbersofar + 1);
+ push_back(newdata);
+ return 1;
+ }
+
+ /**
+ * if you have several literal words to copy over, this might be faster.
+ *
+ *
+ * @param data
+ * the literal words
+ * @param start
+ * the starting point in the array
+ * @param number
+ * the number of literal words to add
+ */
+ @Override
+public void addStreamOfLiteralWords(final int[] data, final int start,
+ final int number) {
+ int leftovernumber = number;
+ while (leftovernumber > 0) {
+ final int NumberOfLiteralWords = this.rlw.getNumberOfLiteralWords();
+ final int whatwecanadd = leftovernumber < RunningLengthWord32.largestliteralcount
+ - NumberOfLiteralWords ? leftovernumber
+ : RunningLengthWord32.largestliteralcount
+ - NumberOfLiteralWords;
+ this.rlw.setNumberOfLiteralWords(NumberOfLiteralWords
+ + whatwecanadd);
+ leftovernumber -= whatwecanadd;
+ push_back(data, start, whatwecanadd);
+ this.sizeinbits += whatwecanadd * wordinbits;
+ if (leftovernumber > 0) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ }
+ }
+ }
+
+ /**
+ * For experts: You want to add many zeroes or ones? This is the method you
+ * use.
+ *
+ * @param v
+ * the boolean value
+ * @param number
+ * the number
+ */
+ @Override
+public void addStreamOfEmptyWords(final boolean v, int number) {
+ if (number == 0)
+ return;
+ this.sizeinbits += number * wordinbits;
+ if ((this.rlw.getRunningBit() != v) && (this.rlw.size() == 0)) {
+ this.rlw.setRunningBit(v);
+ } else if ((this.rlw.getNumberOfLiteralWords() != 0)
+ || (this.rlw.getRunningBit() != v)) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ }
+ final int runlen = this.rlw.getRunningLength();
+ final int whatwecanadd = number < RunningLengthWord32.largestrunninglengthcount
+ - runlen ? number : RunningLengthWord32.largestrunninglengthcount
+ - runlen;
+ this.rlw.setRunningLength(runlen + whatwecanadd);
+ number -= whatwecanadd;
+ while (number >= RunningLengthWord32.largestrunninglengthcount) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(RunningLengthWord32.largestrunninglengthcount);
+ number -= RunningLengthWord32.largestrunninglengthcount;
+ }
+ if (number > 0) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(number);
+ }
+ }
+
+ /**
+ * Same as addStreamOfLiteralWords, but the words are negated.
+ *
+ * @param data
+ * the literal words
+ * @param start
+ * the starting point in the array
+ * @param number
+ * the number of literal words to add
+ */
+ @Override
+public void addStreamOfNegatedLiteralWords(final int[] data, final int start,
+ final int number) {
+ int leftovernumber = number;
+ while (leftovernumber > 0) {
+ final int NumberOfLiteralWords = this.rlw.getNumberOfLiteralWords();
+ final int whatwecanadd = leftovernumber < RunningLengthWord32.largestliteralcount
+ - NumberOfLiteralWords ? leftovernumber
+ : RunningLengthWord32.largestliteralcount
+ - NumberOfLiteralWords;
+ this.rlw.setNumberOfLiteralWords(NumberOfLiteralWords
+ + whatwecanadd);
+ leftovernumber -= whatwecanadd;
+ negative_push_back(data, start, whatwecanadd);
+ this.sizeinbits += whatwecanadd * wordinbits;
+ if (leftovernumber > 0) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ }
+ }
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise AND values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param a
+ * the other bitmap
+ * @return the EWAH compressed bitmap
+ */
+ @Override
+public EWAHCompressedBitmap32 and(final EWAHCompressedBitmap32 a) {
+ final EWAHCompressedBitmap32 container = new EWAHCompressedBitmap32();
+ container
+ .reserve(this.actualsizeinwords > a.actualsizeinwords ? this.actualsizeinwords
+ : a.actualsizeinwords);
+ andToContainer(a, container);
+ return container;
+ }
+
+ /**
+ * Computes new compressed bitmap containing the bitwise AND values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * @param a
+ * the other bitmap
+ * @param container
+ * where we store the result
+ */
+ /**
+ * Computes new compressed bitmap containing the bitwise AND values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * @since 0.4.0
+ * @param a
+ * the other bitmap
+ * @param container
+ * where we store the result
+ */
+ public void andToContainer(final EWAHCompressedBitmap32 a, final BitmapStorage32 container) {
+ final EWAHIterator32 i = a.getEWAHIterator();
+ final EWAHIterator32 j = getEWAHIterator();
+ final IteratingBufferedRunningLengthWord32 rlwi = new IteratingBufferedRunningLengthWord32(i);
+ final IteratingBufferedRunningLengthWord32 rlwj = new IteratingBufferedRunningLengthWord32(j);
+ while ((rlwi.size()>0) && (rlwj.size()>0)) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingBufferedRunningLengthWord32 prey = i_is_prey ? rlwi
+ : rlwj;
+ final IteratingBufferedRunningLengthWord32 predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ container.addStreamOfEmptyWords(false, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ final int index = prey.discharge(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) & rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ if (adjustContainerSizeWhenAggregating) {
+ final boolean i_remains = rlwi.size() > 0;
+ final IteratingBufferedRunningLengthWord32 remaining = i_remains ? rlwi
+ : rlwj;
+ remaining.dischargeAsEmpty(container);
+ container.setSizeInBits(Math.max(sizeInBits(), a.sizeInBits()));
+ }
+ }
+
+
+ /**
+ * Returns the cardinality of the result of a bitwise AND of the values of the
+ * current bitmap with some other bitmap. Avoids needing to allocate an
+ * intermediate bitmap to hold the result of the OR.
+ *
+ * @param a
+ * the other bitmap
+ * @return the cardinality
+ */
+ public int andCardinality(final EWAHCompressedBitmap32 a) {
+ final BitCounter32 counter = new BitCounter32();
+ andToContainer(a, counter);
+ return counter.getCount();
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise AND NOT values of
+ * the current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param a
+ * the other bitmap
+ * @return the EWAH compressed bitmap
+ */
+ @Override
+public EWAHCompressedBitmap32 andNot(final EWAHCompressedBitmap32 a) {
+ final EWAHCompressedBitmap32 container = new EWAHCompressedBitmap32();
+ container
+ .reserve(this.actualsizeinwords > a.actualsizeinwords ? this.actualsizeinwords
+ : a.actualsizeinwords);
+ andNotToContainer(a, container);
+ return container;
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise AND NOT values of
+ * the current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * @param a the other bitmap
+ * @param container where we store the result
+ */
+ public void andNotToContainer(final EWAHCompressedBitmap32 a,
+ final BitmapStorage32 container) {
+ final EWAHIterator32 i = getEWAHIterator();
+ final EWAHIterator32 j = a.getEWAHIterator();
+ final IteratingBufferedRunningLengthWord32 rlwi = new IteratingBufferedRunningLengthWord32(i);
+ final IteratingBufferedRunningLengthWord32 rlwj = new IteratingBufferedRunningLengthWord32(j);
+ while ((rlwi.size()>0) && (rlwj.size()>0)) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingBufferedRunningLengthWord32 prey = i_is_prey ? rlwi : rlwj;
+ final IteratingBufferedRunningLengthWord32 predator = i_is_prey ? rlwj
+ : rlwi;
+ if ( ((predator.getRunningBit() == true) && (i_is_prey))
+ || ((predator.getRunningBit() == false) && (!i_is_prey))){
+ container.addStreamOfEmptyWords(false, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else if (i_is_prey) {
+ int index = prey.discharge(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ int index = prey.dischargeNegated(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(true, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) & (~rlwj.getLiteralWordAt(k)));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ final boolean i_remains = rlwi.size()>0;
+ final IteratingBufferedRunningLengthWord32 remaining = i_remains ? rlwi : rlwj;
+ if(i_remains)
+ remaining.discharge(container);
+ else if (adjustContainerSizeWhenAggregating)
+ remaining.dischargeAsEmpty(container);
+ if (adjustContainerSizeWhenAggregating)
+ container.setSizeInBits(Math.max(sizeInBits(), a.sizeInBits()));
+
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise AND NOT of the values of
+ * the current bitmap with some other bitmap. Avoids needing to allocate an
+ * intermediate bitmap to hold the result of the OR.
+ *
+ * @param a
+ * the other bitmap
+ * @return the cardinality
+ */
+ public int andNotCardinality(final EWAHCompressedBitmap32 a) {
+ final BitCounter32 counter = new BitCounter32();
+ andNotToContainer(a, counter);
+ return counter.getCount();
+ }
+
+ /**
+ * reports the number of bits set to true. Running time is proportional to
+ * compressed size (as reported by sizeInBytes).
+ *
+ * @return the number of bits set to true
+ */
+ public int cardinality() {
+ int counter = 0;
+ final EWAHIterator32 i = new EWAHIterator32(this,
+ this.actualsizeinwords);
+ while (i.hasNext()) {
+ RunningLengthWord32 localrlw = i.next();
+ if (localrlw.getRunningBit()) {
+ counter += wordinbits * localrlw.getRunningLength();
+ }
+ for (int j = 0; j < localrlw.getNumberOfLiteralWords(); ++j) {
+ counter += Integer.bitCount(i.buffer()[i.literalWords() + j]);
+ }
+ }
+ return counter;
+ }
+
+ /**
+ * Clear any set bits and set size in bits back to 0
+ */
+ public void clear() {
+ this.sizeinbits = 0;
+ this.actualsizeinwords = 1;
+ this.rlw.position = 0;
+ // buffer is not fully cleared but any new set operations should overwrite
+ // stale data
+ this.buffer[0] = 0;
+ }
+
+ /*
+ * @see java.lang.Object#clone()
+ */
+ @Override
+ public EWAHCompressedBitmap32 clone() throws CloneNotSupportedException {
+ final EWAHCompressedBitmap32 clone = (EWAHCompressedBitmap32) super.clone();
+ clone.buffer = this.buffer.clone();
+ clone.actualsizeinwords = this.actualsizeinwords;
+ clone.sizeinbits = this.sizeinbits;
+ return clone;
+ }
+
+ /**
+ * Deserialize.
+ *
+ * @param in
+ * the DataInput stream
+ * @throws IOException
+ * Signals that an I/O exception has occurred.
+ */
+ public void deserialize(DataInput in) throws IOException {
+ this.sizeinbits = in.readInt();
+ this.actualsizeinwords = in.readInt();
+ if (this.buffer.length < this.actualsizeinwords) {
+ this.buffer = new int[this.actualsizeinwords];
+ }
+ for (int k = 0; k < this.actualsizeinwords; ++k)
+ this.buffer[k] = in.readInt();
+ this.rlw = new RunningLengthWord32(this, in.readInt());
+ }
+
+ /**
+ * Check to see whether the two compressed bitmaps contain the same set bits.
+ *
+ * @see Object#equals(Object)
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof EWAHCompressedBitmap32) {
+ try {
+ this.xorToContainer((EWAHCompressedBitmap32) o, new NonEmptyVirtualStorage32());
+ return true;
+ } catch (NonEmptyVirtualStorage32.NonEmptyException e) {
+ return false;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * For experts: You want to add many zeroes or ones faster?
+ *
+ * This method does not update sizeinbits.
+ *
+ * @param v
+ * the boolean value
+ * @param number
+ * the number (must be greater than 0)
+ */
+ private void fastaddStreamOfEmptyWords(final boolean v, int number) {
+ if ((this.rlw.getRunningBit() != v) && (this.rlw.size() == 0)) {
+ this.rlw.setRunningBit(v);
+ } else if ((this.rlw.getNumberOfLiteralWords() != 0)
+ || (this.rlw.getRunningBit() != v)) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ }
+ final int runlen = this.rlw.getRunningLength();
+ final int whatwecanadd = number < RunningLengthWord32.largestrunninglengthcount
+ - runlen ? number : RunningLengthWord32.largestrunninglengthcount
+ - runlen;
+ this.rlw.setRunningLength(runlen + whatwecanadd);
+ number -= whatwecanadd;
+ while (number >= RunningLengthWord32.largestrunninglengthcount) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(RunningLengthWord32.largestrunninglengthcount);
+ number -= RunningLengthWord32.largestrunninglengthcount;
+ }
+ if (number > 0) {
+ push_back(0);
+ this.rlw.position = this.actualsizeinwords - 1;
+ if (v)
+ this.rlw.setRunningBit(v);
+ this.rlw.setRunningLength(number);
+ }
+ }
+
+ /**
+ * Gets an EWAHIterator over the data. This is a customized iterator which
+ * iterates over run length word. For experts only.
+ *
+ * @return the EWAHIterator
+ */
+ public EWAHIterator32 getEWAHIterator() {
+ return new EWAHIterator32(this, this.actualsizeinwords);
+ }
+
+ /**
+ * @return the IteratingRLW iterator corresponding to this bitmap
+ */
+ public IteratingRLW32 getIteratingRLW() {
+ return new IteratingBufferedRunningLengthWord32(this);
+ }
+
+ /**
+ * get the locations of the true values as one vector. (may use more memory
+ * than iterator())
+ *
+ * @return the positions
+ */
+ public List getPositions() {
+ final ArrayList v = new ArrayList();
+ final EWAHIterator32 i = new EWAHIterator32(this,
+ this.actualsizeinwords);
+ int pos = 0;
+ while (i.hasNext()) {
+ RunningLengthWord32 localrlw = i.next();
+ if (localrlw.getRunningBit()) {
+ for (int j = 0; j < localrlw.getRunningLength(); ++j) {
+ for (int c = 0; c < wordinbits; ++c)
+ v.add(new Integer(pos++));
+ }
+ } else {
+ pos += wordinbits * localrlw.getRunningLength();
+ }
+ for (int j = 0; j < localrlw.getNumberOfLiteralWords(); ++j) {
+ int data = i.buffer()[i.literalWords() + j];
+ while (data != 0) {
+ final int ntz = Integer.numberOfTrailingZeros(data);
+ data ^= (1 << ntz);
+ v.add(new Integer(ntz + pos));
+ }
+ pos += wordinbits;
+ }
+ }
+ while ((v.size() > 0)
+ && (v.get(v.size() - 1).intValue() >= this.sizeinbits))
+ v.remove(v.size() - 1);
+ return v;
+ }
+
+ /**
+ * Returns a customized hash code (based on Karp-Rabin). Naturally, if the
+ * bitmaps are equal, they will hash to the same value.
+ *
+ */
+ @Override
+ public int hashCode() {
+ int karprabin = 0;
+ final int B = 31;
+ final EWAHIterator32 i = new EWAHIterator32(this,
+ this.actualsizeinwords);
+ while( i.hasNext() ) {
+ i.next();
+ if (i.rlw.getRunningBit() == true) {
+ karprabin += B * karprabin + i.rlw.getRunningLength();
+ }
+ for (int k = 0; k < i.rlw.getNumberOfLiteralWords(); ++k) {
+ karprabin += B * karprabin + this.buffer[k + i.literalWords()];
+ }
+ }
+ return karprabin;
+ }
+
+ /**
+ * Return true if the two EWAHCompressedBitmap have both at least one true bit
+ * in the same position. Equivalently, you could call "and" and check whether
+ * there is a set bit, but intersects will run faster if you don't need the
+ * result of the "and" operation.
+ *
+ * @param a
+ * the other bitmap
+ * @return whether they intersect
+ */
+ public boolean intersects(final EWAHCompressedBitmap32 a) {
+ NonEmptyVirtualStorage32 nevs = new NonEmptyVirtualStorage32();
+ try {
+ this.andToContainer(a, nevs);
+ } catch (NonEmptyVirtualStorage32.NonEmptyException nee) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Iterator over the set bits (this is what most people will want to use to
+ * browse the content if they want an iterator). The location of the set bits
+ * is returned, in increasing order.
+ *
+ * @return the int iterator
+ */
+ public IntIterator intIterator() {
+ return new IntIteratorImpl32(
+ new EWAHIterator32(this, this.actualsizeinwords));
+ }
+
+ /**
+ * iterate over the positions of the true values. This is similar to
+ * intIterator(), but it uses Java generics.
+ *
+ * @return the iterator
+ */
+ @Override
+public Iterator iterator() {
+ return new Iterator() {
+ @Override
+ public boolean hasNext() {
+ return this.under.hasNext();
+ }
+
+ @Override
+ public Integer next() {
+ return new Integer(this.under.next());
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("bitsets do not support remove");
+ }
+
+ final private IntIterator under = intIterator();
+ };
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param data
+ * the array of words to be added
+ * @param start
+ * the starting point
+ * @param number
+ * the number of words to add
+ */
+ private void negative_push_back(final int[] data, final int start,
+ final int number) {
+ while (this.actualsizeinwords + number >= this.buffer.length) {
+ final int oldbuffer[] = this.buffer;
+ if(this.actualsizeinwords + number < 32768)
+ this.buffer = new int[(this.actualsizeinwords + number) * 2];
+ else if ((this.actualsizeinwords + number) * 3 / 2 < this.actualsizeinwords + number)
+ this.buffer = new int[Integer.MAX_VALUE];
+ else
+ this.buffer = new int[(this.actualsizeinwords + number) * 3 / 2];
+ System.arraycopy(oldbuffer, 0, this.buffer, 0, oldbuffer.length);
+ this.rlw.parent.buffer = this.buffer;
+ }
+ for (int k = 0; k < number; ++k)
+ this.buffer[this.actualsizeinwords + k] = ~data[start + k];
+ this.actualsizeinwords += number;
+ }
+
+ /**
+ * Negate (bitwise) the current bitmap. To get a negated copy, do
+ * EWAHCompressedBitmap x= ((EWAHCompressedBitmap) mybitmap.clone()); x.not();
+ *
+ * The running time is proportional to the compressed size (as reported by
+ * sizeInBytes()).
+ *
+ */
+ @Override
+public void not() {
+ final EWAHIterator32 i = new EWAHIterator32(this,
+ this.actualsizeinwords);
+ if (!i.hasNext())
+ return;
+ while (true) {
+ final RunningLengthWord32 rlw1 = i.next();
+ rlw1.setRunningBit(!rlw1.getRunningBit());
+ for (int j = 0; j < rlw1.getNumberOfLiteralWords(); ++j) {
+ i.buffer()[i.literalWords() + j] = ~i.buffer()[i.literalWords() + j];
+ }
+ if (!i.hasNext()) {// must potentially adjust the last literal word
+ final int usedbitsinlast = this.sizeinbits % wordinbits;
+ if (usedbitsinlast == 0)
+ return;
+
+ if (rlw1.getNumberOfLiteralWords() == 0) {
+ if((rlw1.getRunningLength()>0) && (rlw1.getRunningBit())) {
+ rlw1.setRunningLength(rlw1.getRunningLength()-1);
+ this.addLiteralWord((~0) >>> (wordinbits - usedbitsinlast));
+ }
+ return;
+ }
+ i.buffer()[i.literalWords() + rlw1.getNumberOfLiteralWords() - 1] &= ((~0) >>> (wordinbits - usedbitsinlast));
+ return;
+ }
+
+ }
+ }
+
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise OR values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param a
+ * the other bitmap
+ * @return the EWAH compressed bitmap
+ */
+ @Override
+public EWAHCompressedBitmap32 or(final EWAHCompressedBitmap32 a) {
+ final EWAHCompressedBitmap32 container = new EWAHCompressedBitmap32();
+ container.reserve(this.actualsizeinwords + a.actualsizeinwords);
+ orToContainer(a, container);
+ return container;
+ }
+
+ /**
+ * Computes the bitwise or between the current bitmap and the bitmap "a".
+ * Stores the result in the container.
+ *
+ * @param a
+ * the other bitmap
+ * @param container
+ * where we store the result
+ */
+ public void orToContainer(final EWAHCompressedBitmap32 a, final BitmapStorage32 container) {
+ final EWAHIterator32 i = a.getEWAHIterator();
+ final EWAHIterator32 j = getEWAHIterator();
+ final IteratingBufferedRunningLengthWord32 rlwi = new IteratingBufferedRunningLengthWord32(i);
+ final IteratingBufferedRunningLengthWord32 rlwj = new IteratingBufferedRunningLengthWord32(j);
+ while ((rlwi.size()>0) && (rlwj.size()>0)) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingBufferedRunningLengthWord32 prey = i_is_prey ? rlwi
+ : rlwj;
+ final IteratingBufferedRunningLengthWord32 predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == true) {
+ container.addStreamOfEmptyWords(true, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ int index = prey.discharge(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k) {
+ container.add(rlwi.getLiteralWordAt(k) | rlwj.getLiteralWordAt(k));
+ }
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ final boolean i_remains = rlwi.size()>0;
+ final IteratingBufferedRunningLengthWord32 remaining = i_remains ? rlwi : rlwj;
+ remaining.discharge(container);
+ container.setSizeInBits(Math.max(sizeInBits(), a.sizeInBits()));
+ }
+ /**
+ * Returns the cardinality of the result of a bitwise OR of the values of the
+ * current bitmap with some other bitmap. Avoids needing to allocate an
+ * intermediate bitmap to hold the result of the OR.
+ *
+ * @param a
+ * the other bitmap
+ * @return the cardinality
+ */
+ public int orCardinality(final EWAHCompressedBitmap32 a) {
+ final BitCounter32 counter = new BitCounter32();
+ orToContainer(a, counter);
+ return counter.getCount();
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param data
+ * the word to be added
+ */
+ private void push_back(final int data) {
+ if (this.actualsizeinwords == this.buffer.length) {
+ final int oldbuffer[] = this.buffer;
+ if(oldbuffer.length < 32768)
+ this.buffer = new int[oldbuffer.length * 2];
+ else if (oldbuffer.length * 3 / 2 < oldbuffer.length)
+ this.buffer = new int[Integer.MAX_VALUE];
+ else
+ this.buffer = new int[oldbuffer.length * 3 / 2];
+ System.arraycopy(oldbuffer, 0, this.buffer, 0, oldbuffer.length);
+ this.rlw.parent.buffer = this.buffer;
+ }
+ this.buffer[this.actualsizeinwords++] = data;
+ }
+
+ /**
+ * For internal use.
+ *
+ * @param data
+ * the array of words to be added
+ * @param start
+ * the starting point
+ * @param number
+ * the number of words to add
+ */
+ private void push_back(final int[] data, final int start, final int number) {
+ if (this.actualsizeinwords + number >= this.buffer.length) {
+ final int oldbuffer[] = this.buffer;
+ if(this.actualsizeinwords + number < 32768)
+ this.buffer = new int[(this.actualsizeinwords + number) * 2];
+ else if((this.actualsizeinwords + number) * 3 / 2 < this.actualsizeinwords + number) //overflow
+ this.buffer = new int[Integer.MAX_VALUE];
+ else
+ this.buffer = new int[(this.actualsizeinwords + number) * 3 / 2];
+ System.arraycopy(oldbuffer, 0, this.buffer, 0, oldbuffer.length);
+ this.rlw.parent.buffer = this.buffer;
+ }
+ System.arraycopy(data, start, this.buffer, this.actualsizeinwords, number);
+ this.actualsizeinwords += number;
+ }
+
+ /*
+ * @see java.io.Externalizable#readExternal(java.io.ObjectInput)
+ */
+ @Override
+public void readExternal(ObjectInput in) throws IOException {
+ deserialize(in);
+ }
+
+ /**
+ * For internal use (trading off memory for speed).
+ *
+ * @param size
+ * the number of words to allocate
+ * @return True if the operation was a success.
+ */
+ private boolean reserve(final int size) {
+ if (size > this.buffer.length) {
+ final int oldbuffer[] = this.buffer;
+ this.buffer = new int[size];
+ System.arraycopy(oldbuffer, 0, this.buffer, 0, oldbuffer.length);
+ this.rlw.parent.buffer = this.buffer;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Serialize.
+ *
+ * @param out
+ * the DataOutput stream
+ * @throws IOException
+ * Signals that an I/O exception has occurred.
+ */
+ public void serialize(DataOutput out) throws IOException {
+ out.writeInt(this.sizeinbits);
+ out.writeInt(this.actualsizeinwords);
+ for (int k = 0; k < this.actualsizeinwords; ++k)
+ out.writeInt(this.buffer[k]);
+ out.writeInt(this.rlw.position);
+ }
+
+ /**
+ * Report the size required to serialize this bitmap
+ *
+ * @return the size in bytes
+ */
+ public int serializedSizeInBytes() {
+ return this.sizeInBytes() + 3 * 4;
+ }
+
+ /**
+ * Query the value of a single bit. Relying on this method when speed is
+ * needed is discouraged. The complexity is linear with the size of the
+ * bitmap.
+ *
+ * (This implementation is based on zhenjl's Go version of JavaEWAH.)
+ *
+ * @param i
+ * the bit we are interested in
+ * @return whether the bit is set to true
+ */
+ public boolean get(final int i) {
+ if ((i < 0) || (i >= this.sizeinbits))
+ return false;
+ int WordChecked = 0;
+ final IteratingRLW32 j = getIteratingRLW();
+ final int wordi = i / wordinbits;
+ while (WordChecked <= wordi) {
+ WordChecked += j.getRunningLength();
+ if (wordi < WordChecked) {
+ return j.getRunningBit();
+ }
+ if (wordi < WordChecked + j.getNumberOfLiteralWords()) {
+ final int w = j.getLiteralWordAt(wordi
+ - WordChecked);
+ return (w & (1 << i)) != 0;
+ }
+ WordChecked += j.getNumberOfLiteralWords();
+ j.next();
+ }
+ return false;
+ }
+
+ /**
+ * Set the bit at position i to true, the bits must be set in (strictly) increasing
+ * order. For example, set(15) and then set(7) will fail. You must do set(7)
+ * and then set(15).
+ *
+ * @param i
+ * the index
+ * @return true if the value was set (always true when i is greater or equal to sizeInBits()).
+ * @throws IndexOutOfBoundsException
+ * if i is negative or greater than Integer.MAX_VALUE - 32
+ */
+
+ public boolean set(final int i) {
+ if ((i > Integer.MAX_VALUE - wordinbits) || (i < 0))
+ throw new IndexOutOfBoundsException("Set values should be between 0 and "
+ + (Integer.MAX_VALUE - wordinbits));
+ if (i < this.sizeinbits)
+ return false;
+ // distance in words:
+ final int dist = (i + wordinbits) / wordinbits
+ - (this.sizeinbits + wordinbits - 1) / wordinbits;
+ this.sizeinbits = i + 1;
+ if (dist > 0) {// easy
+ if (dist > 1)
+ fastaddStreamOfEmptyWords(false, dist - 1);
+ addLiteralWord(1 << (i % wordinbits));
+ return true;
+ }
+ if (this.rlw.getNumberOfLiteralWords() == 0) {
+ this.rlw.setRunningLength(this.rlw.getRunningLength() - 1);
+ addLiteralWord(1 << (i % wordinbits));
+ return true;
+ }
+ this.buffer[this.actualsizeinwords - 1] |= 1 << (i % wordinbits);
+ if (this.buffer[this.actualsizeinwords - 1] == ~0) {
+ this.buffer[this.actualsizeinwords - 1] = 0;
+ --this.actualsizeinwords;
+ this.rlw.setNumberOfLiteralWords(this.rlw.getNumberOfLiteralWords() - 1);
+ // next we add one clean word
+ addEmptyWord(true);
+ }
+ return true;
+ }
+
+ /**
+ * Set the size in bits. This does not change the compressed bitmap.
+ *
+ */
+ @Override
+public void setSizeInBits(final int size) {
+ if((size+EWAHCompressedBitmap32.wordinbits-1)/EWAHCompressedBitmap32.wordinbits!= (this.sizeinbits+EWAHCompressedBitmap32.wordinbits-1)/EWAHCompressedBitmap32.wordinbits)
+ throw new RuntimeException("You can only reduce the size of the bitmap within the scope of the last word. To extend the bitmap, please call setSizeInbits(int,boolean): "+size+" "+this.sizeinbits);
+ this.sizeinbits = size;
+ }
+
+ /**
+ * Change the reported size in bits of the *uncompressed* bitmap represented
+ * by this compressed bitmap. It may change the underlying compressed bitmap.
+ * It is not possible to reduce the sizeInBits, but
+ * it can be extended. The new bits are set to false or true depending on the
+ * value of defaultvalue.
+ *
+ * @param size
+ * the size in bits
+ * @param defaultvalue
+ * the default boolean value
+ * @return true if the update was possible
+ */
+ public boolean setSizeInBits(final int size, final boolean defaultvalue) {
+ if (size < this.sizeinbits)
+ return false;
+ if (defaultvalue == false)
+ extendEmptyBits(this, this.sizeinbits, size);
+ else {
+ // next bit could be optimized
+ while (((this.sizeinbits % wordinbits) != 0) && (this.sizeinbits < size)) {
+ this.set(this.sizeinbits);
+ }
+ this.addStreamOfEmptyWords(defaultvalue, (size / wordinbits)
+ - this.sizeinbits / wordinbits);
+ // next bit could be optimized
+ while (this.sizeinbits < size) {
+ this.set(this.sizeinbits);
+ }
+ }
+ this.sizeinbits = size;
+ return true;
+ }
+
+ /**
+ * Returns the size in bits of the *uncompressed* bitmap represented by this
+ * compressed bitmap. Initially, the sizeInBits is zero. It is extended
+ * automatically when you set bits to true.
+ *
+ * @return the size in bits
+ */
+ @Override
+public int sizeInBits() {
+ return this.sizeinbits;
+ }
+
+ /**
+ * Report the *compressed* size of the bitmap (equivalent to memory usage,
+ * after accounting for some overhead).
+ *
+ * @return the size in bytes
+ */
+ @Override
+public int sizeInBytes() {
+ return this.actualsizeinwords * (wordinbits / 8);
+ }
+
+ /**
+ * Populate an array of (sorted integers) corresponding to the location of the
+ * set bits.
+ *
+ * @return the array containing the location of the set bits
+ */
+ public int[] toArray() {
+ int[] ans = new int[this.cardinality()];
+ int inanspos = 0;
+ int pos = 0;
+ final EWAHIterator32 i = new EWAHIterator32(this,
+ this.actualsizeinwords);
+ while (i.hasNext()) {
+ RunningLengthWord32 localrlw = i.next();
+ if (localrlw.getRunningBit()) {
+ for (int j = 0; j < localrlw.getRunningLength(); ++j) {
+ for (int c = 0; c < wordinbits; ++c) {
+ ans[inanspos++] = pos++;
+ }
+ }
+ } else {
+ pos += wordinbits * localrlw.getRunningLength();
+ }
+ for (int j = 0; j < localrlw.getNumberOfLiteralWords(); ++j) {
+ int data = i.buffer()[i.literalWords() + j];
+ if (!usetrailingzeros) {
+ for (int c = 0; c < wordinbits; ++c) {
+ if ((data & (1 << c)) != 0)
+ ans[inanspos++] = c + pos;
+ }
+ pos += wordinbits;
+ } else {
+ while (data != 0) {
+ final int ntz = Integer.numberOfTrailingZeros(data);
+ data ^= (1l << ntz);
+ ans[inanspos++] = ntz + pos;
+ }
+ pos += wordinbits;
+ }
+ }
+ }
+ return ans;
+
+ }
+
+ /**
+ * A more detailed string describing the bitmap (useful for debugging).
+ *
+ * @return the string
+ */
+ public String toDebugString() {
+ String ans = " EWAHCompressedBitmap, size in bits = " + this.sizeinbits
+ + " size in words = " + this.actualsizeinwords + "\n";
+ final EWAHIterator32 i = new EWAHIterator32(this,
+ this.actualsizeinwords);
+ while (i.hasNext()) {
+ RunningLengthWord32 localrlw = i.next();
+ if (localrlw.getRunningBit()) {
+ ans += localrlw.getRunningLength() + " 1x11\n";
+ } else {
+ ans += localrlw.getRunningLength() + " 0x00\n";
+ }
+ ans += localrlw.getNumberOfLiteralWords() + " dirties\n";
+ for (int j = 0; j < localrlw.getNumberOfLiteralWords(); ++j) {
+ int data = i.buffer()[i.literalWords() + j];
+ ans += "\t" + data + "\n";
+ }
+ }
+ return ans;
+ }
+
+ /**
+ * A string describing the bitmap.
+ *
+ * @return the string
+ */
+ @Override
+ public String toString() {
+ StringBuffer answer = new StringBuffer();
+ IntIterator i = this.intIterator();
+ answer.append("{");
+ if (i.hasNext())
+ answer.append(i.next());
+ while (i.hasNext()) {
+ answer.append(",");
+ answer.append(i.next());
+ }
+ answer.append("}");
+ return answer.toString();
+ }
+ /**
+ * swap the content of the bitmap with another.
+ *
+ * @param other
+ * bitmap to swap with
+ */
+ public void swap(final EWAHCompressedBitmap32 other) {
+ int[] tmp = this.buffer;
+ this.buffer = other.buffer;
+ other.buffer = tmp;
+
+ int tmp2 = this.rlw.position;
+ this.rlw.position = other.rlw.position;
+ other.rlw.position = tmp2;
+
+ int tmp3 = this.actualsizeinwords;
+ this.actualsizeinwords = other.actualsizeinwords;
+ other.actualsizeinwords = tmp3;
+
+ int tmp4 = this.sizeinbits;
+ this.sizeinbits = other.sizeinbits;
+ other.sizeinbits = tmp4;
+ }
+ /**
+ * Reduce the internal buffer to its minimal allowable size (given
+ * by this.actualsizeinwords). This can free memory.
+ */
+ public void trim() {
+ this.buffer = Arrays.copyOf(this.buffer, this.actualsizeinwords);
+ }
+
+ /*
+ * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
+ */
+ @Override
+public void writeExternal(ObjectOutput out) throws IOException {
+ serialize(out);
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise XOR values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param a
+ * the other bitmap
+ * @return the EWAH compressed bitmap
+ */
+ @Override
+public EWAHCompressedBitmap32 xor(final EWAHCompressedBitmap32 a) {
+ final EWAHCompressedBitmap32 container = new EWAHCompressedBitmap32();
+ container.reserve(this.actualsizeinwords + a.actualsizeinwords);
+ xorToContainer(a, container);
+ return container;
+ }
+
+ /**
+ * Computes a new compressed bitmap containing the bitwise XOR values of the
+ * current bitmap with some other bitmap.
+ *
+ * The running time is proportional to the sum of the compressed sizes (as
+ * reported by sizeInBytes()).
+ *
+ * @param a
+ * the other bitmap
+ * @param container
+ * where we store the result
+ */
+ public void xorToContainer(final EWAHCompressedBitmap32 a,
+ final BitmapStorage32 container) {
+ final EWAHIterator32 i = a.getEWAHIterator();
+ final EWAHIterator32 j = getEWAHIterator();
+ final IteratingBufferedRunningLengthWord32 rlwi = new IteratingBufferedRunningLengthWord32(i);
+ final IteratingBufferedRunningLengthWord32 rlwj = new IteratingBufferedRunningLengthWord32(j);
+ while ((rlwi.size()>0) && (rlwj.size()>0)) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingBufferedRunningLengthWord32 prey = i_is_prey ? rlwi : rlwj;
+ final IteratingBufferedRunningLengthWord32 predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ int index = prey.discharge(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ int index = prey.dischargeNegated(container, predator.getRunningLength());
+ container.addStreamOfEmptyWords(true, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) ^ rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ final boolean i_remains = rlwi.size()>0;
+ final IteratingBufferedRunningLengthWord32 remaining = i_remains ? rlwi : rlwj;
+ remaining.discharge(container);
+ container.setSizeInBits(Math.max(sizeInBits(), a.sizeInBits()));
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise XOR of the values of the
+ * current bitmap with some other bitmap. Avoids needing to allocate an
+ * intermediate bitmap to hold the result of the OR.
+ *
+ * @param a
+ * the other bitmap
+ * @return the cardinality
+ */
+ public int xorCardinality(final EWAHCompressedBitmap32 a) {
+ final BitCounter32 counter = new BitCounter32();
+ xorToContainer(a, counter);
+ return counter.getCount();
+ }
+
+ /**
+ * For internal use. Computes the bitwise and of the provided bitmaps and
+ * stores the result in the container.
+ *
+ * @param container
+ * where the result is stored
+ * @param bitmaps
+ * bitmaps to AND
+ */
+ public static void andWithContainer(final BitmapStorage32 container,
+ final EWAHCompressedBitmap32... bitmaps) {
+ if(bitmaps.length == 1) throw new IllegalArgumentException("Need at least one bitmap");
+ if(bitmaps.length == 2) {
+ bitmaps[0].andToContainer(bitmaps[1],container);
+ return;
+ }
+ EWAHCompressedBitmap32 answer = new EWAHCompressedBitmap32();
+ EWAHCompressedBitmap32 tmp = new EWAHCompressedBitmap32();
+ bitmaps[0].andToContainer(bitmaps[1], answer);
+ for(int k = 2; k < bitmaps.length - 1; ++k) {
+ answer.andToContainer(bitmaps[k], tmp);
+ tmp.swap(answer);
+ tmp.clear();
+ }
+ answer.andToContainer(bitmaps[bitmaps.length - 1], container);
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise AND values of the
+ * provided bitmaps.
+ *
+ * It may or may not be faster than doing the aggregation two-by-two (A.and(B).and(C)).
+ *
+ * If only one bitmap is provided, it is returned as is.
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param bitmaps
+ * bitmaps to AND together
+ * @return result of the AND
+ */
+ public static EWAHCompressedBitmap32 and(
+ final EWAHCompressedBitmap32... bitmaps) {
+ if(bitmaps.length == 1) return bitmaps[0];
+ if(bitmaps.length == 2) return bitmaps[0].and(bitmaps[1]);
+ EWAHCompressedBitmap32 answer = new EWAHCompressedBitmap32();
+ EWAHCompressedBitmap32 tmp = new EWAHCompressedBitmap32();
+ bitmaps[0].andToContainer(bitmaps[1], answer);
+ for(int k = 2; k < bitmaps.length; ++k) {
+ answer.andToContainer(bitmaps[k], tmp);
+ tmp.swap(answer);
+ tmp.clear();
+ }
+ return answer;
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise AND of the values of the
+ * provided bitmaps. Avoids needing to allocate an intermediate bitmap to hold
+ * the result of the AND.
+ *
+ * @param bitmaps
+ * bitmaps to AND
+ * @return the cardinality
+ */
+ public static int andCardinality(final EWAHCompressedBitmap32... bitmaps) {
+ if(bitmaps.length == 1) return bitmaps[0].cardinality();
+ final BitCounter32 counter = new BitCounter32();
+ andWithContainer(counter, bitmaps);
+ return counter.getCount();
+ }
+
+
+ /**
+ * Return a bitmap with the bit set to true at the given
+ * positions. The positions should be given in sorted order.
+ *
+ * (This is a convenience method.)
+ *
+ * @since 0.4.5
+ * @param setbits list of set bit positions
+ * @return the bitmap
+ */
+ public static EWAHCompressedBitmap32 bitmapOf(int ... setbits) {
+ EWAHCompressedBitmap32 a = new EWAHCompressedBitmap32();
+ for (int k : setbits)
+ a.set(k);
+ return a;
+ }
+
+
+
+
+ /**
+ * For internal use. This simply adds a stream of words made of zeroes so that
+ * we pad to the desired size.
+ *
+ * @param storage
+ * bitmap to extend
+ * @param currentSize
+ * current size (in bits)
+ * @param newSize
+ * new desired size (in bits)
+ */
+ private static void extendEmptyBits(final BitmapStorage32 storage,
+ final int currentSize, final int newSize) {
+ final int currentLeftover = currentSize % wordinbits;
+ final int finalLeftover = newSize % wordinbits;
+ storage.addStreamOfEmptyWords(false, (newSize / wordinbits) - currentSize
+ / wordinbits + (finalLeftover != 0 ? 1 : 0)
+ + (currentLeftover != 0 ? -1 : 0));
+ }
+
+ /**
+ * For internal use. Computes the bitwise or of the provided bitmaps and
+ * stores the result in the container.
+ * @param container where store the result
+ * @param bitmaps to be aggregated
+ */
+ public static void orWithContainer(final BitmapStorage32 container,
+ final EWAHCompressedBitmap32... bitmaps) {
+ if (bitmaps.length < 2)
+ throw new IllegalArgumentException("You should provide at least two bitmaps, provided "+bitmaps.length);
+ int size = 0;
+ int sinbits = 0;
+ for (EWAHCompressedBitmap32 b : bitmaps) {
+ size += b.sizeInBytes();
+ if (sinbits < b.sizeInBits())
+ sinbits = b.sizeInBits();
+ }
+ if (size * 8 > sinbits) {
+ FastAggregation32.bufferedorWithContainer(container, 65536, bitmaps);
+ } else {
+ FastAggregation32.orToContainer(container, bitmaps);
+ }
+ }
+
+ /**
+ * For internal use. Computes the bitwise xor of the provided bitmaps and
+ * stores the result in the container.
+ * @param container where store the result
+ * @param bitmaps to be aggregated
+ */
+ public static void xorWithContainer(final BitmapStorage32 container,
+ final EWAHCompressedBitmap32... bitmaps) {
+ if (bitmaps.length < 2)
+ throw new IllegalArgumentException("You should provide at least two bitmaps, provided "+bitmaps.length);
+ int size = 0;
+ int sinbits = 0;
+ for (EWAHCompressedBitmap32 b : bitmaps) {
+ size += b.sizeInBytes();
+ if (sinbits < b.sizeInBits())
+ sinbits = b.sizeInBits();
+ }
+ if (size * 8 > sinbits) {
+ FastAggregation32.bufferedxorWithContainer(container, 65536, bitmaps);
+ } else {
+ FastAggregation32.xorToContainer(container, bitmaps);
+ }
+ }
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise OR values of the
+ * provided bitmaps. This is typically faster than doing the aggregation
+ * two-by-two (A.or(B).or(C).or(D)).
+ *
+ * If only one bitmap is provided, it is returned as is.
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param bitmaps
+ * bitmaps to OR together
+ * @return result of the OR
+ */
+ public static EWAHCompressedBitmap32 or(
+ final EWAHCompressedBitmap32... bitmaps) {
+ if(bitmaps.length == 1) return bitmaps[0];
+ final EWAHCompressedBitmap32 container = new EWAHCompressedBitmap32();
+ int largestSize = 0;
+ for (EWAHCompressedBitmap32 bitmap : bitmaps) {
+ largestSize = Math.max(bitmap.actualsizeinwords, largestSize);
+ }
+ container.reserve((int) (largestSize * 1.5));
+ orWithContainer(container, bitmaps);
+ return container;
+ }
+
+
+ /**
+ * Returns a new compressed bitmap containing the bitwise XOR values of the
+ * provided bitmaps. This is typically faster than doing the aggregation
+ * two-by-two (A.xor(B).xor(C).xor(D)).
+ *
+ * If only one bitmap is provided, it is returned as is.
+ *
+ * If you are not planning on adding to the resulting bitmap, you may call the trim()
+ * method to reduce memory usage.
+ *
+ * @param bitmaps
+ * bitmaps to XOR together
+ * @return result of the XOR
+ */
+ public static EWAHCompressedBitmap32 xor(
+ final EWAHCompressedBitmap32... bitmaps) {
+ if(bitmaps.length == 1) return bitmaps[0];
+ final EWAHCompressedBitmap32 container = new EWAHCompressedBitmap32();
+ int largestSize = 0;
+ for (EWAHCompressedBitmap32 bitmap : bitmaps) {
+ largestSize = Math.max(bitmap.actualsizeinwords, largestSize);
+ }
+ container.reserve((int) (largestSize * 1.5));
+ xorWithContainer(container, bitmaps);
+ return container;
+ }
+
+ /**
+ * Returns the cardinality of the result of a bitwise OR of the values of the
+ * provided bitmaps. Avoids needing to allocate an intermediate bitmap to hold
+ * the result of the OR.
+ *
+ * @param bitmaps
+ * bitmaps to OR
+ * @return the cardinality
+ */
+ public static int orCardinality(final EWAHCompressedBitmap32... bitmaps) {
+ if(bitmaps.length == 1) return bitmaps[0].cardinality();
+ final BitCounter32 counter = new BitCounter32();
+ orWithContainer(counter, bitmaps);
+ return counter.getCount();
+ }
+
+ /** The actual size in words. */
+ int actualsizeinwords = 1;
+
+ /** The buffer (array of 32-bit words) */
+ int buffer[] = null;
+
+ /** The current (last) running length word. */
+ RunningLengthWord32 rlw = null;
+
+ /** sizeinbits: number of bits in the (uncompressed) bitmap. */
+ int sizeinbits = 0;
+
+ /**
+ * The Constant defaultbuffersize: default memory allocation when the object
+ * is constructed.
+ */
+ static final int defaultbuffersize = 4;
+
+ /** optimization option **/
+ public static final boolean usetrailingzeros = true;
+
+ /** whether we adjust after some aggregation by adding in zeroes **/
+ public static final boolean adjustContainerSizeWhenAggregating = true;
+
+ /** The Constant wordinbits represents the number of bits in a int. */
+ public static final int wordinbits = 32;
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/EWAHIterator32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/EWAHIterator32.java
new file mode 100644
index 000000000..dee08341d
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/EWAHIterator32.java
@@ -0,0 +1,98 @@
+package com.fr.third.googlecode.javaewah32;
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * The class EWAHIterator represents a special type of
+ * efficient iterator iterating over (uncompressed) words of bits.
+ *
+ * @author Daniel Lemire
+ * @since 0.5.0
+ *
+ */
+public final class EWAHIterator32 implements Cloneable {
+
+ /**
+ * Instantiates a new eWAH iterator.
+ *
+ * @param a the array of words
+ * @param sizeinwords the number of words that are significant in the array of words
+ */
+ public EWAHIterator32(final EWAHCompressedBitmap32 a, final int sizeinwords) {
+ this.rlw = new RunningLengthWord32(a, 0);
+ this.size = sizeinwords;
+ this.pointer = 0;
+ }
+
+ /**
+ * Allow expert developers to instantiate an EWAHIterator.
+ *
+ * @param bitmap we want to iterate over
+ * @return an iterator
+ */
+ public static EWAHIterator32 getEWAHIterator(EWAHCompressedBitmap32 bitmap) {
+ return bitmap.getEWAHIterator();
+ }
+
+ /**
+ * Access to the array of words
+ *
+ * @return the int[]
+ */
+ public int[] buffer() {
+ return this.rlw.parent.buffer;
+ }
+
+ /**
+ * Position of the literal words represented by this running length word.
+ *
+ * @return the int
+ */
+ public int literalWords() {
+ return this.pointer - this.rlw.getNumberOfLiteralWords();
+ }
+
+ /**
+ * Checks for next.
+ *
+ * @return true, if successful
+ */
+ public boolean hasNext() {
+ return this.pointer < this.size;
+ }
+
+ /**
+ * Next running length word.
+ *
+ * @return the running length word
+ */
+ public RunningLengthWord32 next() {
+ this.rlw.position = this.pointer;
+ this.pointer += this.rlw.getNumberOfLiteralWords() + 1;
+ return this.rlw;
+ }
+
+ @Override
+ public EWAHIterator32 clone() throws CloneNotSupportedException {
+ EWAHIterator32 ans = (EWAHIterator32) super.clone();
+ ans.rlw = this.rlw.clone();
+ ans.size = this.size;
+ ans.pointer = this.pointer;
+ return ans;
+ }
+
+ /** The pointer represent the location of the current running length
+ * word in the array of words (embedded in the rlw attribute). */
+ int pointer;
+
+ /** The current running length word. */
+ RunningLengthWord32 rlw;
+
+ /** The size in words. */
+ int size;
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/FastAggregation32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/FastAggregation32.java
new file mode 100644
index 000000000..7ecd45fcd
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/FastAggregation32.java
@@ -0,0 +1,377 @@
+package com.fr.third.googlecode.javaewah32;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.PriorityQueue;
+
+
+/**
+ * Fast algorithms to aggregate many bitmaps. These algorithms are just given as
+ * reference. They may not be faster than the corresponding methods in the
+ * EWAHCompressedBitmap class.
+ *
+ * @author Daniel Lemire
+ *
+ */
+public class FastAggregation32 {
+
+ /**
+ * Compute the and aggregate using a temporary uncompressed bitmap.
+ * @param bitmaps the source bitmaps
+ * @param bufsize buffer size used during the computation in 64-bit words (per input bitmap)
+ * @return the or aggregate.
+ */
+ public static EWAHCompressedBitmap32 bufferedand(final int bufsize,
+ final EWAHCompressedBitmap32... bitmaps) {
+ EWAHCompressedBitmap32 answer = new EWAHCompressedBitmap32();
+ bufferedandWithContainer(answer,bufsize, bitmaps);
+ return answer;
+ }
+ /**
+ * Compute the and aggregate using a temporary uncompressed bitmap.
+ *
+ * @param container where the aggregate is written
+ * @param bufsize buffer size used during the computation in 64-bit words (per input bitmap)
+ * @param bitmaps the source bitmaps
+ */
+ public static void bufferedandWithContainer(final BitmapStorage32 container,final int bufsize,
+ final EWAHCompressedBitmap32... bitmaps) {
+
+ java.util.LinkedList al = new java.util.LinkedList();
+ for (EWAHCompressedBitmap32 bitmap : bitmaps) {
+ al.add(new IteratingBufferedRunningLengthWord32(bitmap));
+ }
+ int[] hardbitmap = new int[bufsize*bitmaps.length];
+
+ for(IteratingRLW32 i : al)
+ if (i.size() == 0) {
+ al.clear();
+ break;
+ }
+
+ while (!al.isEmpty()) {
+ Arrays.fill(hardbitmap, ~0);
+ int effective = Integer.MAX_VALUE;
+ for(IteratingRLW32 i : al) {
+ int eff = IteratorAggregation32.inplaceand(hardbitmap, i);
+ if (eff < effective)
+ effective = eff;
+ }
+ for (int k = 0; k < effective; ++k)
+ container.add(hardbitmap[k]);
+ for(IteratingRLW32 i : al)
+ if (i.size() == 0) {
+ al.clear();
+ break;
+ }
+ }
+ }
+
+ /**
+ * Compute the or aggregate using a temporary uncompressed bitmap.
+ * @param bitmaps the source bitmaps
+ * @param bufsize buffer size used during the computation in 64-bit words
+ * @return the or aggregate.
+ */
+ public static EWAHCompressedBitmap32 bufferedor(final int bufsize,
+ final EWAHCompressedBitmap32... bitmaps) {
+ EWAHCompressedBitmap32 answer = new EWAHCompressedBitmap32();
+ bufferedorWithContainer(answer, bufsize, bitmaps);
+ return answer;
+ }
+
+ /**
+ * Compute the or aggregate using a temporary uncompressed bitmap.
+ *
+ * @param container where the aggregate is written
+ * @param bufsize buffer size used during the computation in 64-bit words
+ * @param bitmaps the source bitmaps
+ */
+ public static void bufferedorWithContainer(final BitmapStorage32 container,final int bufsize,
+ final EWAHCompressedBitmap32... bitmaps) {
+ int range = 0;
+ EWAHCompressedBitmap32[] sbitmaps = bitmaps.clone();
+ Arrays.sort(sbitmaps, new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) {
+ return b.sizeinbits - a.sizeinbits;
+ }
+ });
+
+ java.util.ArrayList al = new java.util.ArrayList();
+ for (EWAHCompressedBitmap32 bitmap : sbitmaps) {
+ if (bitmap.sizeinbits > range)
+ range = bitmap.sizeinbits;
+ al.add(new IteratingBufferedRunningLengthWord32(bitmap));
+ }
+ int[] hardbitmap = new int[bufsize];
+ int maxr = al.size();
+ while (maxr > 0) {
+ int effective = 0;
+ for (int k = 0; k < maxr; ++k) {
+ if (al.get(k).size() > 0) {
+ int eff = IteratorAggregation32.inplaceor(hardbitmap, al.get(k));
+ if (eff > effective)
+ effective = eff;
+ } else
+ maxr = k;
+ }
+ for (int k = 0; k < effective; ++k)
+ container.add(hardbitmap[k]);
+ Arrays.fill(hardbitmap, 0);
+
+ }
+ container.setSizeInBits(range);
+ }
+
+ /**
+ * Compute the xor aggregate using a temporary uncompressed bitmap.
+ * @param bitmaps the source bitmaps
+ * @param bufsize buffer size used during the computation in 64-bit words
+ * @return the xor aggregate.
+ */
+ public static EWAHCompressedBitmap32 bufferedxor(final int bufsize,
+ final EWAHCompressedBitmap32... bitmaps) {
+ EWAHCompressedBitmap32 answer = new EWAHCompressedBitmap32();
+ bufferedxorWithContainer(answer, bufsize, bitmaps);
+ return answer;
+ }
+
+
+ /**
+ * Compute the xor aggregate using a temporary uncompressed bitmap.
+ *
+ * @param container where the aggregate is written
+ * @param bufsize buffer size used during the computation in 64-bit words
+ * @param bitmaps the source bitmaps
+ */
+ public static void bufferedxorWithContainer(final BitmapStorage32 container,final int bufsize,
+ final EWAHCompressedBitmap32... bitmaps) {
+ int range = 0;
+ EWAHCompressedBitmap32[] sbitmaps = bitmaps.clone();
+ Arrays.sort(sbitmaps, new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) {
+ return b.sizeinbits - a.sizeinbits;
+ }
+ });
+
+ java.util.ArrayList al = new java.util.ArrayList();
+ for (EWAHCompressedBitmap32 bitmap : sbitmaps) {
+ if (bitmap.sizeinbits > range)
+ range = bitmap.sizeinbits;
+ al.add(new IteratingBufferedRunningLengthWord32(bitmap));
+ }
+ int[] hardbitmap = new int[bufsize];
+ int maxr = al.size();
+ while (maxr > 0) {
+ int effective = 0;
+ for (int k = 0; k < maxr; ++k) {
+ if (al.get(k).size() > 0) {
+ int eff = IteratorAggregation32.inplacexor(hardbitmap, al.get(k));
+ if (eff > effective)
+ effective = eff;
+ } else
+ maxr = k;
+ }
+ for (int k = 0; k < effective; ++k)
+ container.add(hardbitmap[k]);
+ Arrays.fill(hardbitmap, 0);
+ }
+ container.setSizeInBits(range);
+ }
+
+ /**
+ * Uses a priority queue to compute the or aggregate.
+ * @param container where we write the result
+ * @param bitmaps to be aggregated
+ */
+ public static void orToContainer(final BitmapStorage32 container,
+ final EWAHCompressedBitmap32 ... bitmaps) {
+ if(bitmaps.length < 2) throw new IllegalArgumentException("We need at least two bitmaps");
+ PriorityQueue pq = new PriorityQueue(bitmaps.length,
+ new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) {
+ return a.sizeInBytes() - b.sizeInBytes();
+ }
+ });
+ for (EWAHCompressedBitmap32 x : bitmaps) {
+ pq.add(x);
+ }
+ while (pq.size() > 2) {
+ EWAHCompressedBitmap32 x1 = pq.poll();
+ EWAHCompressedBitmap32 x2 = pq.poll();
+ pq.add(x1.or(x2));
+ }
+ pq.poll().orToContainer(pq.poll(), container);
+ }
+
+
+ /**
+ * Uses a priority queue to compute the xor aggregate.
+ * @param container where we write the result
+ * @param bitmaps to be aggregated
+ */
+ public static void xorToContainer(final BitmapStorage32 container,
+ final EWAHCompressedBitmap32 ... bitmaps) {
+ if(bitmaps.length < 2) throw new IllegalArgumentException("We need at least two bitmaps");
+ PriorityQueue pq = new PriorityQueue(bitmaps.length,
+ new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) {
+ return a.sizeInBytes() - b.sizeInBytes();
+ }
+ });
+ for (EWAHCompressedBitmap32 x : bitmaps) {
+ pq.add(x);
+ }
+ while (pq.size() > 2) {
+ EWAHCompressedBitmap32 x1 = pq.poll();
+ EWAHCompressedBitmap32 x2 = pq.poll();
+ pq.add(x1.xor(x2));
+ }
+ pq.poll().xorToContainer(pq.poll(), container);
+ }
+
+ /**
+ * For internal use. Computes the bitwise or of the provided bitmaps and
+ * stores the result in the container. (This used to be the default.)
+ *
+ * @deprecated use EWAHCompressedBitmap32.or instead
+ * @since 0.4.0
+ * @param container where store the result
+ * @param bitmaps to be aggregated
+ */
+ @Deprecated
+ public static void legacy_orWithContainer(final BitmapStorage32 container,
+ final EWAHCompressedBitmap32... bitmaps) {
+ if (bitmaps.length == 2) {
+ // should be more efficient
+ bitmaps[0].orToContainer(bitmaps[1], container);
+ return;
+ }
+
+ // Sort the bitmaps in descending order by sizeinbits. We will exhaust the
+ // sorted bitmaps from right to left.
+ final EWAHCompressedBitmap32[] sortedBitmaps = bitmaps.clone();
+ Arrays.sort(sortedBitmaps, new Comparator() {
+ @Override
+ public int compare(EWAHCompressedBitmap32 a, EWAHCompressedBitmap32 b) {
+ return a.sizeinbits < b.sizeinbits ? 1
+ : a.sizeinbits == b.sizeinbits ? 0 : -1;
+ }
+ });
+
+ final IteratingBufferedRunningLengthWord32[] rlws = new IteratingBufferedRunningLengthWord32[bitmaps.length];
+ int maxAvailablePos = 0;
+ for (EWAHCompressedBitmap32 bitmap : sortedBitmaps) {
+ EWAHIterator32 iterator = bitmap.getEWAHIterator();
+ if (iterator.hasNext()) {
+ rlws[maxAvailablePos++] = new IteratingBufferedRunningLengthWord32(
+ iterator);
+ }
+ }
+
+ if (maxAvailablePos == 0) { // this never happens...
+ container.setSizeInBits(0);
+ return;
+ }
+
+ int maxSize = sortedBitmaps[0].sizeinbits;
+
+ while (true) {
+ int maxOneRl = 0;
+ int minZeroRl = Integer.MAX_VALUE;
+ int minSize = Integer.MAX_VALUE;
+ int numEmptyRl = 0;
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord32 rlw = rlws[i];
+ int size = rlw.size();
+ if (size == 0) {
+ maxAvailablePos = i;
+ break;
+ }
+ minSize = Math.min(minSize, size);
+
+ if (rlw.getRunningBit()) {
+ int rl = rlw.getRunningLength();
+ maxOneRl = Math.max(maxOneRl, rl);
+ minZeroRl = 0;
+ if (rl == 0 && size > 0) {
+ numEmptyRl++;
+ }
+ } else {
+ int rl = rlw.getRunningLength();
+ minZeroRl = Math.min(minZeroRl, rl);
+ if (rl == 0 && size > 0) {
+ numEmptyRl++;
+ }
+ }
+ }
+
+ if (maxAvailablePos == 0) {
+ break;
+ } else if (maxAvailablePos == 1) {
+ // only one bitmap is left so just write the rest of it out
+ rlws[0].discharge(container);
+ break;
+ }
+
+ if (maxOneRl > 0) {
+ container.addStreamOfEmptyWords(true, maxOneRl);
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord32 rlw = rlws[i];
+ rlw.discardFirstWords(maxOneRl);
+ }
+ } else if (minZeroRl > 0) {
+ container.addStreamOfEmptyWords(false, minZeroRl);
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord32 rlw = rlws[i];
+ rlw.discardFirstWords(minZeroRl);
+ }
+ } else {
+ int index = 0;
+
+ if (numEmptyRl == 1) {
+ // if one rlw has literal words to process and the rest have a run of
+ // 0's we can write them out here
+ IteratingBufferedRunningLengthWord32 emptyRl = null;
+ int minNonEmptyRl = Integer.MAX_VALUE;
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord32 rlw = rlws[i];
+ int rl = rlw.getRunningLength();
+ if (rl == 0) {
+ assert emptyRl == null;
+ emptyRl = rlw;
+ } else {
+ minNonEmptyRl = Math.min(minNonEmptyRl, rl);
+ }
+ }
+ int wordsToWrite = minNonEmptyRl > minSize ? minSize : minNonEmptyRl;
+ if (emptyRl != null)
+ emptyRl.writeLiteralWords(wordsToWrite, container);
+ index += wordsToWrite;
+ }
+
+ while (index < minSize) {
+ int word = 0;
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord32 rlw = rlws[i];
+ if (rlw.getRunningLength() <= index) {
+ word |= rlw.getLiteralWordAt(index - rlw.getRunningLength());
+ }
+ }
+ container.add(word);
+ index++;
+ }
+ for (int i = 0; i < maxAvailablePos; i++) {
+ IteratingBufferedRunningLengthWord32 rlw = rlws[i];
+ rlw.discardFirstWords(minSize);
+ }
+ }
+ }
+ container.setSizeInBits(maxSize);
+ }
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/IntIteratorImpl32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IntIteratorImpl32.java
new file mode 100644
index 000000000..041b5d8ff
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IntIteratorImpl32.java
@@ -0,0 +1,90 @@
+package com.fr.third.googlecode.javaewah32;
+
+/*
+ * Copyright 2012, Google Inc.
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+import static com.fr.third.googlecode.javaewah32.EWAHCompressedBitmap32.wordinbits;
+
+import com.fr.third.googlecode.javaewah.IntIterator;
+
+/**
+ * The IntIteratorImpl32 is the 32 bit implementation of the IntIterator
+ * interface, which efficiently returns the stream of integers represented by an
+ * EWAHIterator32.
+ *
+ * @author Colby Ranger
+ * @since 0.5.6
+ */
+final class IntIteratorImpl32 implements IntIterator {
+
+ private final EWAHIterator32 ewahIter;
+ private final int[] ewahBuffer;
+ private int position;
+ private int runningLength;
+ private int word;
+ private int wordPosition;
+ private int wordLength;
+ private int literalPosition;
+ private boolean hasnext;
+
+ IntIteratorImpl32(EWAHIterator32 ewahIter) {
+ this.ewahIter = ewahIter;
+ this.ewahBuffer = ewahIter.buffer();
+ this.hasnext = this.moveToNext();
+ }
+
+ public final boolean moveToNext() {
+ while (!runningHasNext() && !literalHasNext()) {
+ if (!this.ewahIter.hasNext()) {
+ return false;
+ }
+ setRunningLengthWord(this.ewahIter.next());
+ }
+ return true;
+ }
+
+ @Override
+ public final boolean hasNext() {
+ return this.hasnext;
+ }
+
+ @Override
+ public final int next() {
+ final int answer;
+ if (runningHasNext()) {
+ answer = this.position++;
+ } else {
+ final int bit = Long.numberOfTrailingZeros(this.word);
+ this.word ^= (1l << bit);
+ answer = this.literalPosition + bit;
+ }
+ this.hasnext = this.moveToNext();
+ return answer;
+ }
+
+ private final void setRunningLengthWord(RunningLengthWord32 rlw) {
+ this.runningLength = wordinbits * rlw.getRunningLength()
+ + this.position;
+ if (!rlw.getRunningBit()) {
+ this.position = this.runningLength;
+ }
+
+ this.wordPosition = this.ewahIter.literalWords();
+ this.wordLength = this.wordPosition + rlw.getNumberOfLiteralWords();
+ }
+
+ private final boolean runningHasNext() {
+ return this.position < this.runningLength;
+ }
+
+ private final boolean literalHasNext() {
+ while (this.word == 0 && this.wordPosition < this.wordLength) {
+ this.word = this.ewahBuffer[this.wordPosition++];
+ this.literalPosition = this.position;
+ this.position += wordinbits;
+ }
+ return this.word != 0;
+ }
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/IntIteratorOverIteratingRLW32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IntIteratorOverIteratingRLW32.java
new file mode 100644
index 000000000..6ad8c47a2
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IntIteratorOverIteratingRLW32.java
@@ -0,0 +1,91 @@
+package com.fr.third.googlecode.javaewah32;
+
+import static com.fr.third.googlecode.javaewah.EWAHCompressedBitmap.wordinbits;
+
+import com.fr.third.googlecode.javaewah.IntIterator;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * Implementation of an IntIterator over an IteratingRLW.
+ *
+ *
+ */
+public class IntIteratorOverIteratingRLW32 implements IntIterator {
+ IteratingRLW32 parent;
+ private int position;
+ private int runningLength;
+ private int word;
+ private int wordPosition;
+ private int wordLength;
+ private int literalPosition;
+ private boolean hasnext;
+
+ /**
+ * @param p iterator we wish to iterate over
+ */
+ public IntIteratorOverIteratingRLW32(final IteratingRLW32 p) {
+ this.parent = p;
+ this.position = 0;
+ setupForCurrentRunningLengthWord();
+ this.hasnext = moveToNext();
+ }
+
+ /**
+ * @return whether we could find another set bit; don't move if there is an unprocessed value
+ */
+ private final boolean moveToNext() {
+ while (!runningHasNext() && !literalHasNext()) {
+ if (this.parent.next())
+ setupForCurrentRunningLengthWord();
+ else return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.hasnext;
+ }
+
+ @Override
+ public final int next() {
+ final int answer;
+ if (runningHasNext()) {
+ answer = this.position++;
+ } else {
+ final int bit = Long.numberOfTrailingZeros(this.word);
+ this.word ^= (1l << bit);
+ answer = this.literalPosition + bit;
+ }
+ this.hasnext = this.moveToNext();
+ return answer;
+ }
+
+ private final void setupForCurrentRunningLengthWord() {
+ this.runningLength = wordinbits * this.parent.getRunningLength()
+ + this.position;
+
+ if (!this.parent.getRunningBit()) {
+ this.position = this.runningLength;
+ }
+ this.wordPosition = 0;
+ this.wordLength = this.parent.getNumberOfLiteralWords();
+ }
+
+ private final boolean runningHasNext() {
+ return this.position < this.runningLength;
+ }
+
+ private final boolean literalHasNext() {
+ while (this.word == 0 && this.wordPosition < this.wordLength) {
+ this.word = this.parent.getLiteralWordAt(this.wordPosition++);
+ this.literalPosition = this.position;
+ this.position += wordinbits;
+ }
+ return this.word != 0;
+ }
+}
+
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratingBufferedRunningLengthWord32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratingBufferedRunningLengthWord32.java
new file mode 100644
index 000000000..f09906274
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratingBufferedRunningLengthWord32.java
@@ -0,0 +1,274 @@
+package com.fr.third.googlecode.javaewah32;
+
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * Mostly for internal use. Similar to BufferedRunningLengthWord32, but automatically
+ * advances to the next BufferedRunningLengthWord32 as words are discarded.
+ *
+ * @since 0.5.0
+ * @author Daniel Lemire and David McIntosh
+ */
+public final class IteratingBufferedRunningLengthWord32 implements IteratingRLW32, Cloneable {
+ /**
+ * Instantiates a new iterating buffered running length word.
+ *
+ * @param iterator iterator
+ */
+ public IteratingBufferedRunningLengthWord32(final EWAHIterator32 iterator) {
+ this.iterator = iterator;
+ this.brlw = new BufferedRunningLengthWord32(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords() + this.brlw.literalwordoffset;
+ this.buffer = this.iterator.buffer();
+ }
+
+
+ /**
+ * Instantiates a new iterating buffered running length word.
+ * @param bitmap over which we want to iterate
+ *
+ */
+ public IteratingBufferedRunningLengthWord32(final EWAHCompressedBitmap32 bitmap) {
+ this(EWAHIterator32.getEWAHIterator(bitmap));
+ }
+
+
+ /**
+ * Discard first words, iterating to the next running length word if needed.
+ *
+ * @param x the x
+ */
+ @Override
+public void discardFirstWords(int x) {
+
+ while (x > 0) {
+ if (this.brlw.RunningLength > x) {
+ this.brlw.RunningLength -= x;
+ return;
+ }
+ x -= this.brlw.RunningLength;
+ this.brlw.RunningLength = 0;
+ int toDiscard = x > this.brlw.NumberOfLiteralWords ? this.brlw.NumberOfLiteralWords : x;
+
+ this.literalWordStartPosition += toDiscard;
+ this.brlw.NumberOfLiteralWords -= toDiscard;
+ x -= toDiscard;
+ if ((x > 0) || (this.brlw.size() == 0)) {
+ if (!this.iterator.hasNext()) {
+ break;
+ }
+ this.brlw.reset(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords(); // + this.brlw.literalwordoffset == 0;
+ }
+ }
+ }
+ /**
+ * Write out up to max words, returns how many were written
+ * @param container target for writes
+ * @param max maximal number of writes
+ * @return how many written
+ */
+ public int discharge(BitmapStorage32 container, int max) {
+ int index = 0;
+ while ((index < max) && (size() > 0)) {
+ // first run
+ int pl = getRunningLength();
+ if (index + pl > max) {
+ pl = max - index;
+ }
+ container.addStreamOfEmptyWords(getRunningBit(), pl);
+ index += pl;
+ int pd = getNumberOfLiteralWords();
+ if (pd + index > max) {
+ pd = max - index;
+ }
+ writeLiteralWords(pd, container);
+ discardFirstWords(pl+pd);
+ index += pd;
+ }
+ return index;
+ }
+
+ /**
+ * Write out up to max words (negated), returns how many were written
+ * @param container target for writes
+ * @param max maximal number of writes
+ * @return how many written
+ */
+ public int dischargeNegated(BitmapStorage32 container, int max) {
+ int index = 0;
+ while ((index < max) && (size() > 0)) {
+ // first run
+ int pl = getRunningLength();
+ if (index + pl > max) {
+ pl = max - index;
+ }
+ container.addStreamOfEmptyWords(!getRunningBit(), pl);
+ index += pl;
+ int pd = getNumberOfLiteralWords();
+ if (pd + index > max) {
+ pd = max - index;
+ }
+ writeNegatedLiteralWords(pd, container);
+ discardFirstWords(pl+pd);
+ index += pd;
+ }
+ return index;
+ }
+
+ /**
+ * Move to the next RunningLengthWord
+ * @return whether the move was possible
+ */
+ @Override
+public boolean next() {
+ if (!this.iterator.hasNext()) {
+ this.brlw.NumberOfLiteralWords = 0;
+ this.brlw.RunningLength = 0;
+ return false;
+ }
+ this.brlw.reset(this.iterator.next());
+ this.literalWordStartPosition = this.iterator.literalWords(); // + this.brlw.literalwordoffset ==0
+ return true;
+ }
+
+ /**
+ * Write out the remain words, transforming them to zeroes.
+ * @param container target for writes
+ */
+ public void dischargeAsEmpty(BitmapStorage32 container) {
+ while(size()>0) {
+ container.addStreamOfEmptyWords(false, size());
+ discardFirstWords(size());
+ }
+ }
+
+ /**
+ * Write out the remaining words
+ * @param container target for writes
+ */
+ public void discharge(BitmapStorage32 container) {
+ // fix the offset
+ this.brlw.literalwordoffset = this.literalWordStartPosition - this.iterator.literalWords();
+ discharge(this.brlw, this.iterator, container);
+ }
+
+ /**
+ * Get the nth literal word for the current running length word
+ * @param index zero based index
+ * @return the literal word
+ */
+ @Override
+public int getLiteralWordAt(int index) {
+ return this.buffer[this.literalWordStartPosition + index];
+ }
+
+ /**
+ * Gets the number of literal words for the current running length word.
+ *
+ * @return the number of literal words
+ */
+ @Override
+public int getNumberOfLiteralWords() {
+ return this.brlw.NumberOfLiteralWords;
+ }
+
+ /**
+ * Gets the running bit.
+ *
+ * @return the running bit
+ */
+ @Override
+public boolean getRunningBit() {
+ return this.brlw.RunningBit;
+ }
+
+ /**
+ * Gets the running length.
+ *
+ * @return the running length
+ */
+ @Override
+public int getRunningLength() {
+ return this.brlw.RunningLength;
+ }
+
+ /**
+ * Size in uncompressed words of the current running length word.
+ *
+ * @return the int
+ */
+ @Override
+public int size() {
+ return this.brlw.size();
+ }
+
+ /**
+ * write the first N literal words to the target bitmap. Does not discard the words or perform iteration.
+ * @param numWords number of words to be written
+ * @param container where we write the data
+ */
+ public void writeLiteralWords(int numWords, BitmapStorage32 container) {
+ container.addStreamOfLiteralWords(this.buffer, this.literalWordStartPosition, numWords);
+ }
+
+
+ /**
+ * write the first N literal words (negated) to the target bitmap. Does not discard the words or perform iteration.
+ * @param numWords number of words to be written
+ * @param container where we write the data
+ */
+ public void writeNegatedLiteralWords(int numWords, BitmapStorage32 container) {
+ container.addStreamOfNegatedLiteralWords(this.buffer, this.literalWordStartPosition, numWords);
+ }
+
+
+ /**
+ * For internal use. (One could use the non-static discharge method instead,
+ * but we expect them to be slower.)
+ *
+ * @param initialWord
+ * the initial word
+ * @param iterator
+ * the iterator
+ * @param container
+ * the container
+ */
+ protected static void discharge(
+ final BufferedRunningLengthWord32 initialWord,
+ final EWAHIterator32 iterator, final BitmapStorage32 container) {
+ BufferedRunningLengthWord32 runningLengthWord = initialWord;
+ for (;;) {
+ final int runningLength = runningLengthWord.getRunningLength();
+ container.addStreamOfEmptyWords(runningLengthWord.getRunningBit(),
+ runningLength);
+ container.addStreamOfLiteralWords(iterator.buffer(), iterator.literalWords()
+ + runningLengthWord.literalwordoffset,
+ runningLengthWord.getNumberOfLiteralWords());
+ if (!iterator.hasNext())
+ break;
+ runningLengthWord = new BufferedRunningLengthWord32(iterator.next());
+ }
+ }
+
+
+
+ @Override
+public IteratingBufferedRunningLengthWord32 clone() throws CloneNotSupportedException {
+ IteratingBufferedRunningLengthWord32 answer = (IteratingBufferedRunningLengthWord32) super.clone();
+ answer.brlw = this.brlw.clone();
+ answer.buffer = this.buffer;
+ answer.iterator = this.iterator.clone();
+ answer.literalWordStartPosition = this.literalWordStartPosition;
+ return answer;
+ }
+
+ private BufferedRunningLengthWord32 brlw;
+ private int[] buffer;
+ private int literalWordStartPosition;
+ private EWAHIterator32 iterator;
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratingRLW32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratingRLW32.java
new file mode 100644
index 000000000..1ebeb2f62
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratingRLW32.java
@@ -0,0 +1,42 @@
+package com.fr.third.googlecode.javaewah32;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * High-level iterator over a compressed bitmap.
+ *
+ */
+public interface IteratingRLW32 {
+ /**
+ * @return whether there is more
+ */
+ public boolean next() ;
+ /**
+ * @param index where the literal word is
+ * @return the literal word at the given index.
+ */
+ public int getLiteralWordAt(int index);
+ /**
+ * @return the number of literal (non-fill) words
+ */
+ public int getNumberOfLiteralWords() ;
+ /**
+ * @return the bit used for the fill bits
+ */
+ public boolean getRunningBit() ;
+ /**
+ * @return sum of getRunningLength() and getNumberOfLiteralWords()
+ */
+ public int size() ;
+ /**
+ * @return length of the run of fill words
+ */
+ public int getRunningLength() ;
+ /**
+ * @param x the number of words to discard
+ */
+ public void discardFirstWords(int x);
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratorAggregation32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratorAggregation32.java
new file mode 100644
index 000000000..cfd5a0adc
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratorAggregation32.java
@@ -0,0 +1,601 @@
+package com.fr.third.googlecode.javaewah32;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import com.fr.third.googlecode.javaewah.CloneableIterator;
+
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * Set of helper functions to aggregate bitmaps.
+ *
+ */
+public class IteratorAggregation32 {
+ /**
+ * @param x iterator to negate
+ * @return negated version of the iterator
+ */
+ public static IteratingRLW32 not(final IteratingRLW32 x) {
+ return new IteratingRLW32() {
+
+ @Override
+ public boolean next() {
+ return x.next();
+ }
+
+ @Override
+ public int getLiteralWordAt(int index) {
+ return ~x.getLiteralWordAt(index);
+ }
+
+ @Override
+ public int getNumberOfLiteralWords() {
+ return x.getNumberOfLiteralWords();
+ }
+
+ @Override
+ public boolean getRunningBit() {
+ return ! x.getRunningBit();
+ }
+
+ @Override
+ public int size() {
+ return x.size();
+ }
+
+ @Override
+ public int getRunningLength() {
+ return x.getRunningLength();
+ }
+
+ @Override
+ public void discardFirstWords(int y) {
+ x.discardFirstWords(y);
+ }
+
+ };
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al iterators to aggregate
+ * @return and aggregate
+ */
+ public static IteratingRLW32 bufferedand(final IteratingRLW32... al) {
+ return bufferedand (DEFAULTMAXBUFSIZE,al);
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al iterators to aggregate
+ * @param bufsize size of the internal buffer used by the iterator in 64-bit words
+ * @return and aggregate
+ */
+ public static IteratingRLW32 bufferedand(final int bufsize, final IteratingRLW32... al) {
+ if (al.length == 0)
+ throw new IllegalArgumentException("Need at least one iterator");
+ if (al.length == 1)
+ return al[0];
+ final LinkedList basell = new LinkedList();
+ for (IteratingRLW32 i : al)
+ basell.add(i);
+ return new BufferedIterator32(new AndIt(basell,bufsize));
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al iterators to aggregate
+ * @return or aggregate
+ */
+ public static IteratingRLW32 bufferedor(final IteratingRLW32... al) {
+ return bufferedor(DEFAULTMAXBUFSIZE,al);
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al iterators to aggregate
+ * @param bufsize size of the internal buffer used by the iterator in 64-bit words
+ * @return or aggregate
+ */
+ public static IteratingRLW32 bufferedor(final int bufsize, final IteratingRLW32... al) {
+ if (al.length == 0)
+ throw new IllegalArgumentException("Need at least one iterator");
+ if (al.length == 1)
+ return al[0];
+
+ final LinkedList basell = new LinkedList();
+ for (IteratingRLW32 i : al)
+ basell.add(i);
+ return new BufferedIterator32(new ORIt(basell,bufsize));
+ }
+
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al iterators to aggregate
+ * @return xor aggregate
+ */
+ public static IteratingRLW32 bufferedxor(final IteratingRLW32... al) {
+ return bufferedxor (DEFAULTMAXBUFSIZE,al);
+ }
+ /**
+ * Aggregate the iterators using a bitmap buffer.
+ *
+ * @param al iterators to aggregate
+ * @param bufsize size of the internal buffer used by the iterator in 64-bit words
+ * @return xor aggregate
+ */
+ public static IteratingRLW32 bufferedxor(final int bufsize, final IteratingRLW32... al) {
+ if (al.length == 0)
+ throw new IllegalArgumentException("Need at least one iterator");
+ if (al.length == 1)
+ return al[0];
+
+ final LinkedList basell = new LinkedList();
+ for (IteratingRLW32 i : al)
+ basell.add(i);
+ return new BufferedIterator32(new XORIt(basell,bufsize));
+ }
+ /**
+ * Write out the content of the iterator, but as if it were all zeros.
+ *
+ * @param container
+ * where we write
+ * @param i
+ * the iterator
+ */
+ protected static void dischargeAsEmpty(final BitmapStorage32 container,
+ final IteratingRLW32 i) {
+ while (i.size() > 0) {
+ container.addStreamOfEmptyWords(false, i.size());
+ i.next();
+
+ }
+ }
+
+ /**
+ * Write out up to max words, returns how many were written
+ * @param container target for writes
+ * @param i source of data
+ * @param max maximal number of writes
+ * @return how many written
+ */
+ protected static int discharge(final BitmapStorage32 container, IteratingRLW32 i, int max) {
+ int counter = 0;
+ while (i.size() > 0 && counter < max) {
+ int L1 = i.getRunningLength();
+ if (L1 > 0) {
+ if (L1 + counter > max)
+ L1 = max - counter;
+ container.addStreamOfEmptyWords(i.getRunningBit(), L1);
+ counter += L1;
+ }
+ int L = i.getNumberOfLiteralWords();
+ if(L + counter > max) L = max - counter;
+ for (int k = 0; k < L; ++k) {
+ container.add(i.getLiteralWordAt(k));
+ }
+ counter += L;
+ i.discardFirstWords(L+L1);
+ }
+ return counter;
+ }
+
+ /**
+ * Write out up to max negated words, returns how many were written
+ * @param container target for writes
+ * @param i source of data
+ * @param max maximal number of writes
+ * @return how many written
+ */
+ protected static int dischargeNegated(final BitmapStorage32 container, IteratingRLW32 i, int max) {
+ int counter = 0;
+ while (i.size() > 0 && counter < max) {
+ int L1 = i.getRunningLength();
+ if (L1 > 0) {
+ if (L1 + counter > max)
+ L1 = max - counter;
+ container.addStreamOfEmptyWords(i.getRunningBit(), L1);
+ counter += L1;
+ }
+ int L = i.getNumberOfLiteralWords();
+ if(L + counter > max) L = max - counter;
+ for (int k = 0; k < L; ++k) {
+ container.add(i.getLiteralWordAt(k));
+ }
+ counter += L;
+ i.discardFirstWords(L+L1);
+ }
+ return counter;
+ }
+
+ static void andToContainer(final BitmapStorage32 container,
+ int desiredrlwcount, final IteratingRLW32 rlwi, IteratingRLW32 rlwj) {
+ while ((rlwi.size()>0) && (rlwj.size()>0) && (desiredrlwcount-- >0) ) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingRLW32 prey = i_is_prey ? rlwi : rlwj;
+ final IteratingRLW32 predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ container.addStreamOfEmptyWords(false, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ final int index = discharge(container, prey, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ desiredrlwcount -= nbre_literal;
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) & rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ }
+
+ static void andToContainer(final BitmapStorage32 container,
+ final IteratingRLW32 rlwi, IteratingRLW32 rlwj) {
+ while ((rlwi.size()>0) && (rlwj.size()>0) ) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingRLW32 prey = i_is_prey ? rlwi : rlwj;
+ final IteratingRLW32 predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ container.addStreamOfEmptyWords(false, predator.getRunningLength());
+ prey.discardFirstWords(predator.getRunningLength());
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ final int index = discharge(container, prey, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) & rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ }
+
+
+ /**
+ * Compute the first few words of the XOR aggregate between two iterators.
+ *
+ * @param container where to write
+ * @param desiredrlwcount number of words to be written (max)
+ * @param rlwi first iterator to aggregate
+ * @param rlwj second iterator to aggregate
+ */
+ public static void xorToContainer(final BitmapStorage32 container,
+ int desiredrlwcount, final IteratingRLW32 rlwi, IteratingRLW32 rlwj) {
+ while ((rlwi.size()>0) && (rlwj.size()>0) && (desiredrlwcount-- >0) ) {
+ while ((rlwi.getRunningLength() > 0) || (rlwj.getRunningLength() > 0)) {
+ final boolean i_is_prey = rlwi.getRunningLength() < rlwj
+ .getRunningLength();
+ final IteratingRLW32 prey = i_is_prey ? rlwi : rlwj;
+ final IteratingRLW32 predator = i_is_prey ? rlwj
+ : rlwi;
+ if (predator.getRunningBit() == false) {
+ int index = discharge(container, prey, predator.getRunningLength());
+ container.addStreamOfEmptyWords(false, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ } else {
+ int index = dischargeNegated(container, prey, predator.getRunningLength());
+ container.addStreamOfEmptyWords(true, predator.getRunningLength()
+ - index);
+ predator.discardFirstWords(predator.getRunningLength());
+ }
+ }
+ final int nbre_literal = Math.min(rlwi.getNumberOfLiteralWords(),
+ rlwj.getNumberOfLiteralWords());
+ if (nbre_literal > 0) {
+ desiredrlwcount -= nbre_literal;
+ for (int k = 0; k < nbre_literal; ++k)
+ container.add(rlwi.getLiteralWordAt(k) ^ rlwj.getLiteralWordAt(k));
+ rlwi.discardFirstWords(nbre_literal);
+ rlwj.discardFirstWords(nbre_literal);
+ }
+ }
+ }
+
+ protected static int inplaceor(int[] bitmap,
+ IteratingRLW32 i) {
+ int pos = 0;
+ int s;
+ while ((s = i.size()) > 0) {
+ if (pos + s < bitmap.length) {
+ final int L = i.getRunningLength();
+ if (i.getRunningBit())
+ Arrays.fill(bitmap, pos, pos + L, ~0);
+ pos += L;
+ final int LR = i.getNumberOfLiteralWords();
+ for (int k = 0; k < LR; ++k)
+ bitmap[pos++] |= i.getLiteralWordAt(k);
+ if (!i.next()) {
+ return pos;
+ }
+ } else {
+ int howmany = bitmap.length - pos;
+ int L = i.getRunningLength();
+ if (pos + L > bitmap.length) {
+ if (i.getRunningBit()) {
+ Arrays.fill(bitmap, pos, bitmap.length, ~0);
+ }
+ i.discardFirstWords(howmany);
+ return bitmap.length;
+ }
+ if (i.getRunningBit())
+ Arrays.fill(bitmap, pos, pos + L, ~0);
+ pos += L;
+ for (int k = 0; pos < bitmap.length; ++k)
+ bitmap[pos++] |= i.getLiteralWordAt(k);
+ i.discardFirstWords(howmany);
+ return pos;
+ }
+ }
+ return pos;
+ }
+
+
+ protected static int inplacexor(int[] bitmap,
+ IteratingRLW32 i) {
+ int pos = 0;
+ int s;
+ while ((s = i.size()) > 0) {
+ if (pos + s < bitmap.length) {
+ final int L = i.getRunningLength();
+ if (i.getRunningBit()) {
+ for(int k = pos ; k < pos + L; ++k)
+ bitmap[k] = ~bitmap[k];
+ }
+ pos += L;
+ final int LR = i.getNumberOfLiteralWords();
+ for (int k = 0; k < LR; ++k)
+ bitmap[pos++] ^= i.getLiteralWordAt(k);
+ if (!i.next()) {
+ return pos;
+ }
+ } else {
+ int howmany = bitmap.length - pos;
+ int L = i.getRunningLength();
+ if (pos + L > bitmap.length) {
+ if (i.getRunningBit()) {
+ for(int k = pos ; k < bitmap.length; ++k)
+ bitmap[k] = ~bitmap[k];
+ }
+ i.discardFirstWords(howmany);
+ return bitmap.length;
+ }
+ if (i.getRunningBit())
+ for(int k = pos ; k < pos + L; ++k)
+ bitmap[k] = ~bitmap[k];
+ pos += L;
+ for (int k = 0; pos < bitmap.length; ++k)
+ bitmap[pos++] ^= i.getLiteralWordAt(k);
+ i.discardFirstWords(howmany);
+ return pos;
+ }
+ }
+ return pos;
+ }
+ protected static int inplaceand(int[] bitmap,
+ IteratingRLW32 i) {
+ int pos = 0;
+ int s;
+ while ((s = i.size()) > 0) {
+ if (pos + s < bitmap.length) {
+ final int L = i.getRunningLength();
+ if (!i.getRunningBit()) {
+ for(int k = pos ; k < pos + L; ++k)
+ bitmap[k] = 0;
+ }
+ pos += L;
+ final int LR = i.getNumberOfLiteralWords();
+ for (int k = 0; k < LR; ++k)
+ bitmap[pos++] &= i.getLiteralWordAt(k);
+ if (!i.next()) {
+ return pos;
+ }
+ } else {
+ int howmany = bitmap.length - pos;
+ int L = i.getRunningLength();
+ if (pos + L > bitmap.length) {
+ if (!i.getRunningBit()) {
+ for(int k = pos ; k < bitmap.length; ++k)
+ bitmap[k] = 0;
+ }
+ i.discardFirstWords(howmany);
+ return bitmap.length;
+ }
+ if (!i.getRunningBit())
+ for(int k = pos ; k < pos + L; ++k)
+ bitmap[k] = 0;
+ pos += L;
+ for (int k = 0; pos < bitmap.length; ++k)
+ bitmap[pos++] &= i.getLiteralWordAt(k);
+ i.discardFirstWords(howmany);
+ return pos;
+ }
+ }
+ return pos;
+ }
+
+ /**
+ * An optimization option. Larger values may improve speed, but at
+ * the expense of memory.
+ */
+ public final static int DEFAULTMAXBUFSIZE = 65536;
+
+
+}
+
+
+class ORIt implements CloneableIterator {
+ EWAHCompressedBitmap32 buffer = new EWAHCompressedBitmap32();
+ int[] hardbitmap;
+ LinkedList ll;
+
+ ORIt(LinkedList basell, final int bufsize) {
+ this.ll = basell;
+ this.hardbitmap = new int[bufsize];
+ }
+
+ @Override
+ public XORIt clone() throws CloneNotSupportedException {
+ XORIt answer = (XORIt) super.clone();
+ answer.buffer = this.buffer.clone();
+ answer.hardbitmap = this.hardbitmap.clone();
+ answer.ll = (LinkedList) this.ll.clone();
+ return answer;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !this.ll.isEmpty();
+ }
+
+ @Override
+ public EWAHIterator32 next() {
+ this.buffer.clear();
+ int effective = 0;
+ Iterator i = this.ll.iterator();
+ while (i.hasNext()) {
+ IteratingRLW32 rlw = i.next();
+ if (rlw.size() > 0) {
+ int eff = IteratorAggregation32.inplaceor(this.hardbitmap, rlw);
+ if (eff > effective)
+ effective = eff;
+ } else
+ i.remove();
+ }
+ for (int k = 0; k < effective; ++k)
+ this.buffer.add(this.hardbitmap[k]);
+ Arrays.fill(this.hardbitmap, 0);
+ return this.buffer.getEWAHIterator();
+ }
+}
+
+class XORIt implements CloneableIterator {
+ EWAHCompressedBitmap32 buffer = new EWAHCompressedBitmap32();
+ int[] hardbitmap;
+ LinkedList ll;
+
+ XORIt(LinkedList basell, final int bufsize) {
+ this.ll = basell;
+ this.hardbitmap = new int[bufsize];
+
+ }
+
+ @Override
+ public XORIt clone() throws CloneNotSupportedException {
+ XORIt answer = (XORIt) super.clone();
+ answer.buffer = this.buffer.clone();
+ answer.hardbitmap = this.hardbitmap.clone();
+ answer.ll = (LinkedList) this.ll.clone();
+ return answer;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !this.ll.isEmpty();
+ }
+
+ @Override
+ public EWAHIterator32 next() {
+ this.buffer.clear();
+ int effective = 0;
+ Iterator i = this.ll.iterator();
+ while (i.hasNext()) {
+ IteratingRLW32 rlw = i.next();
+ if (rlw.size() > 0) {
+ int eff = IteratorAggregation32.inplacexor(this.hardbitmap, rlw);
+ if (eff > effective)
+ effective = eff;
+ } else
+ i.remove();
+ }
+ for (int k = 0; k < effective; ++k)
+ this.buffer.add(this.hardbitmap[k]);
+ Arrays.fill(this.hardbitmap, 0);
+ return this.buffer.getEWAHIterator();
+ }
+}
+
+class AndIt implements CloneableIterator {
+ EWAHCompressedBitmap32 buffer = new EWAHCompressedBitmap32();
+ LinkedList ll;
+ int buffersize;
+
+ public AndIt(LinkedList basell, final int bufsize) {
+ this.ll = basell;
+ this.buffersize = bufsize;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return !this.ll.isEmpty();
+ }
+
+ @Override
+ public AndIt clone() throws CloneNotSupportedException {
+ AndIt answer = (AndIt) super.clone();
+ answer.buffer = this.buffer.clone();
+ answer.ll = (LinkedList) this.ll.clone();
+ return answer;
+ }
+
+ @Override
+ public EWAHIterator32 next() {
+ this.buffer.clear();
+ IteratorAggregation32.andToContainer(this.buffer, this.buffersize * this.ll.size(),
+ this.ll.get(0), this.ll.get(1));
+ if (this.ll.size() > 2) {
+ Iterator i = this.ll.iterator();
+ i.next();
+ i.next();
+ EWAHCompressedBitmap32 tmpbuffer = new EWAHCompressedBitmap32();
+ while (i.hasNext() && this.buffer.sizeInBytes() > 0) {
+ IteratorAggregation32.andToContainer(tmpbuffer,
+ this.buffer.getIteratingRLW(), i.next());
+ this.buffer.swap(tmpbuffer);
+ tmpbuffer.clear();
+ }
+ }
+ Iterator i = this.ll.iterator();
+ while(i.hasNext()) {
+ if(i.next().size() == 0) {
+ this.ll.clear();
+ break;
+ }
+ }
+ return this.buffer.getEWAHIterator();
+ }
+
+}
\ No newline at end of file
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratorUtil32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratorUtil32.java
new file mode 100644
index 000000000..d8e415101
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/IteratorUtil32.java
@@ -0,0 +1,135 @@
+package com.fr.third.googlecode.javaewah32;
+
+import java.util.Iterator;
+
+import com.fr.third.googlecode.javaewah.IntIterator;
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * Convenience functions for working over iterators
+ *
+ */
+public class IteratorUtil32 {
+
+ /**
+ * @param i iterator we wish to iterate over
+ * @return an iterator over the set bits corresponding to the iterator
+ */
+ public static IntIterator toSetBitsIntIterator(final IteratingRLW32 i) {
+ return new IntIteratorOverIteratingRLW32(i);
+ }
+
+ /**
+ * @param i iterator we wish to iterate over
+ * @return an iterator over the set bits corresponding to the iterator
+ */
+ public static Iterator toSetBitsIterator(final IteratingRLW32 i) {
+ return new Iterator() {
+ @Override
+ public boolean hasNext() {
+ return this.under.hasNext();
+ }
+
+ @Override
+ public Integer next() {
+ return new Integer(this.under.next());
+ }
+
+ @Override
+ public void remove() {
+ }
+
+ final private IntIterator under = toSetBitsIntIterator(i);
+ };
+
+ }
+
+ /**
+ * Turn an iterator into a bitmap
+ * @param i iterator we wish to materialize
+ * @param c where we write
+ */
+ public static void materialize(final IteratingRLW32 i, final BitmapStorage32 c) {
+ while (true) {
+ if (i.getRunningLength() > 0) {
+ c.addStreamOfEmptyWords(i.getRunningBit(), i.getRunningLength());
+ }
+ for (int k = 0; k < i.getNumberOfLiteralWords(); ++k)
+ c.add(i.getLiteralWordAt(k));
+ if (!i.next())
+ break;
+ }
+ }
+
+ /**
+ * @param i iterator we wish to iterate over
+ * @return the cardinality (number of set bits) corresponding to the iterator
+ */
+ public static int cardinality(final IteratingRLW32 i) {
+ int answer = 0;
+ while (true) {
+ if(i.getRunningBit()) answer += i.getRunningLength() * EWAHCompressedBitmap32.wordinbits;
+ for (int k = 0; k < i.getNumberOfLiteralWords(); ++k)
+ answer += Long.bitCount(i.getLiteralWordAt(k));
+ if(!i.next()) break;
+ }
+ return answer;
+ }
+
+ /**
+ *
+ * @param x set of bitmaps we wish to iterate over
+ * @return an array of iterators corresponding to the array of bitmaps
+ */
+ public static IteratingRLW32[] toIterators(final EWAHCompressedBitmap32... x) {
+ IteratingRLW32[] X = new IteratingRLW32[x.length];
+ for (int k = 0; k < X.length; ++k) {
+ X[k] = new IteratingBufferedRunningLengthWord32(x[k]);
+ }
+ return X;
+ }
+ /**
+ * Turn an iterator into a bitmap
+ *
+ * @param i iterator we wish to materialize
+ * @param c where we write
+ * @param Max maximum number of words to materialize
+ * @return how many words were actually materialized
+ */
+ public static long materialize(final IteratingRLW32 i, final BitmapStorage32 c, int Max) {
+ final int origMax = Max;
+ while (true) {
+ if (i.getRunningLength() > 0) {
+ int L = i.getRunningLength();
+ if(L > Max) L = Max;
+ c.addStreamOfEmptyWords(i.getRunningBit(), L);
+ Max -= L;
+ }
+ long L = i.getNumberOfLiteralWords();
+ for (int k = 0; k < L; ++k)
+ c.add(i.getLiteralWordAt(k));
+ if(Max>0) {
+ if (!i.next())
+ break;
+ }
+ else break;
+ }
+ return origMax - Max;
+ }
+ /**
+ * Turn an iterator into a bitmap
+ *
+ * @param i iterator we wish to materialize
+ * @return materialized version of the iterator
+ */
+ public static EWAHCompressedBitmap32 materialize(final IteratingRLW32 i) {
+ EWAHCompressedBitmap32 ewah = new EWAHCompressedBitmap32();
+ materialize(i, ewah);
+ return ewah;
+ }
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/NonEmptyVirtualStorage32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/NonEmptyVirtualStorage32.java
new file mode 100644
index 000000000..94e8bd96a
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/NonEmptyVirtualStorage32.java
@@ -0,0 +1,87 @@
+package com.fr.third.googlecode.javaewah32;
+
+
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+/**
+ * This is a BitmapStorage that can be used to determine quickly
+ * if the result of an operation is non-trivial... that is, whether
+ * there will be at least on set bit.
+ *
+ * @since 0.5.0
+ * @author Daniel Lemire and Veronika Zenz
+ *
+ */
+public class NonEmptyVirtualStorage32 implements BitmapStorage32 {
+ static class NonEmptyException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Do not fill in the stack trace for this exception
+ * for performance reasons.
+ *
+ * @return this instance
+ * @see Throwable#fillInStackTrace()
+ */
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ return this;
+ }
+ }
+
+ private static final NonEmptyException nonEmptyException = new NonEmptyException();
+
+
+ /**
+ * If the word to be added is non-zero, a NonEmptyException exception is thrown.
+ */
+ @Override
+public void add(int newdata) {
+ if(newdata!=0) throw nonEmptyException;
+ }
+
+ /**
+ * throws a NonEmptyException exception when number is greater than 0
+ *
+ */
+ @Override
+public void addStreamOfLiteralWords(int[] data, int start, int number) {
+ if (number > 0){
+ throw nonEmptyException;
+ }
+ }
+
+ /**
+ * If the boolean value is true and number is greater than 0, then it throws a NonEmptyException exception,
+ * otherwise, nothing happens.
+ *
+ */
+ @Override
+public void addStreamOfEmptyWords(boolean v, int number) {
+ if(v && (number>0)) throw nonEmptyException;
+ }
+
+ /**
+ * throws a NonEmptyException exception when number is greater than 0
+ *
+ */
+ @Override
+public void addStreamOfNegatedLiteralWords(int[] data, int start, int number) {
+ if (number > 0){
+ throw nonEmptyException;
+ }
+ }
+
+ /**
+ * Does nothing.
+ *
+ * @see com.googlecode.javaewah.BitmapStorage#setSizeInBits(int)
+ */
+ @Override
+public void setSizeInBits(int bits) {
+ }
+
+}
diff --git a/fine-jgit/src/com/fr/third/googlecode/javaewah32/RunningLengthWord32.java b/fine-jgit/src/com/fr/third/googlecode/javaewah32/RunningLengthWord32.java
new file mode 100644
index 000000000..37f52ee83
--- /dev/null
+++ b/fine-jgit/src/com/fr/third/googlecode/javaewah32/RunningLengthWord32.java
@@ -0,0 +1,152 @@
+package com.fr.third.googlecode.javaewah32;
+
+/*
+ * Copyright 2009-2013, Daniel Lemire, Cliff Moon, David McIntosh, Robert Becho, Google Inc., Veronika Zenz and Owen Kaser
+ * Licensed under the Apache License, Version 2.0.
+ */
+
+/**
+ * Mostly for internal use.
+ *
+ * @since 0.5.0
+ * @author Daniel Lemire
+ */
+public final class RunningLengthWord32 implements Cloneable {
+
+ /**
+ * Instantiates a new running length word.
+ *
+ * @param a
+ * an array of 32-bit words
+ * @param p
+ * position in the array where the running length word is
+ * located.
+ */
+ RunningLengthWord32(final EWAHCompressedBitmap32 a, final int p) {
+ this.parent = a;
+ this.position = p;
+ }
+
+ /**
+ * Gets the number of literal words.
+ *
+ * @return the number of literal words
+ */
+ public int getNumberOfLiteralWords() {
+ return (this.parent.buffer[this.position] >>> (1 + runninglengthbits));
+ }
+
+ /**
+ * Gets the running bit.
+ *
+ * @return the running bit
+ */
+ public boolean getRunningBit() {
+ return (this.parent.buffer[this.position] & 1) != 0;
+ }
+
+ /**
+ * Gets the running length.
+ *
+ * @return the running length
+ */
+ public int getRunningLength() {
+ return (this.parent.buffer[this.position] >>> 1)
+ & largestrunninglengthcount;
+ }
+
+ /**
+ * Sets the number of literal words.
+ *
+ * @param number
+ * the new number of literal words
+ */
+ public void setNumberOfLiteralWords(final int number) {
+ this.parent.buffer[this.position] |= notrunninglengthplusrunningbit;
+ this.parent.buffer[this.position] &= (number << (runninglengthbits + 1))
+ | runninglengthplusrunningbit;
+ }
+
+ /**
+ * Sets the running bit.
+ *
+ * @param b
+ * the new running bit
+ */
+ public void setRunningBit(final boolean b) {
+ if (b)
+ this.parent.buffer[this.position] |= 1;
+ else
+ this.parent.buffer[this.position] &= ~1;
+ }
+
+ /**
+ * Sets the running length.
+ *
+ * @param number
+ * the new running length
+ */
+ public void setRunningLength(final int number) {
+ this.parent.buffer[this.position] |= shiftedlargestrunninglengthcount;
+ this.parent.buffer[this.position] &= (number << 1)
+ | notshiftedlargestrunninglengthcount;
+ }
+
+ /**
+ * Return the size in uncompressed words represented by this running
+ * length word.
+ *
+ * @return the int
+ */
+ public int size() {
+ return getRunningLength() + getNumberOfLiteralWords();
+ }
+
+ /*
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "running bit = " + getRunningBit()
+ + " running length = " + getRunningLength()
+ + " number of lit. words " + getNumberOfLiteralWords();
+ }
+
+ @Override
+ public RunningLengthWord32 clone() throws CloneNotSupportedException {
+ RunningLengthWord32 answer;
+ answer = (RunningLengthWord32) super.clone();
+ answer.parent = this.parent;
+ answer.position = this.position;
+ return answer;
+ }
+
+ /** The array of words. */
+ public EWAHCompressedBitmap32 parent;
+
+ /** The position in array. */
+ public int position;
+
+ /**
+ * number of bits dedicated to marking of the running length of clean
+ * words
+ */
+ public static final int runninglengthbits = 16;
+
+ private static final int literalbits = 32 - 1 - runninglengthbits;
+
+ /** largest number of literal words in a run. */
+ public static final int largestliteralcount = (1 << literalbits) - 1;
+
+ /** largest number of clean words in a run */
+ public static final int largestrunninglengthcount = (1 << runninglengthbits) - 1;
+
+ private static final int runninglengthplusrunningbit = (1 << (runninglengthbits + 1)) - 1;
+
+ private static final int shiftedlargestrunninglengthcount = largestrunninglengthcount << 1;
+
+ private static final int notrunninglengthplusrunningbit = ~runninglengthplusrunningbit;
+
+ private static final int notshiftedlargestrunninglengthcount = ~shiftedlargestrunninglengthcount;
+
+}
\ No newline at end of file
diff --git a/fine-jodd/src/com/fr/third/jodd/exception/ExceptionUtil.java b/fine-jodd/src/com/fr/third/jodd/exception/ExceptionUtil.java
index 8ee74fe07..48d00afbc 100644
--- a/fine-jodd/src/com/fr/third/jodd/exception/ExceptionUtil.java
+++ b/fine-jodd/src/com/fr/third/jodd/exception/ExceptionUtil.java
@@ -255,7 +255,7 @@ public class ExceptionUtil {
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
- Thread.currentThread().stop(throwable);
+ throw new UnsupportedOperationException();
}
/**
diff --git a/fine-kryo/src/com/fr/third/esotericsoftware/kryo/util/UnsafeUtil.java b/fine-kryo/src/com/fr/third/esotericsoftware/kryo/util/UnsafeUtil.java
index 18be3eb24..3014b53ff 100644
--- a/fine-kryo/src/com/fr/third/esotericsoftware/kryo/util/UnsafeUtil.java
+++ b/fine-kryo/src/com/fr/third/esotericsoftware/kryo/util/UnsafeUtil.java
@@ -27,7 +27,7 @@ import java.util.Comparator;
import java.util.List;
import com.fr.third.esotericsoftware.minlog.Log;
-import sun.misc.Cleaner;
+import com.fr.third.sun.misc.Cleaner;
import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/Objenesis.java b/fine-objenesis/src/com/fr/third/org/objenesis/Objenesis.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/Objenesis.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/Objenesis.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisBase.java b/fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisBase.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/ObjenesisBase.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisBase.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisException.java b/fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisException.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/ObjenesisException.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisException.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisHelper.java b/fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisHelper.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/ObjenesisHelper.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisHelper.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisSerializer.java b/fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisSerializer.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/ObjenesisSerializer.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisSerializer.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/ObjenesisStd.java b/fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisStd.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/ObjenesisStd.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/ObjenesisStd.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/ObjectInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/ObjectInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/ObjectInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/ObjectInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/SerializationInstantiatorHelper.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/SerializationInstantiatorHelper.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/SerializationInstantiatorHelper.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/SerializationInstantiatorHelper.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android10Instantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/android/Android10Instantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android10Instantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/android/Android10Instantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android17Instantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/android/Android17Instantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android17Instantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/android/Android17Instantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android18Instantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/android/Android18Instantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/Android18Instantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/android/Android18Instantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/android/AndroidSerializationInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/annotations/Instantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/annotations/Instantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/annotations/Instantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/annotations/Instantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/annotations/Typology.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/annotations/Typology.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/annotations/Typology.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/annotations/Typology.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/AccessibleInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/AccessibleInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/AccessibleInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/AccessibleInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ConstructorInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ConstructorInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ConstructorInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ConstructorInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/FailingInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/FailingInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/FailingInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/FailingInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NewInstanceInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/NewInstanceInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NewInstanceInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/NewInstanceInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NullInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/NullInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/NullInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/NullInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java
similarity index 99%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java
index 025dcfc74..490b06aeb 100644
--- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java
+++ b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/basic/ProxyingInstantiator.java
@@ -61,7 +61,7 @@ public class ProxyingInstantiator implements ObjectInstantiator {
byte[] classBytes = writeExtendingClass(type, SUFFIX);
try {
- newType = ClassDefinitionUtils.defineClass(type.getName() + SUFFIX, classBytes, type.getClassLoader());
+ newType = ClassDefinitionUtils.defineClass(type.getName() + SUFFIX, classBytes, type, type.getClassLoader());
} catch (Exception e) {
throw new ObjenesisException(e);
}
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/gcj/GCJInstantiatorBase.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/gcj/GCJSerializationInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/perc/PercInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/perc/PercInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercSerializationInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/perc/PercSerializationInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/perc/PercSerializationInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/perc/PercSerializationInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java
similarity index 99%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java
index 33a9dec8a..531fbc840 100644
--- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java
+++ b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/MagicInstantiator.java
@@ -95,7 +95,7 @@ public class MagicInstantiator implements ObjectInstantiator {
byte[] classBytes = writeExtendingClass(type, className);
try {
- clazz = ClassDefinitionUtils.defineClass(className, classBytes, getClass().getClassLoader());
+ clazz = ClassDefinitionUtils.defineClass(className, classBytes, type, getClass().getClassLoader());
} catch (Exception e) {
throw new ObjenesisException(e);
}
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryHelper.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/SunReflectionFactorySerializationInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/sun/UnsafeFactoryInstantiator.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java
similarity index 97%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java
index d7fdb79ce..fca50d9c1 100644
--- a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java
+++ b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/util/ClassDefinitionUtils.java
@@ -90,9 +90,9 @@ public final class ClassDefinitionUtils {
* @throws Exception whenever something goes wrong
*/
@SuppressWarnings("unchecked")
- public static Class defineClass(String className, byte[] b, ClassLoader loader)
+ public static Class defineClass(String className, byte[] b, Class> neighbor, ClassLoader loader)
throws Exception {
- Class c = (Class) UnsafeUtils.getUnsafe().defineClass(className, b, 0, b.length, loader, PROTECTION_DOMAIN);
+ Class c = (Class) DefineClassHelper.defineClass(className, b, 0, b.length, neighbor, loader, PROTECTION_DOMAIN);
// Force static initializers to run.
Class.forName(className, true, loader);
return c;
diff --git a/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/util/DefineClassHelper.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/util/DefineClassHelper.java
new file mode 100644
index 000000000..6c2a4ebf7
--- /dev/null
+++ b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/util/DefineClassHelper.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2006-2019 the original author or authors.
+ *
+ * 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.
+ */
+package com.fr.third.org.objenesis.instantiator.util;
+
+import com.fr.third.org.objenesis.ObjenesisException;
+import com.fr.third.org.objenesis.strategy.PlatformDescription;
+import sun.misc.Unsafe;
+
+
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.security.ProtectionDomain;
+
+/**
+ * Java 11+ removed sun.misc.Unsafe.defineClass. This class bridges the gap to work from Java 1.8 up to 11.
+ *
+ * It was inspired from javassist.
+ *
+ * @author Henri Tremblay
+ */
+public final class DefineClassHelper {
+
+ private static abstract class Helper {
+ abstract Class> defineClass(String name, byte[] b, int off, int len, Class> neighbor,
+ ClassLoader loader, ProtectionDomain protectionDomain);
+ }
+
+ private static class Java8 extends Helper {
+
+ private final MethodHandle defineClass = defineClass();
+
+ private MethodHandle defineClass() {
+ MethodType mt = MethodType.methodType(Class.class, String.class, byte[].class, int.class, int.class, ClassLoader.class, ProtectionDomain.class);
+ MethodHandle m;
+ try {
+ m = MethodHandles.publicLookup().findVirtual(Unsafe.class, "defineClass", mt);
+ } catch(NoSuchMethodException | IllegalAccessException e) {
+ throw new ObjenesisException(e);
+ }
+ Unsafe unsafe = UnsafeUtils.getUnsafe();
+ return m.bindTo(unsafe);
+ }
+
+ @Override
+ Class> defineClass(String className, byte[] b, int off, int len, Class> neighbor, ClassLoader loader, ProtectionDomain protectionDomain) {
+ try {
+ return (Class>) defineClass.invokeExact(className, b, off, len, loader, protectionDomain);
+ } catch (Throwable e) {
+ if(e instanceof Error) {
+ throw (Error) e;
+ }
+ if(e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ }
+ throw new ObjenesisException(e);
+ }
+ }
+ }
+
+ private static class Java11 extends Helper {
+
+ private final Class> module = module();
+ private final MethodHandles.Lookup lookup = MethodHandles.lookup();
+ private final MethodHandle getModule = getModule();
+ private final MethodHandle addReads = addReads();
+ private final MethodHandle privateLookupIn = privateLookupIn();
+ private final MethodHandle defineClass = defineClass();
+
+ private Class> module() {
+ try {
+ return Class.forName("java.lang.Module");
+ } catch (ClassNotFoundException e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+ private MethodHandle getModule() {
+ try {
+ return lookup.findVirtual(Class.class, "getModule", MethodType.methodType(module));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+ private MethodHandle addReads() {
+ try {
+ return lookup.findVirtual(module, "addReads", MethodType.methodType(module, module));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+ private MethodHandle privateLookupIn() {
+ try {
+ return lookup.findStatic(MethodHandles.class, "privateLookupIn", MethodType.methodType(MethodHandles.Lookup.class, Class.class, MethodHandles.Lookup.class));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+ private MethodHandle defineClass() {
+ try {
+ return lookup.findVirtual(MethodHandles.Lookup.class, "defineClass", MethodType.methodType(Class.class, byte[].class));
+ } catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new ObjenesisException(e);
+ }
+ }
+
+ @Override
+ Class> defineClass(String className, byte[] b, int off, int len, Class> neighbor, ClassLoader loader, ProtectionDomain protectionDomain) {
+ try {
+ Object module = getModule.invokeWithArguments(DefineClassHelper.class);
+ Object neighborModule = getModule.invokeWithArguments(neighbor);
+ addReads.invokeWithArguments(module, neighborModule);
+ MethodHandles.Lookup prvlookup = (MethodHandles.Lookup) privateLookupIn.invokeExact(neighbor, lookup);
+ return (Class>) defineClass.invokeExact(prvlookup, b);
+ } catch (Throwable e) {
+ throw new ObjenesisException(neighbor.getName() + " has no permission to define the class", e);
+ }
+ }
+ }
+
+ // Java 11+ removed sun.misc.Unsafe.defineClass, so we fallback to invoking defineClass on
+ // ClassLoader until we have an implementation that uses MethodHandles.Lookup.defineClass
+ private static final Helper privileged = PlatformDescription.isAfterJava11() ?
+ new Java11() : new Java8();
+
+ public static Class> defineClass(String name, byte[] b, int off, int len, Class> neighbor,
+ ClassLoader loader, ProtectionDomain protectionDomain) {
+ return privileged.defineClass(name, b, off, len, neighbor, loader, protectionDomain);
+ }
+
+ private DefineClassHelper() {}
+}
\ No newline at end of file
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/UnsafeUtils.java b/fine-objenesis/src/com/fr/third/org/objenesis/instantiator/util/UnsafeUtils.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/instantiator/util/UnsafeUtils.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/instantiator/util/UnsafeUtils.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/BaseInstantiatorStrategy.java b/fine-objenesis/src/com/fr/third/org/objenesis/strategy/BaseInstantiatorStrategy.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/strategy/BaseInstantiatorStrategy.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/strategy/BaseInstantiatorStrategy.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/InstantiatorStrategy.java b/fine-objenesis/src/com/fr/third/org/objenesis/strategy/InstantiatorStrategy.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/strategy/InstantiatorStrategy.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/strategy/InstantiatorStrategy.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java b/fine-objenesis/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java
similarity index 89%
rename from fine-kryo/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java
index a401fc320..b5c886e27 100644
--- a/fine-kryo/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java
+++ b/fine-objenesis/src/com/fr/third/org/objenesis/strategy/PlatformDescription.java
@@ -134,6 +134,29 @@ public final class PlatformDescription {
return bootClasspath != null && bootClasspath.toLowerCase().contains("core-oj.jar");
}
+ /**
+ * Tells if the current JVM is running Java 9 or above
+ *
+ * @return if the current JVM is Java 9 or above
+ */
+ public static boolean isAfterJigsaw() {
+ String version = PlatformDescription.SPECIFICATION_VERSION;
+ return version.indexOf('.') < 0; // No dot means the version is 9, 10, 11, ... not 1.6, 1.7, 1.8
+ }
+
+ /**
+ * Tells if the current JVM is running Java 11 or above
+ *
+ * @return if the current JVM is Java 11 or above
+ */
+ public static boolean isAfterJava11() {
+ if(!isAfterJigsaw()) {
+ return false;
+ }
+ int version = Integer.parseInt(PlatformDescription.SPECIFICATION_VERSION);
+ return version >= 11;
+ }
+
public static boolean isGoogleAppEngine() {
return GAE_VERSION != null;
}
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/SerializingInstantiatorStrategy.java b/fine-objenesis/src/com/fr/third/org/objenesis/strategy/SerializingInstantiatorStrategy.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/strategy/SerializingInstantiatorStrategy.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/strategy/SerializingInstantiatorStrategy.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/SingleInstantiatorStrategy.java b/fine-objenesis/src/com/fr/third/org/objenesis/strategy/SingleInstantiatorStrategy.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/strategy/SingleInstantiatorStrategy.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/strategy/SingleInstantiatorStrategy.java
diff --git a/fine-kryo/src/com/fr/third/org/objenesis/strategy/StdInstantiatorStrategy.java b/fine-objenesis/src/com/fr/third/org/objenesis/strategy/StdInstantiatorStrategy.java
similarity index 100%
rename from fine-kryo/src/com/fr/third/org/objenesis/strategy/StdInstantiatorStrategy.java
rename to fine-objenesis/src/com/fr/third/org/objenesis/strategy/StdInstantiatorStrategy.java
diff --git a/fine-poi/src/com/fr/third/v2/org/apache/poi/POIXMLTypeLoader.java b/fine-poi/src/com/fr/third/v2/org/apache/poi/POIXMLTypeLoader.java
index f9203a570..9776713d2 100644
--- a/fine-poi/src/com/fr/third/v2/org/apache/poi/POIXMLTypeLoader.java
+++ b/fine-poi/src/com/fr/third/v2/org/apache/poi/POIXMLTypeLoader.java
@@ -18,9 +18,11 @@
package com.fr.third.v2.org.apache.poi;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.io.StringReader;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
@@ -28,6 +30,7 @@ import java.util.Map;
import javax.xml.stream.XMLStreamReader;
+import com.fr.third.v2.org.apache.poi.util.DocumentHelper;
import com.fr.third.v2.org.apache.xmlbeans.SchemaType;
import com.fr.third.v2.org.apache.xmlbeans.XmlBeans;
import com.fr.third.v2.org.apache.xmlbeans.XmlException;
@@ -35,19 +38,26 @@ import com.fr.third.v2.org.apache.xmlbeans.XmlObject;
import com.fr.third.v2.org.apache.xmlbeans.XmlOptions;
import com.fr.third.v2.org.apache.xmlbeans.xml.stream.XMLInputStream;
import com.fr.third.v2.org.apache.xmlbeans.xml.stream.XMLStreamException;
+import org.w3c.dom.Document;
import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
@SuppressWarnings("deprecation")
public class POIXMLTypeLoader {
public static final XmlOptions DEFAULT_XML_OPTIONS;
+
static {
DEFAULT_XML_OPTIONS = new XmlOptions();
DEFAULT_XML_OPTIONS.setSaveOuter();
DEFAULT_XML_OPTIONS.setUseDefaultNamespace();
DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces();
DEFAULT_XML_OPTIONS.setCharacterEncoding("UTF-8");
- DEFAULT_XML_OPTIONS.setLoadEntityBytesLimit(4096);
+ // Piccolo is disabled for POI builts, i.e. JAXP is used for parsing
+ // so only user code using XmlObject/XmlToken.Factory.parse
+ // directly can bypass the entity check, which is probably unlikely (... and not within our responsibility :))
+ // DEFAULT_XML_OPTIONS.setLoadEntityBytesLimit(4096);
Map map = new HashMap();
map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a");
@@ -66,10 +76,9 @@ public class POIXMLTypeLoader {
map.put("urn:schemas-microsoft-com:vml", "v");
DEFAULT_XML_OPTIONS.setSaveSuggestedPrefixes(Collections.unmodifiableMap(map));
}
-
+
private static XmlOptions getXmlOptions(XmlOptions options) {
- XmlOptions opt = (options == null) ? DEFAULT_XML_OPTIONS : options;
- return opt;
+ return options == null ? DEFAULT_XML_OPTIONS : options;
}
public static XmlObject newInstance(SchemaType type, XmlOptions options) {
@@ -77,19 +86,38 @@ public class POIXMLTypeLoader {
}
public static XmlObject parse(String xmlText, SchemaType type, XmlOptions options) throws XmlException {
- return XmlBeans.getContextTypeLoader().parse(xmlText, type, getXmlOptions(options));
+ try {
+ return parse(new StringReader(xmlText), type, options);
+ } catch (IOException e) {
+ throw new XmlException("Unable to parse xml bean", e);
+ }
}
public static XmlObject parse(File file, SchemaType type, XmlOptions options) throws XmlException, IOException {
- return XmlBeans.getContextTypeLoader().parse(file, type, getXmlOptions(options));
+ InputStream is = new FileInputStream(file);
+ try {
+ return parse(is, type, options);
+ } finally {
+ is.close();
+ }
}
public static XmlObject parse(URL file, SchemaType type, XmlOptions options) throws XmlException, IOException {
- return XmlBeans.getContextTypeLoader().parse(file, type, getXmlOptions(options));
+ InputStream is = file.openStream();
+ try {
+ return parse(is, type, options);
+ } finally {
+ is.close();
+ }
}
public static XmlObject parse(InputStream jiois, SchemaType type, XmlOptions options) throws XmlException, IOException {
- return XmlBeans.getContextTypeLoader().parse(jiois, type, getXmlOptions(options));
+ try {
+ Document doc = DocumentHelper.readDocument(jiois);
+ return XmlBeans.getContextTypeLoader().parse(doc.getDocumentElement(), type, getXmlOptions(options));
+ } catch (SAXException e) {
+ throw new IOException("Unable to parse xml bean", e);
+ }
}
public static XmlObject parse(XMLStreamReader xsr, SchemaType type, XmlOptions options) throws XmlException {
@@ -97,7 +125,12 @@ public class POIXMLTypeLoader {
}
public static XmlObject parse(Reader jior, SchemaType type, XmlOptions options) throws XmlException, IOException {
- return XmlBeans.getContextTypeLoader().parse(jior, type, getXmlOptions(options));
+ try {
+ Document doc = DocumentHelper.readDocument(new InputSource(jior));
+ return XmlBeans.getContextTypeLoader().parse(doc.getDocumentElement(), type, getXmlOptions(options));
+ } catch (SAXException e) {
+ throw new XmlException("Unable to parse xml bean", e);
+ }
}
public static XmlObject parse(Node node, SchemaType type, XmlOptions options) throws XmlException {
@@ -107,8 +140,8 @@ public class POIXMLTypeLoader {
public static XmlObject parse(XMLInputStream xis, SchemaType type, XmlOptions options) throws XmlException, XMLStreamException {
return XmlBeans.getContextTypeLoader().parse(xis, type, getXmlOptions(options));
}
-
- public static XMLInputStream newValidatingXMLInputStream ( XMLInputStream xis, SchemaType type, XmlOptions options ) throws XmlException, XMLStreamException {
+
+ public static XMLInputStream newValidatingXMLInputStream(XMLInputStream xis, SchemaType type, XmlOptions options) throws XmlException, XMLStreamException {
return XmlBeans.getContextTypeLoader().newValidatingXMLInputStream(xis, type, getXmlOptions(options));
}
}
diff --git a/fine-poi/src/com/fr/third/v2/org/apache/poi/util/DocumentHelper.java b/fine-poi/src/com/fr/third/v2/org/apache/poi/util/DocumentHelper.java
index f6d7b5bb1..d9bba2eb8 100644
--- a/fine-poi/src/com/fr/third/v2/org/apache/poi/util/DocumentHelper.java
+++ b/fine-poi/src/com/fr/third/v2/org/apache/poi/util/DocumentHelper.java
@@ -29,12 +29,55 @@ import javax.xml.stream.events.Namespace;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
public final class DocumentHelper {
private static POILogger logger = POILogFactory.getLogger(DocumentHelper.class);
- private DocumentHelper() {}
+ private DocumentHelper() {
+ }
+
+ private static class DocHelperErrorHandler implements ErrorHandler {
+
+ public void warning(SAXParseException exception) throws SAXException {
+ printError(POILogger.WARN, exception);
+ }
+
+ public void error(SAXParseException exception) throws SAXException {
+ printError(POILogger.ERROR, exception);
+ }
+
+ public void fatalError(SAXParseException exception) throws SAXException {
+ printError(POILogger.FATAL, exception);
+ throw exception;
+ }
+
+ /**
+ * Prints the error message.
+ */
+ private void printError(int type, SAXParseException ex) {
+ StringBuilder sb = new StringBuilder();
+
+ String systemId = ex.getSystemId();
+ if (systemId != null) {
+ int index = systemId.lastIndexOf('/');
+ if (index != -1)
+ systemId = systemId.substring(index + 1);
+ sb.append(systemId);
+ }
+ sb.append(':');
+ sb.append(ex.getLineNumber());
+ sb.append(':');
+ sb.append(ex.getColumnNumber());
+ sb.append(": ");
+ sb.append(ex.getMessage());
+
+ logger.log(type, sb.toString(), ex);
+ }
+ }
/**
* Creates a new document builder, with sensible defaults
@@ -43,6 +86,7 @@ public final class DocumentHelper {
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
documentBuilder.setEntityResolver(SAXHelper.IGNORING_ENTITY_RESOLVER);
+ documentBuilder.setErrorHandler(new DocHelperErrorHandler());
return documentBuilder;
} catch (ParserConfigurationException e) {
throw new IllegalStateException("cannot create a DocumentBuilder", e);
@@ -50,6 +94,7 @@ public final class DocumentHelper {
}
private static final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+
static {
documentBuilderFactory.setNamespaceAware(true);
documentBuilderFactory.setValidating(false);
@@ -66,10 +111,10 @@ public final class DocumentHelper {
logger.log(POILogger.WARN, "Cannot set SAX feature because outdated XML parser in classpath", feature, ame);
}
}
-
+
private static void trySetXercesSecurityManager(DocumentBuilderFactory documentBuilderFactory) {
// Try built-in JVM one first, standalone if not
- for (String securityManagerClassName : new String[] {
+ for (String securityManagerClassName : new String[]{
"com.sun.org.apache.xerces.internal.util.SecurityManager",
"org.apache.xerces.util.SecurityManager"
}) {
@@ -89,13 +134,25 @@ public final class DocumentHelper {
/**
* Parses the given stream via the default (sensible)
* DocumentBuilder
+ *
* @param inp Stream to read the XML data from
- * @return the parsed Document
+ * @return the parsed Document
*/
public static Document readDocument(InputStream inp) throws IOException, SAXException {
return newDocumentBuilder().parse(inp);
}
+ /**
+ * Parses the given stream via the default (sensible)
+ * DocumentBuilder
+ *
+ * @param inp sax source to read the XML data from
+ * @return the parsed Document
+ */
+ public static Document readDocument(InputSource inp) throws IOException, SAXException {
+ return newDocumentBuilder().parse(inp);
+ }
+
// must only be used to create empty documents, do not use it for parsing!
private static final DocumentBuilder documentBuilderSingleton = newDocumentBuilder();
diff --git a/fine-quartz/src/com/fr/third/v2/org/quartz/jobs/ee/ejb/EJB3InvokerJob.java b/fine-quartz/src/com/fr/third/v2/org/quartz/jobs/ee/ejb/EJB3InvokerJob.java
deleted file mode 100644
index b24a16182..000000000
--- a/fine-quartz/src/com/fr/third/v2/org/quartz/jobs/ee/ejb/EJB3InvokerJob.java
+++ /dev/null
@@ -1,110 +0,0 @@
-package com.fr.third.v2.org.quartz.jobs.ee.ejb;
-
-import java.lang.reflect.InvocationTargetException;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import com.fr.third.v2.org.quartz.JobDataMap;
-import com.fr.third.v2.org.quartz.JobExecutionContext;
-import com.fr.third.v2.org.quartz.JobExecutionException;
-
-/**
- *
- * A Job that invokes a method on an EJB3.
- *
- *
- *
- * Expects the properties corresponding to the following keys to be in the
- * JobDataMap when it executes:
- *
- *
EJB_JNDI_NAME_KEY- the JNDI name (location) of the EJB's
- * home interface.
- *
EJB_METHOD_KEY- the name of the method to invoke on the EJB.
- *
- *
EJB_ARGS_KEY- an Object[] of the args to pass to the method
- * (optional, if left out, there are no arguments).
- *
EJB_ARG_TYPES_KEY- an Class[] of the types of the args to
- * pass to the method (optional, if left out, the types will be derived by
- * calling getClass() on each of the arguments).
- *
- *
- * The following keys can also be used at need:
- *
- *
INITIAL_CONTEXT_FACTORY - the context factory used to build
- * the context.
- *
PROVIDER_URL - the name of the environment property for
- * specifying configuration information for the service provider to use.
- *
- *
- *
- *
- * The result of the EJB method invocation will be available to
- * Job/TriggerListeners via
- * {@link com.fr.third.v2.org.quartz.JobExecutionContext#getResult()}.
- *
- *
- * @author hhuynh
- * @see {@link EJBInvokerJob}
- */
-public class EJB3InvokerJob extends EJBInvokerJob {
-
- @Override
- public void execute(JobExecutionContext context)
- throws JobExecutionException {
- JobDataMap dataMap = context.getMergedJobDataMap();
-
- String ejb = dataMap.getString(EJB_JNDI_NAME_KEY);
- String method = dataMap.getString(EJB_METHOD_KEY);
-
- Object[] arguments = (Object[]) dataMap.get(EJB_ARGS_KEY);
- if (arguments == null) {
- arguments = new Object[0];
- }
- if (ejb == null) {
- throw new JobExecutionException("must specify EJB_JNDI_NAME_KEY");
- }
- if (method == null) {
- throw new JobExecutionException("must specify EJB_METHOD_KEY");
- }
-
- InitialContext jndiContext = null;
- Object value = null;
- try {
- try {
- jndiContext = getInitialContext(dataMap);
- value = jndiContext.lookup(ejb);
- } catch (NamingException ne) {
- throw new JobExecutionException(ne);
- }
-
- Class>[] argTypes = (Class[]) dataMap.get(EJB_ARG_TYPES_KEY);
- if (argTypes == null) {
- argTypes = new Class[arguments.length];
- for (int i = 0; i < arguments.length; i++) {
- argTypes[i] = arguments[i].getClass();
- }
- }
-
- try {
- Object returnValue = value.getClass()
- .getMethod(method, argTypes).invoke(value, arguments);
- context.setResult(returnValue);
- } catch (IllegalAccessException iae) {
- throw new JobExecutionException(iae);
- } catch (InvocationTargetException ite) {
- throw new JobExecutionException(ite.getTargetException());
- } catch (NoSuchMethodException nsme) {
- throw new JobExecutionException(nsme);
- }
- } finally {
- if (jndiContext != null) {
- try {
- jndiContext.close();
- } catch (Exception e) {
- // ignored
- }
- }
- }
- }
-}
diff --git a/fine-quartz/src/com/fr/third/v2/org/quartz/jobs/ee/ejb/EJBInvokerJob.java b/fine-quartz/src/com/fr/third/v2/org/quartz/jobs/ee/ejb/EJBInvokerJob.java
deleted file mode 100644
index 68d5ba7a2..000000000
--- a/fine-quartz/src/com/fr/third/v2/org/quartz/jobs/ee/ejb/EJBInvokerJob.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * All content copyright Terracotta, Inc., unless otherwise indicated. All rights reserved.
- *
- * 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.
- *
- */
-
-package com.fr.third.v2.org.quartz.jobs.ee.ejb;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.rmi.RemoteException;
-import java.util.Hashtable;
-
-import javax.ejb.EJBHome;
-import javax.ejb.EJBMetaData;
-import javax.ejb.EJBObject;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.rmi.PortableRemoteObject;
-
-import com.fr.third.v2.org.quartz.Job;
-import com.fr.third.v2.org.quartz.JobDataMap;
-import com.fr.third.v2.org.quartz.JobExecutionContext;
-import com.fr.third.v2.org.quartz.JobExecutionException;
-
-/**
- *
- * A Job that invokes a method on an EJB.
- *
- *
- *
- * Expects the properties corresponding to the following keys to be in the
- * JobDataMap when it executes:
- *
- *
EJB_JNDI_NAME_KEY- the JNDI name (location) of the
- * EJB's home interface.
- *
EJB_METHOD_KEY- the name of the method to invoke on the
- * EJB.
- *
EJB_ARGS_KEY- an Object[] of the args to pass to the
- * method (optional, if left out, there are no arguments).
- *
EJB_ARG_TYPES_KEY- an Class[] of the types of the args to
- * pass to the method (optional, if left out, the types will be derived by
- * calling getClass() on each of the arguments).
- *
- *
- * The following keys can also be used at need:
- *
- *
INITIAL_CONTEXT_FACTORY - the context factory used to
- * build the context.
- *
PROVIDER_URL - the name of the environment property
- * for specifying configuration information for the service provider to use.
- *
- *
- *
- *
- *
- * The result of the EJB method invocation will be available to
- * Job/TriggerListeners via
- * {@link com.fr.third.v2.org.quartz.JobExecutionContext#getResult()}.
- *
- *
- * @author Andrew Collins
- * @author James House
- * @author Joel Shellman
- * @author Chris Bonham
- */
-public class EJBInvokerJob implements Job {
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constants.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- public static final String EJB_JNDI_NAME_KEY = "ejb";
-
- public static final String EJB_METHOD_KEY = "method";
-
- public static final String EJB_ARG_TYPES_KEY = "argTypes";
-
- public static final String EJB_ARGS_KEY = "args";
-
- public static final String INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial";
-
- public static final String PROVIDER_URL = "java.naming.provider.url";
-
- public static final String PRINCIPAL = "java.naming.security.principal";
-
- public static final String CREDENTIALS = "java.naming.security.credentials";
-
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Constructors.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- public EJBInvokerJob() {
- // nothing
- }
-
- /*
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * Interface.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
- public void execute(JobExecutionContext context)
- throws JobExecutionException {
- JobDataMap dataMap = context.getMergedJobDataMap();
-
- String ejb = dataMap.getString(EJB_JNDI_NAME_KEY);
- String method = dataMap.getString(EJB_METHOD_KEY);
- Object[] arguments = (Object[]) dataMap.get(EJB_ARGS_KEY);
- if (arguments == null) {
- arguments = new Object[0];
- }
-
- if (ejb == null) {
- // must specify remote home
- throw new JobExecutionException();
- }
-
- InitialContext jndiContext = null;
-
- // get initial context
- try {
- jndiContext = getInitialContext(dataMap);
- } catch (NamingException ne) {
- throw new JobExecutionException(ne);
- }
-
- try {
- Object value = null;
-
- // locate home interface
- try {
- value = jndiContext.lookup(ejb);
- } catch (NamingException ne) {
- throw new JobExecutionException(ne);
- }
-
- // get home interface
- EJBHome ejbHome = (EJBHome) PortableRemoteObject.narrow(value,
- EJBHome.class);
-
- // get meta data
- EJBMetaData metaData = null;
-
- try {
- metaData = ejbHome.getEJBMetaData();
- } catch (RemoteException re) {
- throw new JobExecutionException(re);
- }
-
- // get home interface class
- Class> homeClass = metaData.getHomeInterfaceClass();
-
- // get remote interface class
- Class> remoteClass = metaData.getRemoteInterfaceClass();
-
- // get home interface
- ejbHome = (EJBHome) PortableRemoteObject.narrow(ejbHome, homeClass);
-
- Method methodCreate = null;
-
- try {
- // create method 'create()' on home interface
- methodCreate = homeClass.getMethod("create", ((Class[])null));
- } catch (NoSuchMethodException nsme) {
- throw new JobExecutionException(nsme);
- }
-
- // create remote object
- EJBObject remoteObj = null;
-
- try {
- // invoke 'create()' method on home interface
- remoteObj = (EJBObject) methodCreate.invoke(ejbHome, ((Object[])null));
- } catch (IllegalAccessException iae) {
- throw new JobExecutionException(iae);
- } catch (InvocationTargetException ite) {
- throw new JobExecutionException(ite);
- }
-
- // execute user-specified method on remote object
- Method methodExecute = null;
-
- try {
- // create method signature
-
- Class>[] argTypes = (Class[]) dataMap.get(EJB_ARG_TYPES_KEY);
- if (argTypes == null) {
- argTypes = new Class[arguments.length];
- for (int i = 0; i < arguments.length; i++) {
- argTypes[i] = arguments[i].getClass();
- }
- }
-
- // get method on remote object
- methodExecute = remoteClass.getMethod(method, argTypes);
- } catch (NoSuchMethodException nsme) {
- throw new JobExecutionException(nsme);
- }
-
- try {
- // invoke user-specified method on remote object
- Object returnObj = methodExecute.invoke(remoteObj, arguments);
-
- // Return any result in the JobExecutionContext so it will be
- // available to Job/TriggerListeners
- context.setResult(returnObj);
- } catch (IllegalAccessException iae) {
- throw new JobExecutionException(iae);
- } catch (InvocationTargetException ite) {
- throw new JobExecutionException(ite);
- }
- } finally {
- // Don't close jndiContext until after method execution because
- // WebLogic requires context to be open to keep the user credentials
- // available. See JIRA Issue: QUARTZ-401
- if (jndiContext != null) {
- try {
- jndiContext.close();
- } catch (NamingException e) {
- // Ignore any errors closing the initial context
- }
- }
- }
- }
-
- protected InitialContext getInitialContext(JobDataMap jobDataMap)
- throws NamingException {
- Hashtable params = new Hashtable(2);
-
- String initialContextFactory =
- jobDataMap.getString(INITIAL_CONTEXT_FACTORY);
- if (initialContextFactory != null) {
- params.put(Context.INITIAL_CONTEXT_FACTORY, initialContextFactory);
- }
-
- String providerUrl = jobDataMap.getString(PROVIDER_URL);
- if (providerUrl != null) {
- params.put(Context.PROVIDER_URL, providerUrl);
- }
-
- String principal = jobDataMap.getString(PRINCIPAL);
- if ( principal != null ) {
- params.put( Context.SECURITY_PRINCIPAL, principal );
- }
-
- String credentials = jobDataMap.getString(CREDENTIALS);
- if ( credentials != null ) {
- params.put( Context.SECURITY_CREDENTIALS, credentials );
- }
-
- return (params.size() == 0) ? new InitialContext() : new InitialContext(params);
- }
-}
\ No newline at end of file
diff --git a/fine-quartz/src/com/fr/third/v2/org/quartz/xml/XMLSchedulingDataProcessor.java b/fine-quartz/src/com/fr/third/v2/org/quartz/xml/XMLSchedulingDataProcessor.java
index b70a3992d..8bd0e53fa 100644
--- a/fine-quartz/src/com/fr/third/v2/org/quartz/xml/XMLSchedulingDataProcessor.java
+++ b/fine-quartz/src/com/fr/third/v2/org/quartz/xml/XMLSchedulingDataProcessor.java
@@ -203,7 +203,7 @@ public class XMLSchedulingDataProcessor implements ErrorHandler {
return XMLConstants.NULL_NS_URI;
}
- public Iterator> getPrefixes(String namespaceURI)
+ public Iterator getPrefixes(String namespaceURI)
{
// This method isn't necessary for XPath processing.
throw new UnsupportedOperationException();
diff --git a/fine-spring/src/com/fr/third/springframework/aop/framework/ObjenesisCglibAopProxy.java b/fine-spring/src/com/fr/third/springframework/aop/framework/ObjenesisCglibAopProxy.java
index c26d3d1e5..3f8c40cde 100644
--- a/fine-spring/src/com/fr/third/springframework/aop/framework/ObjenesisCglibAopProxy.java
+++ b/fine-spring/src/com/fr/third/springframework/aop/framework/ObjenesisCglibAopProxy.java
@@ -16,8 +16,8 @@
package com.fr.third.springframework.aop.framework;
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.ObjenesisStd;
+import com.fr.third.org.objenesis.ObjenesisException;
+import com.fr.third.org.objenesis.ObjenesisStd;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.fr.third.springframework.cglib.proxy.Callback;
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/Objenesis.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/Objenesis.java
deleted file mode 100644
index 402c72ea2..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/Objenesis.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis;
-
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Common interface to all kind of Objenesis objects
- *
- * @author Henri Tremblay
- */
-public interface Objenesis {
-
- /**
- * Will create a new object without any constructor being called
- *
- * @param Type instantiated
- * @param clazz Class to instantiate
- * @return New instance of clazz
- */
- T newInstance(Class clazz);
-
- /**
- * Will pick the best instantiator for the provided class. If you need to create a lot of
- * instances from the same class, it is way more efficient to create them from the same
- * ObjectInstantiator than calling {@link #newInstance(Class)}.
- *
- * @param Type to instantiate
- * @param clazz Class to instantiate
- * @return Instantiator dedicated to the class
- */
- ObjectInstantiator getInstantiatorOf(Class clazz);
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisBase.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisBase.java
deleted file mode 100644
index c34690c95..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisBase.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis;
-
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.strategy.InstantiatorStrategy;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Base class to extend if you want to have a class providing your own default strategy. Can also be
- * instantiated directly.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisBase implements Objenesis {
-
- /** Strategy used by this Objenesi implementation to create classes */
- protected final InstantiatorStrategy strategy;
-
- /** Strategy cache. Key = Class, Value = InstantiatorStrategy */
- protected ConcurrentHashMap> cache;
-
- /**
- * Constructor allowing to pick a strategy and using cache
- *
- * @param strategy Strategy to use
- */
- public ObjenesisBase(InstantiatorStrategy strategy) {
- this(strategy, true);
- }
-
- /**
- * Flexible constructor allowing to pick the strategy and if caching should be used
- *
- * @param strategy Strategy to use
- * @param useCache If {@link ObjectInstantiator}s should be cached
- */
- public ObjenesisBase(InstantiatorStrategy strategy, boolean useCache) {
- if(strategy == null) {
- throw new IllegalArgumentException("A strategy can't be null");
- }
- this.strategy = strategy;
- this.cache = useCache ? new ConcurrentHashMap>() : null;
- }
-
- @Override
- public String toString() {
- return getClass().getName() + " using " + strategy.getClass().getName()
- + (cache == null ? " without" : " with") + " caching";
- }
-
- /**
- * Will create a new object without any constructor being called
- *
- * @param clazz Class to instantiate
- * @return New instance of clazz
- */
- public T newInstance(Class clazz) {
- return getInstantiatorOf(clazz).newInstance();
- }
-
- /**
- * Will pick the best instantiator for the provided class. If you need to create a lot of
- * instances from the same class, it is way more efficient to create them from the same
- * ObjectInstantiator than calling {@link #newInstance(Class)}.
- *
- * @param clazz Class to instantiate
- * @return Instantiator dedicated to the class
- */
- @SuppressWarnings("unchecked")
- public ObjectInstantiator getInstantiatorOf(Class clazz) {
- if(clazz.isPrimitive()) {
- throw new IllegalArgumentException("Primitive types can't be instantiated in Java");
- }
- if(cache == null) {
- return strategy.newInstantiatorOf(clazz);
- }
- ObjectInstantiator> instantiator = cache.get(clazz.getName());
- if(instantiator == null) {
- ObjectInstantiator> newInstantiator = strategy.newInstantiatorOf(clazz);
- instantiator = cache.putIfAbsent(clazz.getName(), newInstantiator);
- if(instantiator == null) {
- instantiator = newInstantiator;
- }
- }
- return (ObjectInstantiator) instantiator;
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisException.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisException.java
deleted file mode 100644
index 682c45562..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisException.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis;
-
-/**
- * Exception thrown by Objenesis. It wraps any instantiation exceptions. Note that this exception is
- * runtime to prevent having to catch it.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisException extends RuntimeException {
-
- private static final long serialVersionUID = -2677230016262426968L;
-
- /**
- * @param msg Error message
- */
- public ObjenesisException(String msg) {
- super(msg);
- }
-
- /**
- * @param cause Wrapped exception. The message will be the one of the cause.
- */
- public ObjenesisException(Throwable cause) {
- super(cause);
- }
-
- /**
- * @param msg Error message
- * @param cause Wrapped exception
- */
- public ObjenesisException(String msg, Throwable cause) {
- super(msg, cause);
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisHelper.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisHelper.java
deleted file mode 100644
index 3d0c81483..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisHelper.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis;
-
-import java.io.Serializable;
-
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Use Objenesis in a static way. It is strongly not recommended to use this class.
- *
- * @author Henri Tremblay
- */
-public final class ObjenesisHelper {
-
- private static final Objenesis OBJENESIS_STD = new ObjenesisStd();
-
- private static final Objenesis OBJENESIS_SERIALIZER = new ObjenesisSerializer();
-
- private ObjenesisHelper() {
- }
-
- /**
- * Will create a new object without any constructor being called
- *
- * @param Type instantiated
- * @param clazz Class to instantiate
- * @return New instance of clazz
- */
- public static T newInstance(Class clazz) {
- return OBJENESIS_STD.newInstance(clazz);
- }
-
- /**
- * Will create an object just like it's done by ObjectInputStream.readObject (the default
- * constructor of the first non serializable class will be called)
- *
- * @param Type instantiated
- * @param clazz Class to instantiate
- * @return New instance of clazz
- */
- public static T newSerializableInstance(Class clazz) {
- return (T) OBJENESIS_SERIALIZER.newInstance(clazz);
- }
-
- /**
- * Will pick the best instantiator for the provided class. If you need to create a lot of
- * instances from the same class, it is way more efficient to create them from the same
- * ObjectInstantiator than calling {@link #newInstance(Class)}.
- *
- * @param Type to instantiate
- * @param clazz Class to instantiate
- * @return Instantiator dedicated to the class
- */
- public static ObjectInstantiator getInstantiatorOf(Class clazz) {
- return OBJENESIS_STD.getInstantiatorOf(clazz);
- }
-
- /**
- * Same as {@link #getInstantiatorOf(Class)} but providing an instantiator emulating
- * ObjectInputStream.readObject behavior.
- *
- * @see #newSerializableInstance(Class)
- * @param Type to instantiate
- * @param clazz Class to instantiate
- * @return Instantiator dedicated to the class
- */
- public static ObjectInstantiator getSerializableObjectInstantiatorOf(Class clazz) {
- return OBJENESIS_SERIALIZER.getInstantiatorOf(clazz);
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisSerializer.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisSerializer.java
deleted file mode 100644
index b300c9d15..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisSerializer.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis;
-
-import com.fr.third.springframework.aop.objenesis.strategy.SerializingInstantiatorStrategy;
-
-/**
- * Objenesis implementation using the {@link SerializingInstantiatorStrategy}.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisSerializer extends ObjenesisBase {
-
- /**
- * Default constructor using the {@link com.fr.third.springframework.aop.objenesis.strategy.SerializingInstantiatorStrategy}
- */
- public ObjenesisSerializer() {
- super(new SerializingInstantiatorStrategy());
- }
-
- /**
- * Instance using the {@link com.fr.third.springframework.aop.objenesis.strategy.SerializingInstantiatorStrategy} with or without caching
- * {@link com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator}s
- *
- * @param useCache If {@link com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator}s should be cached
- */
- public ObjenesisSerializer(boolean useCache) {
- super(new SerializingInstantiatorStrategy(), useCache);
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisStd.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisStd.java
deleted file mode 100644
index e7c1d3493..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/ObjenesisStd.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis;
-
-import com.fr.third.springframework.aop.objenesis.strategy.StdInstantiatorStrategy;
-
-/**
- * Objenesis implementation using the {@link com.fr.third.springframework.aop.objenesis.strategy.StdInstantiatorStrategy}.
- *
- * @author Henri Tremblay
- */
-public class ObjenesisStd extends ObjenesisBase {
-
- /**
- * Default constructor using the {@link com.fr.third.springframework.aop.objenesis.strategy.StdInstantiatorStrategy}
- */
- public ObjenesisStd() {
- super(new StdInstantiatorStrategy());
- }
-
- /**
- * Instance using the {@link com.fr.third.springframework.aop.objenesis.strategy.StdInstantiatorStrategy} with or without
- * caching {@link com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator}s
- *
- * @param useCache If {@link com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator}s should be cached
- */
- public ObjenesisStd(boolean useCache) {
- super(new StdInstantiatorStrategy(), useCache);
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/ObjectInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/ObjectInstantiator.java
deleted file mode 100644
index c18b2fe1e..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/ObjectInstantiator.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator;
-
-/**
- * Instantiates a new object.
- *
- * @author Leonardo Mesquita
- */
-public interface ObjectInstantiator {
-
- /**
- * Returns a new instance of an object. The returned object's class is defined by the
- * implementation.
- *
- * @return A new instance of an object.
- */
- T newInstance();
-
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/SerializationInstantiatorHelper.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/SerializationInstantiatorHelper.java
deleted file mode 100644
index 515b69cbe..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/SerializationInstantiatorHelper.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator;
-
-import java.io.Serializable;
-
-/**
- * Helper for common serialization-compatible instantiation functions
- *
- * @author Leonardo Mesquita
- */
-public class SerializationInstantiatorHelper {
-
- /**
- * Returns the first non-serializable superclass of a given class. According to Java Object
- * Serialization Specification, objects read from a stream are initialized by calling an
- * accessible no-arg constructor from the first non-serializable superclass in the object's
- * hierarchy, allowing the state of non-serializable fields to be correctly initialized.
- *
- * @param Type to instantiate
- * @param type Serializable class for which the first non-serializable superclass is to be found
- * @return The first non-serializable superclass of 'type'.
- * @see Serializable
- */
- public static Class super T> getNonSerializableSuperClass(Class type) {
- Class super T> result = type;
- while(Serializable.class.isAssignableFrom(result)) {
- result = result.getSuperclass();
- if(result == null) {
- throw new Error("Bad class hierarchy: No non-serializable parents");
- }
- }
- return result;
-
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android10Instantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android10Instantiator.java
deleted file mode 100644
index 5795e702b..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android10Instantiator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.android;
-
-import java.io.ObjectInputStream;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiator for Android API level 10 and lover which creates objects without driving their
- * constructors, using internal methods on the Dalvik implementation of
- * {@link ObjectInputStream}.
- *
- * @author Piotr 'Qertoip' Włodarek
- */
-@Instantiator(Typology.STANDARD)
-public class Android10Instantiator implements ObjectInstantiator {
- private final Class type;
- private final Method newStaticMethod;
-
- public Android10Instantiator(Class type) {
- this.type = type;
- newStaticMethod = getNewStaticMethod();
- }
-
- public T newInstance() {
- try {
- return type.cast(newStaticMethod.invoke(null, type, Object.class));
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Method getNewStaticMethod() {
- try {
- Method newStaticMethod = ObjectInputStream.class.getDeclaredMethod(
- "newInstance", Class.class, Class.class);
- newStaticMethod.setAccessible(true);
- return newStaticMethod;
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android17Instantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android17Instantiator.java
deleted file mode 100644
index 36d9b8b0c..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android17Instantiator.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.android;
-
-import java.io.ObjectStreamClass;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiator for Android API level 11 to 17 which creates objects without driving their
- * constructors, using internal methods on the Dalvik implementation of {@link ObjectStreamClass}.
- *
- * @author Ian Parkinson (Google Inc.)
- */
-@Instantiator(Typology.STANDARD)
-public class Android17Instantiator implements ObjectInstantiator {
- private final Class type;
- private final Method newInstanceMethod;
- private final Integer objectConstructorId;
-
- public Android17Instantiator(Class type) {
- this.type = type;
- newInstanceMethod = getNewInstanceMethod();
- objectConstructorId = findConstructorIdForJavaLangObjectConstructor();
- }
-
- public T newInstance() {
- try {
- return type.cast(newInstanceMethod.invoke(null, type, objectConstructorId));
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Method getNewInstanceMethod() {
- try {
- Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod(
- "newInstance", Class.class, Integer.TYPE);
- newInstanceMethod.setAccessible(true);
- return newInstanceMethod;
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Integer findConstructorIdForJavaLangObjectConstructor() {
- try {
- Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod(
- "getConstructorId", Class.class);
- newInstanceMethod.setAccessible(true);
-
- return (Integer) newInstanceMethod.invoke(null, Object.class);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android18Instantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android18Instantiator.java
deleted file mode 100644
index 81957ace2..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/Android18Instantiator.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.android;
-
-import java.io.ObjectStreamClass;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiator for Android API leve 18 and higher. Same as the version 17 but the
- * newInstance now takes a long in parameter
- *
- * @author Henri Tremblay
- */
-@Instantiator(Typology.STANDARD)
-public class Android18Instantiator implements ObjectInstantiator {
- private final Class type;
- private final Method newInstanceMethod;
- private final Long objectConstructorId;
-
- public Android18Instantiator(Class type) {
- this.type = type;
- newInstanceMethod = getNewInstanceMethod();
- objectConstructorId = findConstructorIdForJavaLangObjectConstructor();
- }
-
- public T newInstance() {
- try {
- return type.cast(newInstanceMethod.invoke(null, type, objectConstructorId));
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Method getNewInstanceMethod() {
- try {
- Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance",
- Class.class, Long.TYPE);
- newInstanceMethod.setAccessible(true);
- return newInstanceMethod;
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Long findConstructorIdForJavaLangObjectConstructor() {
- try {
- Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("getConstructorId",
- Class.class);
- newInstanceMethod.setAccessible(true);
-
- return (Long) newInstanceMethod.invoke(null, Object.class);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/AndroidSerializationInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/AndroidSerializationInstantiator.java
deleted file mode 100644
index 6dd9a25d2..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/android/AndroidSerializationInstantiator.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.android;
-
-import java.io.ObjectStreamClass;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * {@link ObjectInstantiator} for Android which creates objects using the constructor from the first
- * non-serializable parent class constructor, using internal methods on the Dalvik implementation of
- * {@link ObjectStreamClass}.
- *
- * @author Ian Parkinson (Google Inc.)
- */
-@Instantiator(Typology.SERIALIZATION)
-public class AndroidSerializationInstantiator implements ObjectInstantiator {
- private final Class type;
- private final ObjectStreamClass objectStreamClass;
- private final Method newInstanceMethod;
-
- public AndroidSerializationInstantiator(Class type) {
- this.type = type;
- newInstanceMethod = getNewInstanceMethod();
- Method m = null;
- try {
- m = ObjectStreamClass.class.getMethod("lookupAny", Class.class);
- } catch (NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- try {
- objectStreamClass = (ObjectStreamClass) m.invoke(null, type);
- } catch (IllegalAccessException e) {
- throw new ObjenesisException(e);
- } catch (InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-
- public T newInstance() {
- try {
- return type.cast(newInstanceMethod.invoke(objectStreamClass, type));
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalArgumentException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Method getNewInstanceMethod() {
- try {
- Method newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod(
- "newInstance", Class.class);
- newInstanceMethod.setAccessible(true);
- return newInstanceMethod;
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/annotations/Instantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/annotations/Instantiator.java
deleted file mode 100644
index de8a7c8b0..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/annotations/Instantiator.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.annotations;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Denote that the class in an instantiator of a given type
- *
- * @author Henri Tremblay
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-public @interface Instantiator {
-
- /**
- * @return type of instantiator
- */
- Typology value();
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/annotations/Typology.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/annotations/Typology.java
deleted file mode 100644
index 2e2512768..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/annotations/Typology.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.annotations;
-
-/**
- * Possible types of instantiator
- * @author Henri Tremblay
- */
-public enum Typology {
- /**
- * Mark an instantiator used for standard instantiation (not calling a constructor).
- */
- STANDARD,
-
- /**
- * Mark an instantiator used for serialization.
- */
- SERIALIZATION,
-
- /**
- * Mark an instantiator that doesn't behave like a {@link #STANDARD} nor a {@link #SERIALIZATION} (e.g. calls a constructor, fails
- * all the time, etc.)
- */
- NOT_COMPLIANT,
-
- /**
- * No type specified on the instantiator class
- */
- UNKNOWN
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/AccessibleInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/AccessibleInstantiator.java
deleted file mode 100644
index 759538927..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/AccessibleInstantiator.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.basic;
-
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates a class by grabbing the no-args constructor, making it accessible and then calling
- * Constructor.newInstance(). Although this still requires no-arg constructors, it can call
- * non-public constructors (if the security manager allows it).
- *
- * @author Joe Walnes
- * @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator
- */
-@Instantiator(Typology.NOT_COMPLIANT)
-public class AccessibleInstantiator extends ConstructorInstantiator {
-
- public AccessibleInstantiator(Class type) {
- super(type);
- if(constructor != null) {
- constructor.setAccessible(true);
- }
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ConstructorInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ConstructorInstantiator.java
deleted file mode 100644
index 5a7fbb0dd..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ConstructorInstantiator.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.basic;
-
-import java.lang.reflect.Constructor;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates a class by grabbing the no args constructor and calling Constructor.newInstance().
- * This can deal with default public constructors, but that's about it.
- *
- * @author Joe Walnes
- * @param Type instantiated
- * @see ObjectInstantiator
- */
-@Instantiator(Typology.NOT_COMPLIANT)
-public class ConstructorInstantiator implements ObjectInstantiator {
-
- protected Constructor constructor;
-
- public ConstructorInstantiator(Class type) {
- try {
- constructor = type.getDeclaredConstructor((Class[]) null);
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
- public T newInstance() {
- try {
- return constructor.newInstance((Object[]) null);
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/FailingInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/FailingInstantiator.java
deleted file mode 100644
index 9807425ed..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/FailingInstantiator.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.basic;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * The instantiator that always throws an exception. Mainly used for tests
- *
- * @author Henri Tremblay
- */
-@Instantiator(Typology.NOT_COMPLIANT)
-public class FailingInstantiator implements ObjectInstantiator {
-
- public FailingInstantiator(Class type) {
- }
-
- /**
- * @return Always throwing an exception
- */
- public T newInstance() {
- throw new ObjenesisException("Always failing");
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/NewInstanceInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/NewInstanceInstantiator.java
deleted file mode 100644
index d7e0c730d..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/NewInstanceInstantiator.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.basic;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * The simplest instantiator - simply calls Class.newInstance(). This can deal with default public
- * constructors, but that's about it.
- *
- * @author Joe Walnes
- * @see ObjectInstantiator
- */
-@Instantiator(Typology.NOT_COMPLIANT)
-public class NewInstanceInstantiator implements ObjectInstantiator {
-
- private final Class type;
-
- public NewInstanceInstantiator(Class type) {
- this.type = type;
- }
-
- public T newInstance() {
- try {
- return type.newInstance();
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/NullInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/NullInstantiator.java
deleted file mode 100644
index 24960ab3c..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/NullInstantiator.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.basic;
-
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * The instantiator that always return a null instance
- *
- * @author Henri Tremblay
- */
-@Instantiator(Typology.NOT_COMPLIANT)
-public class NullInstantiator implements ObjectInstantiator {
-
- public NullInstantiator(Class type) {
- }
-
- /**
- * @return Always null
- */
- public T newInstance() {
- return null;
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java
deleted file mode 100644
index ee1aa4dc0..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ObjectInputStreamInstantiator.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.basic;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.NotSerializableException;
-import java.io.ObjectInputStream;
-import java.io.ObjectStreamClass;
-import java.io.ObjectStreamConstants;
-import java.io.Serializable;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates a class by using a dummy input stream that always feeds data for an empty object of
- * the same kind. NOTE: This instantiator may not work properly if the class being instantiated
- * defines a "readResolve" method, since it may return objects that have been returned previously
- * (i.e., there's no guarantee that the returned object is a new one), or even objects from a
- * completely different class.
- *
- * @author Leonardo Mesquita
- * @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator
- */
-@Instantiator(Typology.SERIALIZATION)
-public class ObjectInputStreamInstantiator implements ObjectInstantiator {
- private static class MockStream extends InputStream {
-
- private int pointer;
- private byte[] data;
- private int sequence;
- private static final int[] NEXT = new int[] {1, 2, 2};
- private byte[][] buffers;
-
- private final byte[] FIRST_DATA;
- private static byte[] HEADER;
- private static byte[] REPEATING_DATA;
-
- static {
- initialize();
- }
-
- private static void initialize() {
- try {
- ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(byteOut);
- dout.writeShort(ObjectStreamConstants.STREAM_MAGIC);
- dout.writeShort(ObjectStreamConstants.STREAM_VERSION);
- HEADER = byteOut.toByteArray();
-
- byteOut = new ByteArrayOutputStream();
- dout = new DataOutputStream(byteOut);
-
- dout.writeByte(ObjectStreamConstants.TC_OBJECT);
- dout.writeByte(ObjectStreamConstants.TC_REFERENCE);
- dout.writeInt(ObjectStreamConstants.baseWireHandle);
- REPEATING_DATA = byteOut.toByteArray();
- }
- catch(IOException e) {
- throw new Error("IOException: " + e.getMessage());
- }
-
- }
-
- public MockStream(Class> clazz) {
- this.pointer = 0;
- this.sequence = 0;
- this.data = HEADER;
-
- // (byte) TC_OBJECT
- // (byte) TC_CLASSDESC
- // (short length)
- // (byte * className.length)
- // (long)serialVersionUID
- // (byte) SC_SERIALIZABLE
- // (short)0
- // TC_ENDBLOCKDATA
- // TC_NULL
- ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
- DataOutputStream dout = new DataOutputStream(byteOut);
- try {
- dout.writeByte(ObjectStreamConstants.TC_OBJECT);
- dout.writeByte(ObjectStreamConstants.TC_CLASSDESC);
- dout.writeUTF(clazz.getName());
- dout.writeLong(ObjectStreamClass.lookup(clazz).getSerialVersionUID());
- dout.writeByte(ObjectStreamConstants.SC_SERIALIZABLE);
- dout.writeShort((short) 0); // Zero fields
- dout.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA);
- dout.writeByte(ObjectStreamConstants.TC_NULL);
- }
- catch(IOException e) {
- throw new Error("IOException: " + e.getMessage());
- }
- this.FIRST_DATA = byteOut.toByteArray();
- buffers = new byte[][] {HEADER, FIRST_DATA, REPEATING_DATA};
- }
-
- private void advanceBuffer() {
- pointer = 0;
- sequence = NEXT[sequence];
- data = buffers[sequence];
- }
-
- @Override
- public int read() throws IOException {
- int result = data[pointer++];
- if(pointer >= data.length) {
- advanceBuffer();
- }
-
- return result;
- }
-
- @Override
- public int available() throws IOException {
- return Integer.MAX_VALUE;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- int left = len;
- int remaining = data.length - pointer;
-
- while(remaining <= left) {
- System.arraycopy(data, pointer, b, off, remaining);
- off += remaining;
- left -= remaining;
- advanceBuffer();
- remaining = data.length - pointer;
- }
- if(left > 0) {
- System.arraycopy(data, pointer, b, off, left);
- pointer += left;
- }
-
- return len;
- }
- }
-
- private ObjectInputStream inputStream;
-
- public ObjectInputStreamInstantiator(Class clazz) {
- if(Serializable.class.isAssignableFrom(clazz)) {
- try {
- this.inputStream = new ObjectInputStream(new MockStream(clazz));
- }
- catch(IOException e) {
- throw new Error("IOException: " + e.getMessage());
- }
- }
- else {
- throw new ObjenesisException(new NotSerializableException(clazz + " not serializable"));
- }
- }
-
- @SuppressWarnings("unchecked")
- public T newInstance() {
- try {
- return (T) inputStream.readObject();
- }
- catch(ClassNotFoundException e) {
- throw new Error("ClassNotFoundException: " + e.getMessage());
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java
deleted file mode 100644
index 74d11c8f4..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ObjectStreamClassInstantiator.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.basic;
-
-import java.io.ObjectStreamClass;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates a class by using reflection to make a call to private method
- * ObjectStreamClass.newInstance, present in many JVM implementations. This instantiator will create
- * classes in a way compatible with serialization, calling the first non-serializable superclass'
- * no-arg constructor.
- *
- * @author Leonardo Mesquita
- * @see ObjectInstantiator
- * @see java.io.Serializable
- */
-@Instantiator(Typology.SERIALIZATION)
-public class ObjectStreamClassInstantiator implements ObjectInstantiator {
-
- private static Method newInstanceMethod;
-
- private static void initialize() {
- if(newInstanceMethod == null) {
- try {
- newInstanceMethod = ObjectStreamClass.class.getDeclaredMethod("newInstance");
- newInstanceMethod.setAccessible(true);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- private final ObjectStreamClass objStreamClass;
-
- public ObjectStreamClassInstantiator(Class type) {
- initialize();
- objStreamClass = ObjectStreamClass.lookup(type);
- }
-
- @SuppressWarnings("unchecked")
- public T newInstance() {
-
- try {
- return (T) newInstanceMethod.invoke(objStreamClass);
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
-
- }
-
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ProxyingInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ProxyingInstantiator.java
deleted file mode 100644
index 30f55ae59..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/basic/ProxyingInstantiator.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.basic;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-import com.fr.third.springframework.aop.objenesis.instantiator.util.ClassDefinitionUtils;
-
-import static com.fr.third.springframework.aop.objenesis.instantiator.util.ClassDefinitionUtils.*;
-
-/**
- * This instantiator creates a class by dynamically extending it. It will skip the call to the parent constructor
- * in the bytecode. So that the constructor is indeed not called but you however instantiate a child class, not
- * the actual class. The class loader will normally throw a {@code VerifyError} is you do that. However, using
- * {@code -Xverify:none} should make it work
- *
- * @author Henri Tremblay
- */
-@Instantiator(Typology.STANDARD)
-public class ProxyingInstantiator implements ObjectInstantiator {
-
- private static final int INDEX_CLASS_THIS = 1;
- private static final int INDEX_CLASS_SUPERCLASS = 2;
- private static final int INDEX_UTF8_CONSTRUCTOR_NAME = 3;
- private static final int INDEX_UTF8_CONSTRUCTOR_DESC = 4;
- private static final int INDEX_UTF8_CODE_ATTRIBUTE = 5;
- private static final int INDEX_UTF8_CLASS = 7;
- private static final int INDEX_UTF8_SUPERCLASS = 8;
-
- private static int CONSTANT_POOL_COUNT = 9;
-
- private static final byte[] CODE = { OPS_aload_0, OPS_return};
- private static final int CODE_ATTRIBUTE_LENGTH = 12 + CODE.length;
-
- private static final String SUFFIX = "$$$Objenesis";
-
- private static final String CONSTRUCTOR_NAME = "";
- private static final String CONSTRUCTOR_DESC = "()V";
-
- private final Class> newType;
-
- public ProxyingInstantiator(Class type) {
-
- byte[] classBytes = writeExtendingClass(type, SUFFIX);
-
- try {
- newType = ClassDefinitionUtils.defineClass(type.getName() + SUFFIX, classBytes, type.getClassLoader());
- } catch (Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
- @SuppressWarnings("unchecked")
- public T newInstance() {
- try {
- return (T) newType.newInstance();
- } catch (InstantiationException e) {
- throw new ObjenesisException(e);
- } catch (IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- }
-
- /**
- * Will generate the bytes for a class extending the type passed in parameter. This class will
- * only have an empty default constructor
- *
- * @param type type to extend
- * @param suffix the suffix appended to the class name to create the next extending class name
- * @return the byte for the class
- * @throws ObjenesisException is something goes wrong
- */
- private static byte[] writeExtendingClass(Class> type, String suffix) {
- String parentClazz = classNameToInternalClassName(type.getName());
- String clazz = parentClazz + suffix;
-
- DataOutputStream in = null;
- ByteArrayOutputStream bIn = new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class
- try {
- in = new DataOutputStream(bIn);
-
- in.write(MAGIC);
- in.write(VERSION);
- in.writeShort(CONSTANT_POOL_COUNT);
-
- // set all the constant pool here
-
- // 1. class
- in.writeByte(CONSTANT_Class);
- in.writeShort(INDEX_UTF8_CLASS);
-
- // 2. super class
- in.writeByte(CONSTANT_Class);
- in.writeShort(INDEX_UTF8_SUPERCLASS);
-
- // 3. default constructor name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(CONSTRUCTOR_NAME);
-
- // 4. default constructor description
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(CONSTRUCTOR_DESC);
-
- // 5. Code
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF("Code");
-
- // 6. Class name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF("L" + clazz + ";");
-
- // 7. Class name (again)
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(clazz);
-
- // 8. Superclass name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(parentClazz);
-
- // end of constant pool
-
- // access flags: We want public, ACC_SUPER is always there
- in.writeShort(ACC_PUBLIC | ACC_SUPER);
-
- // this class index in the constant pool
- in.writeShort(INDEX_CLASS_THIS);
-
- // super class index in the constant pool
- in.writeShort(INDEX_CLASS_SUPERCLASS);
-
- // interfaces implemented count (we have none)
- in.writeShort(0);
-
- // fields count (we have none)
- in.writeShort(0);
-
- // methods count (we have one: the default constructor)
- in.writeShort(1);
-
- // default constructor method_info
- in.writeShort(ACC_PUBLIC);
- in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name ()
- in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description
- in.writeShort(1); // number of attributes: only one, the code
-
- // code attribute of the default constructor
- in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE);
- in.writeInt(CODE_ATTRIBUTE_LENGTH); // attribute length
- in.writeShort(1); // max_stack
- in.writeShort(1); // max_locals
- in.writeInt(CODE.length); // code length
- in.write(CODE);
- in.writeShort(0); // exception_table_length = 0
- in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable
-
- // class attributes
- in.writeShort(0); // none. No need to have a source file attribute
-
-
- } catch (IOException e) {
- throw new ObjenesisException(e);
- } finally {
- if(in != null) {
- try {
- in.close();
- } catch (IOException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- return bIn.toByteArray();
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJInstantiator.java
deleted file mode 100644
index 9a35db494..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJInstantiator.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.gcj;
-
-import java.lang.reflect.InvocationTargetException;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to
- * work on GCJ JVMs. This instantiator will not call any constructors.
- *
- * @author Leonardo Mesquita
- * @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator
- */
-@Instantiator(Typology.STANDARD)
-public class GCJInstantiator extends GCJInstantiatorBase {
- public GCJInstantiator(Class type) {
- super(type);
- }
-
- @Override
- public T newInstance() {
- try {
- return type.cast(newObjectMethod.invoke(dummyStream, type, Object.class));
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJInstantiatorBase.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJInstantiatorBase.java
deleted file mode 100644
index 2390266f1..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJInstantiatorBase.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.gcj;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-
-/**
- * Base class for GCJ-based instantiators. It initializes reflection access to method
- * ObjectInputStream.newObject, as well as creating a dummy ObjectInputStream to be used as the
- * "this" argument for the method.
- *
- * @author Leonardo Mesquita
- */
-public abstract class GCJInstantiatorBase implements ObjectInstantiator {
- static Method newObjectMethod = null;
- static ObjectInputStream dummyStream;
-
- private static class DummyStream extends ObjectInputStream {
- public DummyStream() throws IOException {
- }
- }
-
- private static void initialize() {
- if(newObjectMethod == null) {
- try {
- newObjectMethod = ObjectInputStream.class.getDeclaredMethod("newObject", new Class[] {
- Class.class, Class.class});
- newObjectMethod.setAccessible(true);
- dummyStream = new DummyStream();
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- catch(IOException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- protected final Class type;
-
- public GCJInstantiatorBase(Class type) {
- this.type = type;
- initialize();
- }
-
- public abstract T newInstance();
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJSerializationInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJSerializationInstantiator.java
deleted file mode 100644
index 16a4d70ad..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/gcj/GCJSerializationInstantiator.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.gcj;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.SerializationInstantiatorHelper;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates a class by making a call to internal GCJ private methods. It is only supposed to
- * work on GCJ JVMs. This instantiator will create classes in a way compatible with serialization,
- * calling the first non-serializable superclass' no-arg constructor.
- *
- * @author Leonardo Mesquita
- * @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator
- */
-@Instantiator(Typology.SERIALIZATION)
-public class GCJSerializationInstantiator extends GCJInstantiatorBase {
- private Class super T> superType;
-
- public GCJSerializationInstantiator(Class type) {
- super(type);
- this.superType = SerializationInstantiatorHelper.getNonSerializableSuperClass(type);
- }
-
- @Override
- public T newInstance() {
- try {
- return type.cast(newObjectMethod.invoke(dummyStream, type, superType));
- }
- catch(Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/perc/PercInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/perc/PercInstantiator.java
deleted file mode 100644
index 894193b6a..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/perc/PercInstantiator.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.perc;
-
-import java.io.ObjectInputStream;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates a class by making a call to internal Perc private methods. It is only supposed to
- * work on Perc JVMs. This instantiator will not call any constructors. The code was provided by
- * Aonix Perc support team.
- *
- * @author Henri Tremblay
- * @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator
- */
-@Instantiator(Typology.STANDARD)
-public class PercInstantiator implements ObjectInstantiator {
-
- private final Method newInstanceMethod;
-
- private final Object[] typeArgs = new Object[] { null, Boolean.FALSE };
-
- public PercInstantiator(Class type) {
-
- typeArgs[0] = type;
-
- try {
- newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("newInstance", Class.class,
- Boolean.TYPE);
- newInstanceMethod.setAccessible(true);
- }
- catch(RuntimeException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
-
- @SuppressWarnings("unchecked")
- public T newInstance() {
- try {
- return (T) newInstanceMethod.invoke(null, typeArgs);
- } catch (Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/perc/PercSerializationInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/perc/PercSerializationInstantiator.java
deleted file mode 100644
index ea9ab3acd..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/perc/PercSerializationInstantiator.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.perc;
-
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates a class by making a call to internal Perc private methods. It is only supposed to
- * work on Perc JVMs. This instantiator will create classes in a way compatible with serialization,
- * calling the first non-serializable superclass' no-arg constructor.
- *
- * Based on code provided by Aonix but doesn't work right now
- *
- * @author Henri Tremblay
- * @see com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator
- */
-@Instantiator(Typology.SERIALIZATION)
-public class PercSerializationInstantiator implements ObjectInstantiator {
-
- private Object[] typeArgs;
-
- private final Method newInstanceMethod;
-
- public PercSerializationInstantiator(Class type) {
-
- // Find the first unserializable parent class
- Class super T> unserializableType = type;
-
- while(Serializable.class.isAssignableFrom(unserializableType)) {
- unserializableType = unserializableType.getSuperclass();
- }
-
- try {
- // Get the special Perc method to call
- Class> percMethodClass = Class.forName("COM.newmonics.PercClassLoader.Method");
-
- newInstanceMethod = ObjectInputStream.class.getDeclaredMethod("noArgConstruct",
- new Class[] {Class.class, Object.class, percMethodClass});
- newInstanceMethod.setAccessible(true);
-
- // Create invoke params
- Class> percClassClass = Class.forName("COM.newmonics.PercClassLoader.PercClass");
- Method getPercClassMethod = percClassClass.getDeclaredMethod("getPercClass", Class.class);
- Object someObject = getPercClassMethod.invoke(null, unserializableType);
- Method findMethodMethod = someObject.getClass().getDeclaredMethod("findMethod",
- new Class[] {String.class});
- Object percMethod = findMethodMethod.invoke(someObject, "()V");
-
- typeArgs = new Object[] {unserializableType, type, percMethod};
-
- }
- catch(ClassNotFoundException e) {
- throw new ObjenesisException(e);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- }
-
- @SuppressWarnings("unchecked")
- public T newInstance() {
- try {
- return (T) newInstanceMethod.invoke(null, typeArgs);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/MagicInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/MagicInstantiator.java
deleted file mode 100644
index 045716400..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/MagicInstantiator.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.sun;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-import com.fr.third.springframework.aop.objenesis.instantiator.util.ClassDefinitionUtils;
-
-import static com.fr.third.springframework.aop.objenesis.instantiator.util.ClassDefinitionUtils.*;
-
-/**
- * This instantiator will correctly bypass the constructors by instantiating the class using the default
- * constructor from Object. It will be allowed to do so by extending {@code MagicAccessorImpl} which prevents
- * its children to be verified by the class loader
- *
- * @author Henri Tremblay
- */
-@Instantiator(Typology.STANDARD)
-public class MagicInstantiator implements ObjectInstantiator {
-
- private static final String MAGIC_ACCESSOR = getMagicClass();
-
- private static final int INDEX_CLASS_THIS = 1;
- private static final int INDEX_CLASS_SUPERCLASS = 2;
- private static final int INDEX_UTF8_CONSTRUCTOR_NAME = 3;
- private static final int INDEX_UTF8_CONSTRUCTOR_DESC = 4;
- private static final int INDEX_UTF8_CODE_ATTRIBUTE = 5;
- private static final int INDEX_UTF8_INSTANTIATOR_CLASS = 7;
- private static final int INDEX_UTF8_SUPERCLASS = 8;
- private static final int INDEX_CLASS_INTERFACE = 9;
- private static final int INDEX_UTF8_INTERFACE = 10;
- private static final int INDEX_UTF8_NEWINSTANCE_NAME = 11;
- private static final int INDEX_UTF8_NEWINSTANCE_DESC = 12;
- private static final int INDEX_METHODREF_OBJECT_CONSTRUCTOR = 13;
- private static final int INDEX_CLASS_OBJECT = 14;
- private static final int INDEX_UTF8_OBJECT = 15;
- private static final int INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR = 16;
- private static final int INDEX_CLASS_TYPE = 17;
- private static final int INDEX_UTF8_TYPE = 18;
-
- private static int CONSTANT_POOL_COUNT = 19;
-
- private static final byte[] CONSTRUCTOR_CODE = { OPS_aload_0, OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, OPS_return};
- private static final int CONSTRUCTOR_CODE_ATTRIBUTE_LENGTH = 12 + CONSTRUCTOR_CODE.length;
-
- private static final byte[] NEWINSTANCE_CODE = { OPS_new, 0, INDEX_CLASS_TYPE, OPS_dup, OPS_invokespecial, 0, INDEX_METHODREF_OBJECT_CONSTRUCTOR, OPS_areturn};
- private static final int NEWINSTANCE_CODE_ATTRIBUTE_LENGTH = 12 + NEWINSTANCE_CODE.length;
-
- private static final String CONSTRUCTOR_NAME = "";
- private static final String CONSTRUCTOR_DESC = "()V";
-
- private ObjectInstantiator instantiator;
-
- public MagicInstantiator(Class type) {
- instantiator = newInstantiatorOf(type);
- }
-
- /**
- * Get the underlying instantiator.
- *
- * {@link MagicInstantiator} is a wrapper around another object
- * which implements {@link ObjectInstantiator} interface.
- * This method exposes that instantiator.
- *
- * @return the underlying instantiator
- */
- public ObjectInstantiator getInstantiator() {
- return instantiator;
- }
-
- private ObjectInstantiator newInstantiatorOf(Class type) {
- String suffix = type.getSimpleName();
- String className = getClass().getName() + "$$$" + suffix;
-
- Class> clazz = getExistingClass(getClass().getClassLoader(), className);
-
- if(clazz == null) {
- byte[] classBytes = writeExtendingClass(type, className);
-
- try {
- clazz = ClassDefinitionUtils.defineClass(className, classBytes, getClass().getClassLoader());
- } catch (Exception e) {
- throw new ObjenesisException(e);
- }
- }
-
- try {
- return clazz.newInstance();
- } catch (InstantiationException e) {
- throw new ObjenesisException(e);
- } catch (IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- }
-
- /**
- * Will generate the bytes for a class extending the type passed in parameter. This class will
- * only have an empty default constructor
- *
- * @param type type to extend
- * @param className name of the wrapped instantiator class
- * @return the byte for the class
- * @throws ObjenesisException is something goes wrong
- */
- private byte[] writeExtendingClass(Class> type, String className) {
- String clazz = classNameToInternalClassName(className);
-
- DataOutputStream in = null;
- ByteArrayOutputStream bIn = new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class
- try {
- in = new DataOutputStream(bIn);
-
- in.write(MAGIC);
- in.write(VERSION);
- in.writeShort(CONSTANT_POOL_COUNT);
-
- // set all the constant pool here
-
- // 1. class
- in.writeByte(CONSTANT_Class);
- in.writeShort(INDEX_UTF8_INSTANTIATOR_CLASS);
-
- // 2. super class
- in.writeByte(CONSTANT_Class);
- in.writeShort(INDEX_UTF8_SUPERCLASS);
-
- // 3. default constructor name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(CONSTRUCTOR_NAME);
-
- // 4. default constructor description
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(CONSTRUCTOR_DESC);
-
- // 5. Code
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF("Code");
-
- // 6. Class name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF("L" + clazz + ";");
-
- // 7. Class name (again)
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(clazz);
-
- // 8. Superclass name
- in.writeByte(CONSTANT_Utf8);
-// in.writeUTF("java/lang/Object");
- in.writeUTF(MAGIC_ACCESSOR);
-
- // 9. ObjectInstantiator interface
- in.writeByte(CONSTANT_Class);
- in.writeShort(INDEX_UTF8_INTERFACE);
-
- // 10. ObjectInstantiator name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(ObjectInstantiator.class.getName().replace('.', '/'));
-
- // 11. newInstance name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF("newInstance");
-
- // 12. newInstance desc
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF("()Ljava/lang/Object;");
-
- // 13. Methodref to the Object constructor
- in.writeByte(CONSTANT_Methodref);
- in.writeShort(INDEX_CLASS_OBJECT);
- in.writeShort(INDEX_NAMEANDTYPE_DEFAULT_CONSTRUCTOR);
-
- // 14. Object class
- in.writeByte(CONSTANT_Class);
- in.writeShort(INDEX_UTF8_OBJECT);
-
- // 15. Object class name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF("java/lang/Object");
-
- // 16. Default constructor name and type
- in.writeByte(CONSTANT_NameAndType);
- in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME);
- in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC);
-
- // 17. Type to instantiate class
- in.writeByte(CONSTANT_Class);
- in.writeShort(INDEX_UTF8_TYPE);
-
- // 18. Type to instantiate name
- in.writeByte(CONSTANT_Utf8);
- in.writeUTF(classNameToInternalClassName(type.getName()));
-
- // end of constant pool
-
- // access flags: We want public, ACC_SUPER is always there
- in.writeShort(ACC_PUBLIC | ACC_SUPER | ACC_FINAL);
-
- // this class index in the constant pool
- in.writeShort(INDEX_CLASS_THIS);
-
- // super class index in the constant pool
- in.writeShort(INDEX_CLASS_SUPERCLASS);
-
- // interfaces implemented count (we have none)
- in.writeShort(1);
- in.writeShort(INDEX_CLASS_INTERFACE);
-
- // fields count (we have none)
- in.writeShort(0);
-
- // method count (we have two: the default constructor and newInstance)
- in.writeShort(2);
-
- // default constructor method_info
- in.writeShort(ACC_PUBLIC);
- in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name ()
- in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description
- in.writeShort(1); // number of attributes: only one, the code
-
- // code attribute of the default constructor
- in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE);
- in.writeInt(CONSTRUCTOR_CODE_ATTRIBUTE_LENGTH); // attribute length
- in.writeShort(0); // max_stack
- in.writeShort(1); // max_locals
- in.writeInt(CONSTRUCTOR_CODE.length); // code length
- in.write(CONSTRUCTOR_CODE);
- in.writeShort(0); // exception_table_length = 0
- in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable
-
- // newInstance method_info
- in.writeShort(ACC_PUBLIC);
- in.writeShort(INDEX_UTF8_NEWINSTANCE_NAME); // index of the method name (newInstance)
- in.writeShort(INDEX_UTF8_NEWINSTANCE_DESC); // index of the description
- in.writeShort(1); // number of attributes: only one, the code
-
- // code attribute of newInstance
- in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE);
- in.writeInt(NEWINSTANCE_CODE_ATTRIBUTE_LENGTH); // attribute length
- in.writeShort(2); // max_stack
- in.writeShort(1); // max_locals
- in.writeInt(NEWINSTANCE_CODE.length); // code length
- in.write(NEWINSTANCE_CODE);
- in.writeShort(0); // exception_table_length = 0
- in.writeShort(0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable
-
- // class attributes
- in.writeShort(0); // none. No need to have a source file attribute
-
- } catch (IOException e) {
- throw new ObjenesisException(e);
- } finally {
- if(in != null) {
- try {
- in.close();
- } catch (IOException e) {
- throw new ObjenesisException(e);
- }
- }
- }
-
- return bIn.toByteArray();
- }
-
- public T newInstance() {
- return instantiator.newInstance();
- }
-
- private static String getMagicClass() {
- try {
- Class.forName("sun.reflect.MagicAccessorImpl", false, MagicInstantiator.class.getClassLoader());
- return "sun/reflect/MagicAccessorImpl";
- } catch (ClassNotFoundException e) {
- return "jdk/internal/reflect/MagicAccessorImpl";
- }
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/SunReflectionFactoryHelper.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/SunReflectionFactoryHelper.java
deleted file mode 100644
index 994c6a52a..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/SunReflectionFactoryHelper.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.sun;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-
-
-/**
- * Helper methods providing access to {@link sun.reflect.ReflectionFactory} via reflection, for use
- * by the {@link ObjectInstantiator}s that use it.
- *
- * @author Henri Tremblay
- */
-@SuppressWarnings("restriction")
-class SunReflectionFactoryHelper {
-
- @SuppressWarnings("unchecked")
- public static Constructor newConstructorForSerialization(Class type,
- Constructor> constructor) {
- Class> reflectionFactoryClass = getReflectionFactoryClass();
- Object reflectionFactory = createReflectionFactory(reflectionFactoryClass);
-
- Method newConstructorForSerializationMethod = getNewConstructorForSerializationMethod(
- reflectionFactoryClass);
-
- try {
- return (Constructor) newConstructorForSerializationMethod.invoke(
- reflectionFactory, type, constructor);
- }
- catch(IllegalArgumentException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Class> getReflectionFactoryClass() {
- try {
- return Class.forName("sun.reflect.ReflectionFactory");
- }
- catch(ClassNotFoundException e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Object createReflectionFactory(Class> reflectionFactoryClass) {
- try {
- Method method = reflectionFactoryClass.getDeclaredMethod(
- "getReflectionFactory");
- return method.invoke(null);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalAccessException e) {
- throw new ObjenesisException(e);
- }
- catch(IllegalArgumentException e) {
- throw new ObjenesisException(e);
- }
- catch(InvocationTargetException e) {
- throw new ObjenesisException(e);
- }
- }
-
- private static Method getNewConstructorForSerializationMethod(Class> reflectionFactoryClass) {
- try {
- return reflectionFactoryClass.getDeclaredMethod(
- "newConstructorForSerialization", Class.class, Constructor.class);
- }
- catch(NoSuchMethodException e) {
- throw new ObjenesisException(e);
- }
- }
-}
diff --git a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java b/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java
deleted file mode 100644
index 761001115..000000000
--- a/fine-spring/src/com/fr/third/springframework/aop/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright 2006-2017 the original author or authors.
- *
- * 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.
- */
-package com.fr.third.springframework.aop.objenesis.instantiator.sun;
-
-import java.lang.reflect.Constructor;
-
-import com.fr.third.springframework.aop.objenesis.ObjenesisException;
-import com.fr.third.springframework.aop.objenesis.instantiator.ObjectInstantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Instantiator;
-import com.fr.third.springframework.aop.objenesis.instantiator.annotations.Typology;
-
-/**
- * Instantiates an object, WITHOUT calling it's constructor, using internal
- * sun.reflect.ReflectionFactory - a class only available on JDK's that use Sun's 1.4 (or later)
- * Java implementation. This is the best way to instantiate an object without any side effects
- * caused by the constructor - however it is not available on every platform.
- *
- * @author Joe Walnes
- * @see ObjectInstantiator
- */
-@Instantiator(Typology.STANDARD)
-public class SunReflectionFactoryInstantiator implements ObjectInstantiator {
-
- private final Constructor mungedConstructor;
-
- public SunReflectionFactoryInstantiator(Class type) {
- Constructor