mirror of https://github.com/apache/lucene.git
SOLR-875: Upgraded Lucene and consolidated the OpenBitSet implementation
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@723994 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
527bce2658
commit
246a83f0d4
|
@ -173,6 +173,8 @@ Other Changes
|
|||
|
||||
7. SOLR-889: Upgraded to commons-io-1.4.jar and commons-fileupload-1.2.1.jar (ryan)
|
||||
|
||||
8. SOLR-875: Upgraded to Lucene 2.9-dev (r723985) and consolidated the BitSet implementations (Michael Busch, gsingers)
|
||||
|
||||
|
||||
Build
|
||||
----------------------
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
AnyObjectId[250f81771570bf7abf5c89245e8372ea821b14a1] was removed in git history.
|
||||
AnyObjectId[bd68f2e2af1f4c65f2857a0c5fb2d39b910e122d] was removed in git history.
|
||||
Apache SVN contains full history.
|
|
@ -1,2 +1,2 @@
|
|||
AnyObjectId[7bb75010db926e6b68ea590c731fcb145a0f59f3] was removed in git history.
|
||||
AnyObjectId[392f97ca7b216bcb772746bc4106154c96f2c4f6] was removed in git history.
|
||||
Apache SVN contains full history.
|
|
@ -1,2 +1,2 @@
|
|||
AnyObjectId[2873bf0293528695fecbb505f61e0283a75920b0] was removed in git history.
|
||||
AnyObjectId[76fe36d5a34fea911866a623f2b81a99b5d51462] was removed in git history.
|
||||
Apache SVN contains full history.
|
|
@ -1,2 +1,2 @@
|
|||
AnyObjectId[52a9a5de073e05d888b6c5f390b0739abc4404fb] was removed in git history.
|
||||
AnyObjectId[734a27bf9d7d0e1af60c959f3ac94fa396faf78f] was removed in git history.
|
||||
Apache SVN contains full history.
|
|
@ -1,2 +1,2 @@
|
|||
AnyObjectId[c01bd51bcd6d5690ff1682177107da1c7ae8139e] was removed in git history.
|
||||
AnyObjectId[54d7e351cf51f25642359e551e2df1765f9b5a3c] was removed in git history.
|
||||
Apache SVN contains full history.
|
|
@ -1,2 +1,2 @@
|
|||
AnyObjectId[5184484659bb72515f7b6f47145478dadd586001] was removed in git history.
|
||||
AnyObjectId[b1ad8fbea0c97811807841055b053aa535170386] was removed in git history.
|
||||
Apache SVN contains full history.
|
|
@ -29,7 +29,7 @@ import org.apache.solr.common.util.NamedList;
|
|||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.request.SimpleFacets;
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
import org.apache.solr.schema.SchemaField;
|
||||
import org.apache.solr.search.QueryParsing;
|
||||
import org.apache.lucene.queryParser.ParseException;
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.apache.solr.search.DocIterator;
|
|||
import org.apache.solr.search.DocSet;
|
||||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.util.BoundedTreeSet;
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
|
||||
package org.apache.solr.search;
|
||||
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.solr.util.BitSetIterator;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSetIterator;
|
||||
|
||||
/**
|
||||
* <code>BitDocSet</code> represents an unordered set of Lucene Document Ids
|
||||
|
@ -81,8 +81,8 @@ public class BitDocSet extends DocSetBase {
|
|||
|
||||
public DocIterator iterator() {
|
||||
return new DocIterator() {
|
||||
private final BitSetIterator iter = new BitSetIterator(bits);
|
||||
private int pos = iter.next();
|
||||
private final OpenBitSetIterator iter = new OpenBitSetIterator(bits);
|
||||
private int pos = iter.nextDoc();
|
||||
public boolean hasNext() {
|
||||
return pos>=0;
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ public class BitDocSet extends DocSetBase {
|
|||
|
||||
public int nextDoc() {
|
||||
int old=pos;
|
||||
pos=iter.next();
|
||||
pos=iter.nextDoc();
|
||||
return old;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
package org.apache.solr.search;
|
||||
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
|
||||
/**
|
||||
* <code>DocSet</code> represents an unordered set of Lucene Document Ids.
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
package org.apache.solr.search;
|
||||
|
||||
import org.apache.lucene.search.HitCollector;
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.solr.core.SolrConfig;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
|
||||
/**
|
||||
* @version $Id$
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
package org.apache.solr.search;
|
||||
|
||||
import org.apache.solr.util.BitUtil;
|
||||
import org.apache.lucene.util.BitUtil;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,7 +31,7 @@ import org.apache.solr.core.SolrConfig;
|
|||
import org.apache.solr.core.SolrCore;
|
||||
import org.apache.solr.core.SolrInfoMBean;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
import org.apache.solr.search.*;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
|
|
|
@ -17,10 +17,13 @@
|
|||
|
||||
package org.apache.solr.util;
|
||||
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
|
||||
/** An iterator to iterate over set bits in an OpenBitSet.
|
||||
* This is faster than nextSetBit() for iterating over the complete set of bits,
|
||||
* especially when the density of the bits set is high.
|
||||
*
|
||||
* @deprecated Use {@link org.apache.lucene.util.OpenBitSetIterator} instead.
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BitSetIterator {
|
||||
|
|
|
@ -18,782 +18,9 @@
|
|||
package org.apache.solr.util;
|
||||
|
||||
/** A variety of high efficiencly bit twiddling routines.
|
||||
*
|
||||
* @deprecated Use {@link org.apache.lucene.util.BitUtil} directly
|
||||
* @version $Id$
|
||||
*/
|
||||
public class BitUtil {
|
||||
|
||||
/** Returns the number of bits set in the long */
|
||||
public static int pop(long x) {
|
||||
/* Hacker's Delight 32 bit pop function:
|
||||
* http://www.hackersdelight.org/HDcode/newCode/pop_arrayHS.cc
|
||||
*
|
||||
int pop(unsigned x) {
|
||||
x = x - ((x >> 1) & 0x55555555);
|
||||
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
|
||||
x = (x + (x >> 4)) & 0x0F0F0F0F;
|
||||
x = x + (x >> 8);
|
||||
x = x + (x >> 16);
|
||||
return x & 0x0000003F;
|
||||
}
|
||||
***/
|
||||
|
||||
// 64 bit java version of the C function from above
|
||||
x = x - ((x >>> 1) & 0x5555555555555555L);
|
||||
x = (x & 0x3333333333333333L) + ((x >>>2 ) & 0x3333333333333333L);
|
||||
x = (x + (x >>> 4)) & 0x0F0F0F0F0F0F0F0FL;
|
||||
x = x + (x >>> 8);
|
||||
x = x + (x >>> 16);
|
||||
x = x + (x >>> 32);
|
||||
return ((int)x) & 0x7F;
|
||||
}
|
||||
|
||||
/*** Returns the number of set bits in an array of longs. */
|
||||
public static long pop_array(long A[], int wordOffset, int numWords) {
|
||||
/*
|
||||
* Robert Harley and David Seal's bit counting algorithm, as documented
|
||||
* in the revisions of Hacker's Delight
|
||||
* http://www.hackersdelight.org/revisions.pdf
|
||||
* http://www.hackersdelight.org/HDcode/newCode/pop_arrayHS.cc
|
||||
*
|
||||
* This function was adapted to Java, and extended to use 64 bit words.
|
||||
* if only we had access to wider registers like SSE from java...
|
||||
*
|
||||
* This function can be transformed to compute the popcount of other functions
|
||||
* on bitsets via something like this:
|
||||
* sed 's/A\[\([^]]*\)\]/\(A[\1] \& B[\1]\)/g'
|
||||
*
|
||||
*/
|
||||
int n = wordOffset+numWords;
|
||||
long tot=0, tot8=0;
|
||||
long ones=0, twos=0, fours=0;
|
||||
|
||||
int i;
|
||||
for (i = wordOffset; i <= n - 8; i+=8) {
|
||||
/*** C macro from Hacker's Delight
|
||||
#define CSA(h,l, a,b,c) \
|
||||
{unsigned u = a ^ b; unsigned v = c; \
|
||||
h = (a & b) | (u & v); l = u ^ v;}
|
||||
***/
|
||||
|
||||
long twosA,twosB,foursA,foursB,eights;
|
||||
|
||||
// CSA(twosA, ones, ones, A[i], A[i+1])
|
||||
{
|
||||
long b=A[i], c=A[i+1];
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, A[i+2], A[i+3])
|
||||
{
|
||||
long b=A[i+2], c=A[i+3];
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursA, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
//CSA(twosA, ones, ones, A[i+4], A[i+5])
|
||||
{
|
||||
long b=A[i+4], c=A[i+5];
|
||||
long u=ones^b;
|
||||
twosA=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, A[i+6], A[i+7])
|
||||
{
|
||||
long b=A[i+6], c=A[i+7];
|
||||
long u=ones^b;
|
||||
twosB=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursB, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursB=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
|
||||
//CSA(eights, fours, fours, foursA, foursB)
|
||||
{
|
||||
long u=fours^foursA;
|
||||
eights=(fours&foursA)|(u&foursB);
|
||||
fours=u^foursB;
|
||||
}
|
||||
tot8 += pop(eights);
|
||||
}
|
||||
|
||||
// handle trailing words in a binary-search manner...
|
||||
// derived from the loop above by setting specific elements to 0.
|
||||
// the original method in Hackers Delight used a simple for loop:
|
||||
// for (i = i; i < n; i++) // Add in the last elements
|
||||
// tot = tot + pop(A[i]);
|
||||
|
||||
if (i<=n-4) {
|
||||
long twosA, twosB, foursA, eights;
|
||||
{
|
||||
long b=A[i], c=A[i+1];
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long b=A[i+2], c=A[i+3];
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=4;
|
||||
}
|
||||
|
||||
if (i<=n-2) {
|
||||
long b=A[i], c=A[i+1];
|
||||
long u=ones ^ b;
|
||||
long twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
|
||||
long foursA=twos&twosA;
|
||||
twos=twos^twosA;
|
||||
|
||||
long eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=2;
|
||||
}
|
||||
|
||||
if (i<n) {
|
||||
tot += pop(A[i]);
|
||||
}
|
||||
|
||||
tot += (pop(fours)<<2)
|
||||
+ (pop(twos)<<1)
|
||||
+ pop(ones)
|
||||
+ (tot8<<3);
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
/** Returns the popcount or cardinality of the two sets after an intersection.
|
||||
* Neither array is modified.
|
||||
*/
|
||||
public static long pop_intersect(long A[], long B[], int wordOffset, int numWords) {
|
||||
// generated from pop_array via sed 's/A\[\([^]]*\)\]/\(A[\1] \& B[\1]\)/g'
|
||||
int n = wordOffset+numWords;
|
||||
long tot=0, tot8=0;
|
||||
long ones=0, twos=0, fours=0;
|
||||
|
||||
int i;
|
||||
for (i = wordOffset; i <= n - 8; i+=8) {
|
||||
long twosA,twosB,foursA,foursB,eights;
|
||||
|
||||
// CSA(twosA, ones, ones, (A[i] & B[i]), (A[i+1] & B[i+1]))
|
||||
{
|
||||
long b=(A[i] & B[i]), c=(A[i+1] & B[i+1]);
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, (A[i+2] & B[i+2]), (A[i+3] & B[i+3]))
|
||||
{
|
||||
long b=(A[i+2] & B[i+2]), c=(A[i+3] & B[i+3]);
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursA, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
//CSA(twosA, ones, ones, (A[i+4] & B[i+4]), (A[i+5] & B[i+5]))
|
||||
{
|
||||
long b=(A[i+4] & B[i+4]), c=(A[i+5] & B[i+5]);
|
||||
long u=ones^b;
|
||||
twosA=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, (A[i+6] & B[i+6]), (A[i+7] & B[i+7]))
|
||||
{
|
||||
long b=(A[i+6] & B[i+6]), c=(A[i+7] & B[i+7]);
|
||||
long u=ones^b;
|
||||
twosB=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursB, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursB=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
|
||||
//CSA(eights, fours, fours, foursA, foursB)
|
||||
{
|
||||
long u=fours^foursA;
|
||||
eights=(fours&foursA)|(u&foursB);
|
||||
fours=u^foursB;
|
||||
}
|
||||
tot8 += pop(eights);
|
||||
}
|
||||
|
||||
|
||||
if (i<=n-4) {
|
||||
long twosA, twosB, foursA, eights;
|
||||
{
|
||||
long b=(A[i] & B[i]), c=(A[i+1] & B[i+1]);
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long b=(A[i+2] & B[i+2]), c=(A[i+3] & B[i+3]);
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=4;
|
||||
}
|
||||
|
||||
if (i<=n-2) {
|
||||
long b=(A[i] & B[i]), c=(A[i+1] & B[i+1]);
|
||||
long u=ones ^ b;
|
||||
long twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
|
||||
long foursA=twos&twosA;
|
||||
twos=twos^twosA;
|
||||
|
||||
long eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=2;
|
||||
}
|
||||
|
||||
if (i<n) {
|
||||
tot += pop((A[i] & B[i]));
|
||||
}
|
||||
|
||||
tot += (pop(fours)<<2)
|
||||
+ (pop(twos)<<1)
|
||||
+ pop(ones)
|
||||
+ (tot8<<3);
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
/** Returns the popcount or cardinality of the union of two sets.
|
||||
* Neither array is modified.
|
||||
*/
|
||||
public static long pop_union(long A[], long B[], int wordOffset, int numWords) {
|
||||
// generated from pop_array via sed 's/A\[\([^]]*\)\]/\(A[\1] \| B[\1]\)/g'
|
||||
int n = wordOffset+numWords;
|
||||
long tot=0, tot8=0;
|
||||
long ones=0, twos=0, fours=0;
|
||||
|
||||
int i;
|
||||
for (i = wordOffset; i <= n - 8; i+=8) {
|
||||
/*** C macro from Hacker's Delight
|
||||
#define CSA(h,l, a,b,c) \
|
||||
{unsigned u = a ^ b; unsigned v = c; \
|
||||
h = (a & b) | (u & v); l = u ^ v;}
|
||||
***/
|
||||
|
||||
long twosA,twosB,foursA,foursB,eights;
|
||||
|
||||
// CSA(twosA, ones, ones, (A[i] | B[i]), (A[i+1] | B[i+1]))
|
||||
{
|
||||
long b=(A[i] | B[i]), c=(A[i+1] | B[i+1]);
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, (A[i+2] | B[i+2]), (A[i+3] | B[i+3]))
|
||||
{
|
||||
long b=(A[i+2] | B[i+2]), c=(A[i+3] | B[i+3]);
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursA, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
//CSA(twosA, ones, ones, (A[i+4] | B[i+4]), (A[i+5] | B[i+5]))
|
||||
{
|
||||
long b=(A[i+4] | B[i+4]), c=(A[i+5] | B[i+5]);
|
||||
long u=ones^b;
|
||||
twosA=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, (A[i+6] | B[i+6]), (A[i+7] | B[i+7]))
|
||||
{
|
||||
long b=(A[i+6] | B[i+6]), c=(A[i+7] | B[i+7]);
|
||||
long u=ones^b;
|
||||
twosB=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursB, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursB=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
|
||||
//CSA(eights, fours, fours, foursA, foursB)
|
||||
{
|
||||
long u=fours^foursA;
|
||||
eights=(fours&foursA)|(u&foursB);
|
||||
fours=u^foursB;
|
||||
}
|
||||
tot8 += pop(eights);
|
||||
}
|
||||
|
||||
|
||||
if (i<=n-4) {
|
||||
long twosA, twosB, foursA, eights;
|
||||
{
|
||||
long b=(A[i] | B[i]), c=(A[i+1] | B[i+1]);
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long b=(A[i+2] | B[i+2]), c=(A[i+3] | B[i+3]);
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=4;
|
||||
}
|
||||
|
||||
if (i<=n-2) {
|
||||
long b=(A[i] | B[i]), c=(A[i+1] | B[i+1]);
|
||||
long u=ones ^ b;
|
||||
long twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
|
||||
long foursA=twos&twosA;
|
||||
twos=twos^twosA;
|
||||
|
||||
long eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=2;
|
||||
}
|
||||
|
||||
if (i<n) {
|
||||
tot += pop((A[i] | B[i]));
|
||||
}
|
||||
|
||||
tot += (pop(fours)<<2)
|
||||
+ (pop(twos)<<1)
|
||||
+ pop(ones)
|
||||
+ (tot8<<3);
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
/** Returns the popcount or cardinality of A & ~B
|
||||
* Neither array is modified.
|
||||
*/
|
||||
public static long pop_andnot(long A[], long B[], int wordOffset, int numWords) {
|
||||
// generated from pop_array via sed 's/A\[\([^]]*\)\]/\(A[\1] \& ~B[\1]\)/g'
|
||||
int n = wordOffset+numWords;
|
||||
long tot=0, tot8=0;
|
||||
long ones=0, twos=0, fours=0;
|
||||
|
||||
int i;
|
||||
for (i = wordOffset; i <= n - 8; i+=8) {
|
||||
/*** C macro from Hacker's Delight
|
||||
#define CSA(h,l, a,b,c) \
|
||||
{unsigned u = a ^ b; unsigned v = c; \
|
||||
h = (a & b) | (u & v); l = u ^ v;}
|
||||
***/
|
||||
|
||||
long twosA,twosB,foursA,foursB,eights;
|
||||
|
||||
// CSA(twosA, ones, ones, (A[i] & ~B[i]), (A[i+1] & ~B[i+1]))
|
||||
{
|
||||
long b=(A[i] & ~B[i]), c=(A[i+1] & ~B[i+1]);
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, (A[i+2] & ~B[i+2]), (A[i+3] & ~B[i+3]))
|
||||
{
|
||||
long b=(A[i+2] & ~B[i+2]), c=(A[i+3] & ~B[i+3]);
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursA, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
//CSA(twosA, ones, ones, (A[i+4] & ~B[i+4]), (A[i+5] & ~B[i+5]))
|
||||
{
|
||||
long b=(A[i+4] & ~B[i+4]), c=(A[i+5] & ~B[i+5]);
|
||||
long u=ones^b;
|
||||
twosA=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, (A[i+6] & ~B[i+6]), (A[i+7] & ~B[i+7]))
|
||||
{
|
||||
long b=(A[i+6] & ~B[i+6]), c=(A[i+7] & ~B[i+7]);
|
||||
long u=ones^b;
|
||||
twosB=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursB, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursB=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
|
||||
//CSA(eights, fours, fours, foursA, foursB)
|
||||
{
|
||||
long u=fours^foursA;
|
||||
eights=(fours&foursA)|(u&foursB);
|
||||
fours=u^foursB;
|
||||
}
|
||||
tot8 += pop(eights);
|
||||
}
|
||||
|
||||
|
||||
if (i<=n-4) {
|
||||
long twosA, twosB, foursA, eights;
|
||||
{
|
||||
long b=(A[i] & ~B[i]), c=(A[i+1] & ~B[i+1]);
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long b=(A[i+2] & ~B[i+2]), c=(A[i+3] & ~B[i+3]);
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=4;
|
||||
}
|
||||
|
||||
if (i<=n-2) {
|
||||
long b=(A[i] & ~B[i]), c=(A[i+1] & ~B[i+1]);
|
||||
long u=ones ^ b;
|
||||
long twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
|
||||
long foursA=twos&twosA;
|
||||
twos=twos^twosA;
|
||||
|
||||
long eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=2;
|
||||
}
|
||||
|
||||
if (i<n) {
|
||||
tot += pop((A[i] & ~B[i]));
|
||||
}
|
||||
|
||||
tot += (pop(fours)<<2)
|
||||
+ (pop(twos)<<1)
|
||||
+ pop(ones)
|
||||
+ (tot8<<3);
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
public static long pop_xor(long A[], long B[], int wordOffset, int numWords) {
|
||||
int n = wordOffset+numWords;
|
||||
long tot=0, tot8=0;
|
||||
long ones=0, twos=0, fours=0;
|
||||
|
||||
int i;
|
||||
for (i = wordOffset; i <= n - 8; i+=8) {
|
||||
/*** C macro from Hacker's Delight
|
||||
#define CSA(h,l, a,b,c) \
|
||||
{unsigned u = a ^ b; unsigned v = c; \
|
||||
h = (a & b) | (u & v); l = u ^ v;}
|
||||
***/
|
||||
|
||||
long twosA,twosB,foursA,foursB,eights;
|
||||
|
||||
// CSA(twosA, ones, ones, (A[i] ^ B[i]), (A[i+1] ^ B[i+1]))
|
||||
{
|
||||
long b=(A[i] ^ B[i]), c=(A[i+1] ^ B[i+1]);
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, (A[i+2] ^ B[i+2]), (A[i+3] ^ B[i+3]))
|
||||
{
|
||||
long b=(A[i+2] ^ B[i+2]), c=(A[i+3] ^ B[i+3]);
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursA, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
//CSA(twosA, ones, ones, (A[i+4] ^ B[i+4]), (A[i+5] ^ B[i+5]))
|
||||
{
|
||||
long b=(A[i+4] ^ B[i+4]), c=(A[i+5] ^ B[i+5]);
|
||||
long u=ones^b;
|
||||
twosA=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
// CSA(twosB, ones, ones, (A[i+6] ^ B[i+6]), (A[i+7] ^ B[i+7]))
|
||||
{
|
||||
long b=(A[i+6] ^ B[i+6]), c=(A[i+7] ^ B[i+7]);
|
||||
long u=ones^b;
|
||||
twosB=(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
//CSA(foursB, twos, twos, twosA, twosB)
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursB=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
|
||||
//CSA(eights, fours, fours, foursA, foursB)
|
||||
{
|
||||
long u=fours^foursA;
|
||||
eights=(fours&foursA)|(u&foursB);
|
||||
fours=u^foursB;
|
||||
}
|
||||
tot8 += pop(eights);
|
||||
}
|
||||
|
||||
|
||||
if (i<=n-4) {
|
||||
long twosA, twosB, foursA, eights;
|
||||
{
|
||||
long b=(A[i] ^ B[i]), c=(A[i+1] ^ B[i+1]);
|
||||
long u=ones ^ b;
|
||||
twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long b=(A[i+2] ^ B[i+2]), c=(A[i+3] ^ B[i+3]);
|
||||
long u=ones^b;
|
||||
twosB =(ones&b)|(u&c);
|
||||
ones=u^c;
|
||||
}
|
||||
{
|
||||
long u=twos^twosA;
|
||||
foursA=(twos&twosA)|(u&twosB);
|
||||
twos=u^twosB;
|
||||
}
|
||||
eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=4;
|
||||
}
|
||||
|
||||
if (i<=n-2) {
|
||||
long b=(A[i] ^ B[i]), c=(A[i+1] ^ B[i+1]);
|
||||
long u=ones ^ b;
|
||||
long twosA=(ones & b)|( u & c);
|
||||
ones=u^c;
|
||||
|
||||
long foursA=twos&twosA;
|
||||
twos=twos^twosA;
|
||||
|
||||
long eights=fours&foursA;
|
||||
fours=fours^foursA;
|
||||
|
||||
tot8 += pop(eights);
|
||||
i+=2;
|
||||
}
|
||||
|
||||
if (i<n) {
|
||||
tot += pop((A[i] ^ B[i]));
|
||||
}
|
||||
|
||||
tot += (pop(fours)<<2)
|
||||
+ (pop(twos)<<1)
|
||||
+ pop(ones)
|
||||
+ (tot8<<3);
|
||||
|
||||
return tot;
|
||||
}
|
||||
|
||||
/* python code to generate ntzTable
|
||||
def ntz(val):
|
||||
if val==0: return 8
|
||||
i=0
|
||||
while (val&0x01)==0:
|
||||
i = i+1
|
||||
val >>= 1
|
||||
return i
|
||||
print ','.join([ str(ntz(i)) for i in range(256) ])
|
||||
***/
|
||||
/** table of number of trailing zeros in a byte */
|
||||
public static final byte[] ntzTable = {8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
|
||||
|
||||
|
||||
/** Returns number of trailing zeros in the 64 bit long value. */
|
||||
public static int ntz(long val) {
|
||||
// A full binary search to determine the low byte was slower than
|
||||
// a linear search for nextSetBit(). This is most likely because
|
||||
// the implementation of nextSetBit() shifts bits to the right, increasing
|
||||
// the probability that the first non-zero byte is in the rhs.
|
||||
//
|
||||
// This implementation does a single binary search at the top level only
|
||||
// so that all other bit shifting can be done on ints instead of longs to
|
||||
// remain friendly to 32 bit architectures. In addition, the case of a
|
||||
// non-zero first byte is checked for first because it is the most common
|
||||
// in dense bit arrays.
|
||||
|
||||
int lower = (int)val;
|
||||
int lowByte = lower & 0xff;
|
||||
if (lowByte != 0) return ntzTable[lowByte];
|
||||
|
||||
if (lower!=0) {
|
||||
lowByte = (lower>>>8) & 0xff;
|
||||
if (lowByte != 0) return ntzTable[lowByte] + 8;
|
||||
lowByte = (lower>>>16) & 0xff;
|
||||
if (lowByte != 0) return ntzTable[lowByte] + 16;
|
||||
// no need to mask off low byte for the last byte in the 32 bit word
|
||||
// no need to check for zero on the last byte either.
|
||||
return ntzTable[lower>>>24] + 24;
|
||||
} else {
|
||||
// grab upper 32 bits
|
||||
int upper=(int)(val>>32);
|
||||
lowByte = upper & 0xff;
|
||||
if (lowByte != 0) return ntzTable[lowByte] + 32;
|
||||
lowByte = (upper>>>8) & 0xff;
|
||||
if (lowByte != 0) return ntzTable[lowByte] + 40;
|
||||
lowByte = (upper>>>16) & 0xff;
|
||||
if (lowByte != 0) return ntzTable[lowByte] + 48;
|
||||
// no need to mask off low byte for the last byte in the 32 bit word
|
||||
// no need to check for zero on the last byte either.
|
||||
return ntzTable[upper>>>24] + 56;
|
||||
}
|
||||
}
|
||||
|
||||
/** returns 0 based index of first set bit
|
||||
* (only works for x!=0)
|
||||
* <br/> This is an alternate implementation of ntz()
|
||||
*/
|
||||
public static int ntz2(long x) {
|
||||
int n = 0;
|
||||
int y = (int)x;
|
||||
if (y==0) {n+=32; y = (int)(x>>>32); } // the only 64 bit shift necessary
|
||||
if ((y & 0x0000FFFF) == 0) { n+=16; y>>>=16; }
|
||||
if ((y & 0x000000FF) == 0) { n+=8; y>>>=8; }
|
||||
return (ntzTable[ y & 0xff ]) + n;
|
||||
}
|
||||
|
||||
/** returns 0 based index of first set bit
|
||||
* <br/> This is an alternate implementation of ntz()
|
||||
*/
|
||||
public static int ntz3(long x) {
|
||||
// another implementation taken from Hackers Delight, extended to 64 bits
|
||||
// and converted to Java.
|
||||
// Many 32 bit ntz algorithms are at http://www.hackersdelight.org/HDcode/ntz.cc
|
||||
int n = 1;
|
||||
|
||||
// do the first step as a long, all others as ints.
|
||||
int y = (int)x;
|
||||
if (y==0) {n+=32; y = (int)(x>>>32); }
|
||||
if ((y & 0x0000FFFF) == 0) { n+=16; y>>>=16; }
|
||||
if ((y & 0x000000FF) == 0) { n+=8; y>>>=8; }
|
||||
if ((y & 0x0000000F) == 0) { n+=4; y>>>=4; }
|
||||
if ((y & 0x00000003) == 0) { n+=2; y>>>=2; }
|
||||
return n - (y & 1);
|
||||
}
|
||||
|
||||
|
||||
/** returns true if v is a power of two or zero*/
|
||||
public static boolean isPowerOfTwo(int v) {
|
||||
return ((v & (v-1)) == 0);
|
||||
}
|
||||
|
||||
/** returns true if v is a power of two or zero*/
|
||||
public static boolean isPowerOfTwo(long v) {
|
||||
return ((v & (v-1)) == 0);
|
||||
}
|
||||
|
||||
/** returns the next highest power of two, or the current value if it's already a power of two or zero*/
|
||||
public static int nextHighestPowerOfTwo(int v) {
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
/** returns the next highest power of two, or the current value if it's already a power of two or zero*/
|
||||
public static long nextHighestPowerOfTwo(long v) {
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v |= v >> 32;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
public class BitUtil extends org.apache.lucene.util.BitUtil {
|
||||
// just inherit for backwards-compatibility reasons
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.apache.solr.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.io.Serializable;
|
||||
|
||||
/** An "open" BitSet implementation that allows direct access to the array of words
|
||||
|
@ -71,24 +70,21 @@ Test system: AMD Opteron, 64 bit linux, Sun Java 1.5_06 -server -Xbatch -Xmx64M
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
@deprecated Use {@link org.apache.lucene.util.OpenBitSet} directly.
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
public class OpenBitSet implements Cloneable, Serializable {
|
||||
protected long[] bits;
|
||||
protected int wlen; // number of words (elements) used in the array
|
||||
|
||||
public class OpenBitSet extends org.apache.lucene.util.OpenBitSet implements Cloneable, Serializable {
|
||||
/** Constructs an OpenBitSet large enough to hold numBits.
|
||||
*
|
||||
* @param numBits
|
||||
*/
|
||||
public OpenBitSet(long numBits) {
|
||||
bits = new long[bits2words(numBits)];
|
||||
wlen = bits.length;
|
||||
super(numBits);
|
||||
}
|
||||
|
||||
public OpenBitSet() {
|
||||
this(64);
|
||||
super();
|
||||
}
|
||||
|
||||
/** Constructs an OpenBitSet from an existing long[].
|
||||
|
@ -105,662 +101,8 @@ public class OpenBitSet implements Cloneable, Serializable {
|
|||
*
|
||||
*/
|
||||
public OpenBitSet(long[] bits, int numWords) {
|
||||
this.bits = bits;
|
||||
this.wlen = numWords;
|
||||
super();
|
||||
}
|
||||
|
||||
/** Returns the current capacity in bits (1 greater than the index of the last bit) */
|
||||
public long capacity() { return bits.length << 6; }
|
||||
|
||||
/**
|
||||
* Returns the current capacity of this set. Included for
|
||||
* compatibility. This is *not* equal to {@link #cardinality}
|
||||
*/
|
||||
public long size() {
|
||||
return capacity();
|
||||
}
|
||||
|
||||
/** Returns true if there are no set bits */
|
||||
public boolean isEmpty() { return cardinality()==0; }
|
||||
|
||||
/** Expert: returns the long[] storing the bits */
|
||||
public long[] getBits() { return bits; }
|
||||
|
||||
/** Expert: sets a new long[] to use as the bit storage */
|
||||
public void setBits(long[] bits) { this.bits = bits; }
|
||||
|
||||
/** Expert: gets the number of longs in the array that are in use */
|
||||
public int getNumWords() { return wlen; }
|
||||
|
||||
/** Expert: sets the number of longs in the array that are in use */
|
||||
public void setNumWords(int nWords) { this.wlen=nWords; }
|
||||
|
||||
|
||||
|
||||
/** Returns true or false for the specified bit index. */
|
||||
public boolean get(int index) {
|
||||
int i = index >> 6; // div 64
|
||||
// signed shift will keep a negative index and force an
|
||||
// array-index-out-of-bounds-exception, removing the need for an explicit check.
|
||||
if (i>=bits.length) return false;
|
||||
|
||||
int bit = index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
return (bits[i] & bitmask) != 0;
|
||||
}
|
||||
|
||||
|
||||
/** Returns true or false for the specified bit index.
|
||||
* The index should be less than the OpenBitSet size
|
||||
*/
|
||||
public boolean fastGet(int index) {
|
||||
int i = index >> 6; // div 64
|
||||
// signed shift will keep a negative index and force an
|
||||
// array-index-out-of-bounds-exception, removing the need for an explicit check.
|
||||
int bit = index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
return (bits[i] & bitmask) != 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Returns true or false for the specified bit index
|
||||
* The index should be less than the OpenBitSet size
|
||||
*/
|
||||
public boolean get(long index) {
|
||||
int i = (int)(index >> 6); // div 64
|
||||
if (i>=bits.length) return false;
|
||||
int bit = (int)index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
return (bits[i] & bitmask) != 0;
|
||||
}
|
||||
|
||||
/** Returns true or false for the specified bit index. Allows specifying
|
||||
* an index outside the current size. */
|
||||
public boolean fastGet(long index) {
|
||||
int i = (int)(index >> 6); // div 64
|
||||
int bit = (int)index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
return (bits[i] & bitmask) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
// alternate implementation of get()
|
||||
public boolean get1(int index) {
|
||||
int i = index >> 6; // div 64
|
||||
int bit = index & 0x3f; // mod 64
|
||||
return ((bits[i]>>>bit) & 0x01) != 0;
|
||||
// this does a long shift and a bittest (on x86) vs
|
||||
// a long shift, and a long AND, (the test for zero is prob a no-op)
|
||||
// testing on a P4 indicates this is slower than (bits[i] & bitmask) != 0;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/** returns 1 if the bit is set, 0 if not.
|
||||
* The index should be less than the OpenBitSet size
|
||||
*/
|
||||
public int getBit(int index) {
|
||||
int i = index >> 6; // div 64
|
||||
int bit = index & 0x3f; // mod 64
|
||||
return ((int)(bits[i]>>>bit)) & 0x01;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public boolean get2(int index) {
|
||||
int word = index >> 6; // div 64
|
||||
int bit = index & 0x0000003f; // mod 64
|
||||
return (bits[word] << bit) < 0; // hmmm, this would work if bit order were reversed
|
||||
// we could right shift and check for parity bit, if it was available to us.
|
||||
}
|
||||
*/
|
||||
|
||||
/** sets a bit, expanding the set size if necessary */
|
||||
public void set(long index) {
|
||||
int wordNum = expandingWordNum(index);
|
||||
int bit = (int)index & 0x3f;
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] |= bitmask;
|
||||
}
|
||||
|
||||
|
||||
/** Sets the bit at the specified index.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public void fastSet(int index) {
|
||||
int wordNum = index >> 6; // div 64
|
||||
int bit = index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] |= bitmask;
|
||||
}
|
||||
|
||||
/** Sets the bit at the specified index.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public void fastSet(long index) {
|
||||
int wordNum = (int)(index >> 6);
|
||||
int bit = (int)index & 0x3f;
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] |= bitmask;
|
||||
}
|
||||
|
||||
/** Sets a range of bits, expanding the set size if necessary
|
||||
*
|
||||
* @param startIndex lower index
|
||||
* @param endIndex one-past the last bit to set
|
||||
*/
|
||||
public void set(long startIndex, long endIndex) {
|
||||
if (endIndex <= startIndex) return;
|
||||
|
||||
int startWord = (int)(startIndex>>6);
|
||||
|
||||
// since endIndex is one past the end, this is index of the last
|
||||
// word to be changed.
|
||||
int endWord = expandingWordNum(endIndex-1);
|
||||
|
||||
long startmask = -1L << startIndex;
|
||||
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
|
||||
|
||||
if (startWord == endWord) {
|
||||
bits[startWord] |= (startmask & endmask);
|
||||
return;
|
||||
}
|
||||
|
||||
bits[startWord] |= startmask;
|
||||
Arrays.fill(bits, startWord+1, endWord, -1L);
|
||||
bits[endWord] |= endmask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected int expandingWordNum(long index) {
|
||||
int wordNum = (int)(index >> 6);
|
||||
if (wordNum>=wlen) {
|
||||
ensureCapacity(index+1);
|
||||
wlen = wordNum+1;
|
||||
}
|
||||
return wordNum;
|
||||
}
|
||||
|
||||
|
||||
/** clears a bit.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public void fastClear(int index) {
|
||||
int wordNum = index >> 6;
|
||||
int bit = index & 0x03f;
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] &= ~bitmask;
|
||||
// hmmm, it takes one more instruction to clear than it does to set... any
|
||||
// way to work around this? If there were only 63 bits per word, we could
|
||||
// use a right shift of 10111111...111 in binary to position the 0 in the
|
||||
// correct place (using sign extension).
|
||||
// Could also use Long.rotateRight() or rotateLeft() *if* they were converted
|
||||
// by the JVM into a native instruction.
|
||||
// bits[word] &= Long.rotateLeft(0xfffffffe,bit);
|
||||
}
|
||||
|
||||
/** clears a bit.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public void fastClear(long index) {
|
||||
int wordNum = (int)(index >> 6); // div 64
|
||||
int bit = (int)index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] &= ~bitmask;
|
||||
}
|
||||
|
||||
/** clears a bit, allowing access beyond the current set size without changing the size.*/
|
||||
public void clear(long index) {
|
||||
int wordNum = (int)(index >> 6); // div 64
|
||||
if (wordNum>=wlen) return;
|
||||
int bit = (int)index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] &= ~bitmask;
|
||||
}
|
||||
|
||||
/** Clears a range of bits. Clearing past the end does not change the size of the set.
|
||||
*
|
||||
* @param startIndex lower index
|
||||
* @param endIndex one-past the last bit to clear
|
||||
*/
|
||||
public void clear(long startIndex, long endIndex) {
|
||||
if (endIndex <= startIndex) return;
|
||||
|
||||
int startWord = (int)(startIndex>>6);
|
||||
if (startWord >= wlen) return;
|
||||
|
||||
// since endIndex is one past the end, this is index of the last
|
||||
// word to be changed.
|
||||
int endWord = (int)((endIndex-1)>>6);
|
||||
|
||||
long startmask = -1L << startIndex;
|
||||
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
|
||||
|
||||
// invert masks since we are clearing
|
||||
startmask = ~startmask;
|
||||
endmask = ~endmask;
|
||||
|
||||
if (startWord == endWord) {
|
||||
bits[startWord] &= (startmask | endmask);
|
||||
return;
|
||||
}
|
||||
|
||||
bits[startWord] &= startmask;
|
||||
|
||||
int middle = Math.min(wlen, endWord);
|
||||
Arrays.fill(bits, startWord+1, middle, 0L);
|
||||
if (endWord < wlen) {
|
||||
bits[endWord] &= endmask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Sets a bit and returns the previous value.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public boolean getAndSet(int index) {
|
||||
int wordNum = index >> 6; // div 64
|
||||
int bit = index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
boolean val = (bits[wordNum] & bitmask) != 0;
|
||||
bits[wordNum] |= bitmask;
|
||||
return val;
|
||||
}
|
||||
|
||||
/** Sets a bit and returns the previous value.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public boolean getAndSet(long index) {
|
||||
int wordNum = (int)(index >> 6); // div 64
|
||||
int bit = (int)index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
boolean val = (bits[wordNum] & bitmask) != 0;
|
||||
bits[wordNum] |= bitmask;
|
||||
return val;
|
||||
}
|
||||
|
||||
/** flips a bit.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public void fastFlip(int index) {
|
||||
int wordNum = index >> 6; // div 64
|
||||
int bit = index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] ^= bitmask;
|
||||
}
|
||||
|
||||
/** flips a bit.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public void fastFlip(long index) {
|
||||
int wordNum = (int)(index >> 6); // div 64
|
||||
int bit = (int)index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] ^= bitmask;
|
||||
}
|
||||
|
||||
/** flips a bit, expanding the set size if necessary */
|
||||
public void flip(long index) {
|
||||
int wordNum = expandingWordNum(index);
|
||||
int bit = (int)index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] ^= bitmask;
|
||||
}
|
||||
|
||||
/** flips a bit and returns the resulting bit value.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public boolean flipAndGet(int index) {
|
||||
int wordNum = index >> 6; // div 64
|
||||
int bit = index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] ^= bitmask;
|
||||
return (bits[wordNum] & bitmask) != 0;
|
||||
}
|
||||
|
||||
/** flips a bit and returns the resulting bit value.
|
||||
* The index should be less than the OpenBitSet size.
|
||||
*/
|
||||
public boolean flipAndGet(long index) {
|
||||
int wordNum = (int)(index >> 6); // div 64
|
||||
int bit = (int)index & 0x3f; // mod 64
|
||||
long bitmask = 1L << bit;
|
||||
bits[wordNum] ^= bitmask;
|
||||
return (bits[wordNum] & bitmask) != 0;
|
||||
}
|
||||
|
||||
/** Flips a range of bits, expanding the set size if necessary
|
||||
*
|
||||
* @param startIndex lower index
|
||||
* @param endIndex one-past the last bit to flip
|
||||
*/
|
||||
public void flip(long startIndex, long endIndex) {
|
||||
if (endIndex <= startIndex) return;
|
||||
int oldlen = wlen;
|
||||
int startWord = (int)(startIndex>>6);
|
||||
|
||||
// since endIndex is one past the end, this is index of the last
|
||||
// word to be changed.
|
||||
int endWord = expandingWordNum(endIndex-1);
|
||||
|
||||
/*** Grrr, java shifting wraps around so -1L>>>64 == -1
|
||||
* for that reason, make sure not to use endmask if the bits to flip will
|
||||
* be zero in the last word (redefine endWord to be the last changed...)
|
||||
long startmask = -1L << (startIndex & 0x3f); // example: 11111...111000
|
||||
long endmask = -1L >>> (64-(endIndex & 0x3f)); // example: 00111...111111
|
||||
***/
|
||||
|
||||
long startmask = -1L << startIndex;
|
||||
long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex due to wrap
|
||||
|
||||
if (startWord == endWord) {
|
||||
bits[startWord] ^= (startmask & endmask);
|
||||
return;
|
||||
}
|
||||
|
||||
bits[startWord] ^= startmask;
|
||||
|
||||
for (int i=startWord+1; i<endWord; i++) {
|
||||
bits[i] = ~bits[i];
|
||||
}
|
||||
|
||||
bits[endWord] ^= endmask;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public static int pop(long v0, long v1, long v2, long v3) {
|
||||
// derived from pop_array by setting last four elems to 0.
|
||||
// exchanges one pop() call for 10 elementary operations
|
||||
// saving about 7 instructions... is there a better way?
|
||||
long twosA=v0 & v1;
|
||||
long ones=v0^v1;
|
||||
|
||||
long u2=ones^v2;
|
||||
long twosB =(ones&v2)|(u2&v3);
|
||||
ones=u2^v3;
|
||||
|
||||
long fours=(twosA&twosB);
|
||||
long twos=twosA^twosB;
|
||||
|
||||
return (pop(fours)<<2)
|
||||
+ (pop(twos)<<1)
|
||||
+ pop(ones);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/** @return the number of set bits */
|
||||
public long cardinality() {
|
||||
return BitUtil.pop_array(bits,0,wlen);
|
||||
}
|
||||
|
||||
/** Returns the popcount or cardinality of the intersection of the two sets.
|
||||
* Neither set is modified.
|
||||
*/
|
||||
public static long intersectionCount(OpenBitSet a, OpenBitSet b) {
|
||||
return BitUtil.pop_intersect(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen));
|
||||
}
|
||||
|
||||
/** Returns the popcount or cardinality of the union of the two sets.
|
||||
* Neither set is modified.
|
||||
*/
|
||||
public static long unionCount(OpenBitSet a, OpenBitSet b) {
|
||||
long tot = BitUtil.pop_union(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen));
|
||||
if (a.wlen < b.wlen) {
|
||||
tot += BitUtil.pop_array(b.bits, a.wlen, b.wlen-a.wlen);
|
||||
} else if (a.wlen > b.wlen) {
|
||||
tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen-b.wlen);
|
||||
}
|
||||
return tot;
|
||||
}
|
||||
|
||||
/** Returns the popcount or cardinality of "a and not b"
|
||||
* or "intersection(a, not(b))".
|
||||
* Neither set is modified.
|
||||
*/
|
||||
public static long andNotCount(OpenBitSet a, OpenBitSet b) {
|
||||
long tot = BitUtil.pop_andnot(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen));
|
||||
if (a.wlen > b.wlen) {
|
||||
tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen-b.wlen);
|
||||
}
|
||||
return tot;
|
||||
}
|
||||
|
||||
/** Returns the popcount or cardinality of the exclusive-or of the two sets.
|
||||
* Neither set is modified.
|
||||
*/
|
||||
public static long xorCount(OpenBitSet a, OpenBitSet b) {
|
||||
long tot = BitUtil.pop_xor(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen));
|
||||
if (a.wlen < b.wlen) {
|
||||
tot += BitUtil.pop_array(b.bits, a.wlen, b.wlen-a.wlen);
|
||||
} else if (a.wlen > b.wlen) {
|
||||
tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen-b.wlen);
|
||||
}
|
||||
return tot;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the index of the first set bit starting at the index specified.
|
||||
* -1 is returned if there are no more set bits.
|
||||
*/
|
||||
public int nextSetBit(int index) {
|
||||
int i = index>>6;
|
||||
if (i>=wlen) return -1;
|
||||
int subIndex = index & 0x3f; // index within the word
|
||||
long word = bits[i] >> subIndex; // skip all the bits to the right of index
|
||||
|
||||
if (word!=0) {
|
||||
return (i<<6) + subIndex + BitUtil.ntz(word);
|
||||
}
|
||||
|
||||
while(++i < wlen) {
|
||||
word = bits[i];
|
||||
if (word!=0) return (i<<6) + BitUtil.ntz(word);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Returns the index of the first set bit starting at the index specified.
|
||||
* -1 is returned if there are no more set bits.
|
||||
*/
|
||||
public long nextSetBit(long index) {
|
||||
int i = (int)(index>>>6);
|
||||
if (i>=wlen) return -1;
|
||||
int subIndex = (int)index & 0x3f; // index within the word
|
||||
long word = bits[i] >>> subIndex; // skip all the bits to the right of index
|
||||
|
||||
if (word!=0) {
|
||||
return (((long)i)<<6) + (subIndex + BitUtil.ntz(word));
|
||||
}
|
||||
|
||||
while(++i < wlen) {
|
||||
word = bits[i];
|
||||
if (word!=0) return (((long)i)<<6) + BitUtil.ntz(word);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
OpenBitSet obs = (OpenBitSet)super.clone();
|
||||
obs.bits = obs.bits.clone(); // hopefully an array clone is as fast(er) than arraycopy
|
||||
return obs;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** this = this AND other */
|
||||
public void intersect(OpenBitSet other) {
|
||||
int newLen= Math.min(this.wlen,other.wlen);
|
||||
long[] thisArr = this.bits;
|
||||
long[] otherArr = other.bits;
|
||||
// testing against zero can be more efficient
|
||||
int pos=newLen;
|
||||
while(--pos>=0) {
|
||||
thisArr[pos] &= otherArr[pos];
|
||||
}
|
||||
if (this.wlen > newLen) {
|
||||
// fill zeros from the new shorter length to the old length
|
||||
Arrays.fill(bits,newLen,this.wlen,0);
|
||||
}
|
||||
this.wlen = newLen;
|
||||
}
|
||||
|
||||
/** this = this OR other */
|
||||
public void union(OpenBitSet other) {
|
||||
int newLen = Math.max(wlen,other.wlen);
|
||||
ensureCapacityWords(newLen);
|
||||
|
||||
long[] thisArr = this.bits;
|
||||
long[] otherArr = other.bits;
|
||||
int pos=Math.min(wlen,other.wlen);
|
||||
while(--pos>=0) {
|
||||
thisArr[pos] |= otherArr[pos];
|
||||
}
|
||||
if (this.wlen < newLen) {
|
||||
System.arraycopy(otherArr, this.wlen, thisArr, this.wlen, newLen-this.wlen);
|
||||
}
|
||||
this.wlen = newLen;
|
||||
}
|
||||
|
||||
|
||||
/** Remove all elements set in other. this = this AND_NOT other */
|
||||
public void remove(OpenBitSet other) {
|
||||
int idx = Math.min(wlen,other.wlen);
|
||||
long[] thisArr = this.bits;
|
||||
long[] otherArr = other.bits;
|
||||
while(--idx>=0) {
|
||||
thisArr[idx] &= ~otherArr[idx];
|
||||
}
|
||||
}
|
||||
|
||||
/** this = this XOR other */
|
||||
public void xor(OpenBitSet other) {
|
||||
int newLen = Math.max(wlen,other.wlen);
|
||||
ensureCapacityWords(newLen);
|
||||
|
||||
long[] thisArr = this.bits;
|
||||
long[] otherArr = other.bits;
|
||||
int pos=Math.min(wlen,other.wlen);
|
||||
while(--pos>=0) {
|
||||
thisArr[pos] ^= otherArr[pos];
|
||||
}
|
||||
if (this.wlen < newLen) {
|
||||
System.arraycopy(otherArr, this.wlen, thisArr, this.wlen, newLen-this.wlen);
|
||||
}
|
||||
this.wlen = newLen;
|
||||
}
|
||||
|
||||
|
||||
// some BitSet compatability methods
|
||||
|
||||
//** see {@link intersect} */
|
||||
public void and(OpenBitSet other) {
|
||||
intersect(other);
|
||||
}
|
||||
|
||||
//** see {@link union} */
|
||||
public void or(OpenBitSet other) {
|
||||
union(other);
|
||||
}
|
||||
|
||||
//** see {@link andNot} */
|
||||
public void andNot(OpenBitSet other) {
|
||||
remove(other);
|
||||
}
|
||||
|
||||
/** returns true if the sets have any elements in common */
|
||||
public boolean intersects(OpenBitSet other) {
|
||||
int pos = Math.min(this.wlen, other.wlen);
|
||||
long[] thisArr = this.bits;
|
||||
long[] otherArr = other.bits;
|
||||
while (--pos>=0) {
|
||||
if ((thisArr[pos] & otherArr[pos])!=0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Expand the long[] with the size given as a number of words (64 bit longs).
|
||||
* getNumWords() is unchanged by this call.
|
||||
*/
|
||||
public void ensureCapacityWords(int numWords) {
|
||||
if (bits.length < numWords) {
|
||||
long[] newBits = new long[numWords];
|
||||
System.arraycopy(bits,0,newBits,0,wlen);
|
||||
bits = newBits;
|
||||
}
|
||||
}
|
||||
|
||||
/** Ensure that the long[] is big enough to hold numBits, expanding it if necessary.
|
||||
* getNumWords() is unchanged by this call.
|
||||
*/
|
||||
public void ensureCapacity(long numBits) {
|
||||
ensureCapacityWords(bits2words(numBits));
|
||||
}
|
||||
|
||||
/** Lowers numWords, the number of words in use,
|
||||
* by checking for trailing zero words.
|
||||
*/
|
||||
public void trimTrailingZeros() {
|
||||
int idx = wlen-1;
|
||||
while (idx>=0 && bits[idx]==0) idx--;
|
||||
wlen = idx+1;
|
||||
}
|
||||
|
||||
/** returns the number of 64 bit words it would take to hold numBits */
|
||||
public static int bits2words(long numBits) {
|
||||
return (int)(((numBits-1)>>>6)+1);
|
||||
}
|
||||
|
||||
|
||||
/** returns true if both sets have the same bits set */
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof OpenBitSet)) return false;
|
||||
OpenBitSet a;
|
||||
OpenBitSet b = (OpenBitSet)o;
|
||||
// make a the larger set.
|
||||
if (b.wlen > this.wlen) {
|
||||
a = b; b=this;
|
||||
} else {
|
||||
a=this;
|
||||
}
|
||||
|
||||
// check for any set bits out of the range of b
|
||||
for (int i=a.wlen-1; i>=b.wlen; i--) {
|
||||
if (a.bits[i]!=0) return false;
|
||||
}
|
||||
|
||||
for (int i=b.wlen-1; i>=0; i--) {
|
||||
if (a.bits[i] != b.bits[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public int hashCode() {
|
||||
long h = 0x98761234; // something non-zero for length==0
|
||||
for (int i = bits.length; --i>=0;) {
|
||||
h ^= bits[i];
|
||||
h = (h << 1) | (h >>> 31); // rotate left
|
||||
}
|
||||
return (int)((h>>32) ^ h); // fold leftmost bits into right
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ package org.apache.solr.search;
|
|||
import org.apache.solr.search.BitDocSet;
|
||||
import org.apache.solr.search.HashDocSet;
|
||||
import org.apache.solr.search.DocSet;
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.BitSet;
|
||||
|
|
|
@ -21,8 +21,8 @@ import junit.framework.TestCase;
|
|||
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.solr.util.OpenBitSet;
|
||||
import org.apache.solr.util.BitSetIterator;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSetIterator;
|
||||
|
||||
/**
|
||||
* @version $Id$
|
||||
|
@ -42,9 +42,9 @@ public class TestDocSet extends TestCase {
|
|||
|
||||
public DocSet getHashDocSet(OpenBitSet bs) {
|
||||
int[] docs = new int[(int)bs.cardinality()];
|
||||
BitSetIterator iter = new BitSetIterator(bs);
|
||||
OpenBitSetIterator iter = new OpenBitSetIterator(bs);
|
||||
for (int i=0; i<docs.length; i++) {
|
||||
docs[i] = iter.next();
|
||||
docs[i] = iter.nextDoc();
|
||||
}
|
||||
return new HashDocSet(docs,0,docs.length);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ package org.apache.solr.util;
|
|||
import java.util.Random;
|
||||
import java.util.BitSet;
|
||||
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
import org.apache.lucene.util.OpenBitSetIterator;
|
||||
|
||||
/** Performance tester for OpenBitSet.
|
||||
* Use -Xbatch for more predictable results, and run tests such that the duration
|
||||
* is at least 10 seconds for better accuracy. Close browsers on your system (javascript
|
||||
|
@ -169,8 +172,8 @@ public class BitSetPerf {
|
|||
for (int i=0; i<numSets; i++) {
|
||||
if (impl=="open") {
|
||||
final OpenBitSet set = osets[i];
|
||||
final BitSetIterator iterator = new BitSetIterator(set);
|
||||
for(int next=iterator.next(); next>=0; next=iterator.next()) {
|
||||
final OpenBitSetIterator iterator = new OpenBitSetIterator(set);
|
||||
for(int next=iterator.nextDoc(); next>=0; next=iterator.nextDoc()) {
|
||||
ret += next;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -22,7 +22,10 @@ import junit.framework.TestCase;
|
|||
import java.util.Random;
|
||||
import java.util.BitSet;
|
||||
|
||||
import org.apache.lucene.util.OpenBitSetIterator;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @version $Id$
|
||||
*/
|
||||
public class TestOpenBitSet extends TestCase {
|
||||
|
@ -49,13 +52,16 @@ public class TestOpenBitSet extends TestCase {
|
|||
// test interleaving different BitSetIterator.next()
|
||||
void doIterate(BitSet a, OpenBitSet b) {
|
||||
int aa=-1,bb=-1;
|
||||
BitSetIterator iterator = new BitSetIterator(b);
|
||||
OpenBitSetIterator iterator = new OpenBitSetIterator(b);
|
||||
do {
|
||||
aa = a.nextSetBit(aa+1);
|
||||
if (rand.nextBoolean())
|
||||
bb = iterator.next();
|
||||
else
|
||||
bb = iterator.next(bb+1);
|
||||
if (rand.nextBoolean()) {
|
||||
iterator.next();
|
||||
bb = iterator.doc();
|
||||
} else {
|
||||
iterator.skipTo(bb+1);
|
||||
bb = iterator.doc();
|
||||
}
|
||||
assertEquals(aa,bb);
|
||||
} while (aa>=0);
|
||||
}
|
||||
|
|
|
@ -127,24 +127,4 @@ public class TestUtils extends TestCase {
|
|||
assertEquals( num, NumberUtils.SortableStr2long(sortable, 0, sortable.length() ) );
|
||||
assertEquals( Long.toString(num), NumberUtils.SortableStr2long(sortable) );
|
||||
}
|
||||
|
||||
public void testBitUtils()
|
||||
{
|
||||
long num = 100000;
|
||||
assertEquals( 5, BitUtil.ntz(num) );
|
||||
assertEquals( 5, BitUtil.ntz2(num) );
|
||||
assertEquals( 5, BitUtil.ntz3(num) );
|
||||
|
||||
num = 10;
|
||||
assertEquals( 1, BitUtil.ntz(num) );
|
||||
assertEquals( 1, BitUtil.ntz2(num) );
|
||||
assertEquals( 1, BitUtil.ntz3(num) );
|
||||
|
||||
for (int i=0; i<64; i++) {
|
||||
num = 1L << i;
|
||||
assertEquals( i, BitUtil.ntz(num) );
|
||||
assertEquals( i, BitUtil.ntz2(num) );
|
||||
assertEquals( i, BitUtil.ntz3(num) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue