diff --git a/base-third-project/base-third-step1/pom.xml b/base-third-project/base-third-step1/pom.xml index ce0a9e507..cc9979a75 100644 --- a/base-third-project/base-third-step1/pom.xml +++ b/base-third-project/base-third-step1/pom.xml @@ -37,6 +37,7 @@ ../../fine-lucene ../../fine-lz4 ../../fine-org-dom4j + ../../fine-roaringbitmap ../../fine-sense4 ../../fine-deprecated-utils ../../fine-third-default diff --git a/build.third_step1-jdk11.gradle b/build.third_step1-jdk11.gradle index 2b2790374..3b9eff091 100644 --- a/build.third_step1-jdk11.gradle +++ b/build.third_step1-jdk11.gradle @@ -54,6 +54,7 @@ sourceSets{ "${srcDir}/fine-lucene/src/main/java", "${srcDir}/fine-lz4/src/main/java", "${srcDir}/fine-org-dom4j/src/main/java", + "${srcDir}/fine-roaringbitmap/src/main/java", "${srcDir}/fine-sense4/src/main/java", "${srcDir}/fine-third-default/fine-mail/src/main/java", "${srcDir}/fine-third-default/fine-sun-misc/src/main/java", @@ -113,6 +114,8 @@ def resourceDirs = [ "${srcDir}/fine-lz4/src/main/resources", "${srcDir}/fine-org-dom4j/src/main/java", "${srcDir}/fine-org-dom4j/src/main/resources", + "${srcDir}/fine-roaringbitmap/src/main/java", + "${srcDir}/fine-roaringbitmap/src/main/resources", "${srcDir}/fine-sense4/src/main/java", "${srcDir}/fine-sense4/src/main/resources", "${srcDir}/fine-third-default/fine-mail/src/main/java", diff --git a/build.third_step1.gradle b/build.third_step1.gradle index 984568b17..852b4591b 100644 --- a/build.third_step1.gradle +++ b/build.third_step1.gradle @@ -55,6 +55,7 @@ sourceSets{ "${srcDir}/fine-lucene/src/main/java", "${srcDir}/fine-lz4/src/main/java", "${srcDir}/fine-org-dom4j/src/main/java", + "${srcDir}/fine-roaringbitmap/src/main/java", "${srcDir}/fine-sense4/src/main/java", "${srcDir}/fine-third-default/fine-mail/src/main/java", "${srcDir}/fine-third-default/fine-sun-misc/src/main/java", @@ -156,6 +157,8 @@ task copyFiles(type:Copy,dependsOn:'compileJava'){ with dataContent.call("${srcDir}/fine-lz4/src/main/resources") with dataContent.call("${srcDir}/fine-org-dom4j/src/main/java") with dataContent.call("${srcDir}/fine-org-dom4j/src/main/resources") + with dataContent.call("${srcDir}/fine-roaringbitmap/src/main/java") + with dataContent.call("${srcDir}/fine-roaringbitmap/src/main/resources") with dataContent.call("${srcDir}/fine-sense4/src/main/java") with dataContent.call("${srcDir}/fine-sense4/src/main/resources") with dataContent.call("${srcDir}/fine-third-default/fine-sun-misc/src/main/java") diff --git a/fine-roaringbitmap/pom.xml b/fine-roaringbitmap/pom.xml new file mode 100644 index 000000000..ff94f07eb --- /dev/null +++ b/fine-roaringbitmap/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + + com.fr.third + step1 + ${revision} + ../base-third-project/base-third-step1 + + + fine-roaringbitmap + ${revision} + + + \ No newline at end of file diff --git a/fine-roaringbitmap/src/main/java/com/fr/third/bitmap/roaringbitmap/RoaringBitmap.java b/fine-roaringbitmap/src/main/java/com/fr/third/bitmap/roaringbitmap/RoaringBitmap.java new file mode 100644 index 000000000..146848602 --- /dev/null +++ b/fine-roaringbitmap/src/main/java/com/fr/third/bitmap/roaringbitmap/RoaringBitmap.java @@ -0,0 +1,194 @@ +package com.fr.third.bitmap.roaringbitmap; + +import java.util.Iterator; + +/** + * Created by loy on 2021/7/13. + * + *

兼容新引擎插件中用到的这个类,后续会删除 + */ +@Deprecated +public class RoaringBitmap { + + private byte[] value; + private int length; + private int cap; + + public RoaringBitmap() { + this(8192); + } + + public RoaringBitmap(int cap) { + this.cap = cap; + this.value = new byte[(cap + 7) / 8]; + } + + 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(cap); + 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.value.length, bm2.value.length); + RoaringBitmap bm = new RoaringBitmap(Integer.max(bm1.cap, bm2.cap)); + 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.value[i] = b; + bm.length += countInByte(b); + } + return bm; + } + + public static int andCardinality(RoaringBitmap bm1, RoaringBitmap bm2) { + int len = Integer.min(bm1.value.length, bm2.value.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 += countInByte(b); + } + return count; + } + + public Iterator iterator() { + return new Iterator() { + 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; + } +} +