帆软使用的第三方框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

182 lines
5.0 KiB

package com.fr.third.bitmap.roaringbitmap;
import java.util.Iterator;
/**
* Created by loy on 2021/7/13.
*
* <p>兼容新引擎插件中用到的这个类,后续会删除
*/
@Deprecated
public class RoaringBitmap {
private byte[] value = new byte[1024];
private int length;
public void add(int n) {
checkIndex(n);
ensureCap(n);
int idx0 = n / 8;
int idx1 = n % 8;
if ((value[idx0] & (1 << idx1)) == 0) {
length++;
value[idx0] |= (1 << idx1);
}
}
public void remove(int n) {
checkIndex(n);
if (n >= value.length * 8) {
return;
}
int idx0 = n / 8;
int idx1 = n % 8;
if ((value[idx0] & (1 << idx1)) != 0) {
length--;
value[idx0] &= ~(1 << idx1);
}
}
public boolean contains(int n) {
checkIndex(n);
if (n >= value.length * 8) {
return false;
}
int idx0 = n / 8;
int idx1 = n % 8;
return (value[idx0] & (1 << idx1)) != 0;
}
public void flip(long rangeStart, long rangeEnd) {
int sIdx0 = (int) ((rangeStart + 7) / 8);
int sIdx1 = (int) (rangeStart % 8);
int eIdx0 = (int) (rangeEnd / 8);
int eIdx1 = (int) (rangeEnd % 8);
int lenDiff = 0;
if (sIdx1 > 0) {
byte b = value[sIdx0 - 1];
byte b2 = (byte) (~(b & 0xff) >> sIdx1 << sIdx1 + ((b & 0xff) << (32 - sIdx1) >> (32 - sIdx1)));
value[sIdx0 - 1] = b2;
lenDiff += countInByte(b2) - countInByte(b);
}
for (int i = sIdx0; i < eIdx0; i++) {
value[i] = (byte) ~(value[i]);
lenDiff += countInByte(value[i]) * 2 - 8;
}
if (eIdx1 > 0) {
byte b = value[eIdx0];
byte b2 = (byte) (((b & 0xff) >> eIdx1 << eIdx1) + ~(b & 0xff) << (32 - eIdx1) >> (32 - eIdx1));
value[eIdx0] = b2;
lenDiff += countInByte(b2) - countInByte(b);
}
length += lenDiff;
}
public int getCardinality() {
return length;
}
@Override
public RoaringBitmap clone() {
RoaringBitmap bm = new RoaringBitmap();
bm.length = length;
bm.value = new byte[value.length];
System.arraycopy(value, 0, bm.value, 0, value.length);
return bm;
}
public static RoaringBitmap and(RoaringBitmap bm1, RoaringBitmap bm2) {
int len = Integer.min(bm1.length, bm2.length);
RoaringBitmap bm = new RoaringBitmap();
bm.value = new byte[len];
for (int i = 0; i < len; i++) {
byte b = (byte) (bm1.value[i] & bm2.value[i]);
if (b == 0) {
continue;
}
bm.length += countInByte(b);
}
return bm;
}
public static int andCardinality(RoaringBitmap bm1, RoaringBitmap bm2) {
int len = Integer.min(bm1.length, bm2.length);
int count = 0;
for (int i = 0; i < len; i++) {
byte b = (byte) (bm1.value[i] & bm2.value[i]);
if (b == 0) {
continue;
}
count++;
}
return count;
}
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private int idx0 = 0;
private int idx1 = 0;
@Override
public boolean hasNext() {
while (idx0 < value.length) {
if (value[idx0] != 0) {
byte b = value[idx0];
while (idx1 < 8) {
if ((b & (1 << idx1)) != 0) {
return true;
}
idx1++;
}
}
idx0++;
idx1 = 0;
}
return false;
}
@Override
public Integer next() {
if (hasNext()) {
int v = idx0 * 8 + idx1;
idx1++;
if (idx1 >= 8) {
idx1 = 0;
idx0++;
}
return v;
}
return null;
}
};
}
private void ensureCap(int n) {
int idx = (n + 7) / 8;
int len = value.length;
while (len < idx) {
len <<= 1;
}
if (len > value.length) {
byte[] value2 = new byte[len];
System.arraycopy(value, 0, value2, 0, value.length);
value = value2;
}
}
private void checkIndex(int n) {
if (n < 0) {
throw new ArrayIndexOutOfBoundsException();
}
}
private static int countInByte(byte b) {
int count = 0;
while (b != 0) {
if ((b & 0x01) == 0x01) {
count++;
}
b = (byte) ((b & 0xff) >> 1);
}
return count;
}
}