You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rocketmq.apache.org by yu...@apache.org on 2017/08/01 07:23:22 UTC
[24/50] [abbrv] incubator-rocketmq git commit: [ROCKETMQ-121]Support
message filtering based on SQL92 closes apache/incubator-rocketmq#82
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/9eeb2f7e/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java
----------------------------------------------------------------------
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java
new file mode 100644
index 0000000..915658c
--- /dev/null
+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserConstants.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* Generated By:JavaCC: Do not edit this line. SelectorParserConstants.java */
+package org.apache.rocketmq.filter.parser;
+
+/**
+ * Token literal values and constants.
+ * Generated by org.javacc.parser.OtherFilesGen#start()
+ */
+public interface SelectorParserConstants {
+
+ /**
+ * End of File.
+ */
+ int EOF = 0;
+ /**
+ * RegularExpression Id.
+ */
+ int LINE_COMMENT = 6;
+ /**
+ * RegularExpression Id.
+ */
+ int BLOCK_COMMENT = 7;
+ /**
+ * RegularExpression Id.
+ */
+ int NOT = 8;
+ /**
+ * RegularExpression Id.
+ */
+ int AND = 9;
+ /**
+ * RegularExpression Id.
+ */
+ int OR = 10;
+ /**
+ * RegularExpression Id.
+ */
+ int BETWEEN = 11;
+ /**
+ * RegularExpression Id.
+ */
+ int IN = 12;
+ /**
+ * RegularExpression Id.
+ */
+ int TRUE = 13;
+ /**
+ * RegularExpression Id.
+ */
+ int FALSE = 14;
+ /**
+ * RegularExpression Id.
+ */
+ int NULL = 15;
+ /**
+ * RegularExpression Id.
+ */
+ int IS = 16;
+ /**
+ * RegularExpression Id.
+ */
+ int DECIMAL_LITERAL = 17;
+ /**
+ * RegularExpression Id.
+ */
+ int FLOATING_POINT_LITERAL = 18;
+ /**
+ * RegularExpression Id.
+ */
+ int EXPONENT = 19;
+ /**
+ * RegularExpression Id.
+ */
+ int STRING_LITERAL = 20;
+ /**
+ * RegularExpression Id.
+ */
+ int ID = 21;
+
+ /**
+ * Lexical state.
+ */
+ int DEFAULT = 0;
+
+ /**
+ * Literal token values.
+ */
+ String[] TOKEN_IMAGE = {
+ "<EOF>",
+ "\" \"",
+ "\"\\t\"",
+ "\"\\n\"",
+ "\"\\r\"",
+ "\"\\f\"",
+ "<LINE_COMMENT>",
+ "<BLOCK_COMMENT>",
+ "\"NOT\"",
+ "\"AND\"",
+ "\"OR\"",
+ "\"BETWEEN\"",
+ "\"IN\"",
+ "\"TRUE\"",
+ "\"FALSE\"",
+ "\"NULL\"",
+ "\"IS\"",
+ "<DECIMAL_LITERAL>",
+ "<FLOATING_POINT_LITERAL>",
+ "<EXPONENT>",
+ "<STRING_LITERAL>",
+ "<ID>",
+ "\"=\"",
+ "\"<>\"",
+ "\">\"",
+ "\">=\"",
+ "\"<\"",
+ "\"<=\"",
+ "\"(\"",
+ "\",\"",
+ "\")\"",
+ "\"+\"",
+ "\"-\"",
+ };
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/9eeb2f7e/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java
----------------------------------------------------------------------
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java
new file mode 100644
index 0000000..354f5ba
--- /dev/null
+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SelectorParserTokenManager.java
@@ -0,0 +1,919 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* Generated By:JavaCC: Do not edit this line. SelectorParserTokenManager.java */
+package org.apache.rocketmq.filter.parser;
+
+/**
+ * Token Manager.
+ */
+public class SelectorParserTokenManager implements SelectorParserConstants {
+
+ /**
+ * Debug output.
+ */
+ public java.io.PrintStream debugStream = System.out;
+
+ /**
+ * Set debug output.
+ */
+ public void setDebugStream(java.io.PrintStream ds) {
+ debugStream = ds;
+ }
+
+ private int jjStopAtPos(int pos, int kind) {
+ jjmatchedKind = kind;
+ jjmatchedPos = pos;
+ return pos + 1;
+ }
+
+ private int jjMoveStringLiteralDfa0_0() {
+ switch (curChar) {
+ case 9:
+ jjmatchedKind = 2;
+ return jjMoveNfa_0(5, 0);
+ case 10:
+ jjmatchedKind = 3;
+ return jjMoveNfa_0(5, 0);
+ case 12:
+ jjmatchedKind = 5;
+ return jjMoveNfa_0(5, 0);
+ case 13:
+ jjmatchedKind = 4;
+ return jjMoveNfa_0(5, 0);
+ case 32:
+ jjmatchedKind = 1;
+ return jjMoveNfa_0(5, 0);
+ case 40:
+ jjmatchedKind = 28;
+ return jjMoveNfa_0(5, 0);
+ case 41:
+ jjmatchedKind = 30;
+ return jjMoveNfa_0(5, 0);
+ case 43:
+ jjmatchedKind = 31;
+ return jjMoveNfa_0(5, 0);
+ case 44:
+ jjmatchedKind = 29;
+ return jjMoveNfa_0(5, 0);
+ case 45:
+ jjmatchedKind = 32;
+ return jjMoveNfa_0(5, 0);
+ case 60:
+ jjmatchedKind = 26;
+ return jjMoveStringLiteralDfa1_0(0x8800000L);
+ case 61:
+ jjmatchedKind = 22;
+ return jjMoveNfa_0(5, 0);
+ case 62:
+ jjmatchedKind = 24;
+ return jjMoveStringLiteralDfa1_0(0x2000000L);
+ case 65:
+ return jjMoveStringLiteralDfa1_0(0x200L);
+ case 66:
+ return jjMoveStringLiteralDfa1_0(0x800L);
+ case 70:
+ return jjMoveStringLiteralDfa1_0(0x4000L);
+ case 73:
+ return jjMoveStringLiteralDfa1_0(0x11000L);
+ case 78:
+ return jjMoveStringLiteralDfa1_0(0x8100L);
+ case 79:
+ return jjMoveStringLiteralDfa1_0(0x400L);
+ case 84:
+ return jjMoveStringLiteralDfa1_0(0x2000L);
+ case 97:
+ return jjMoveStringLiteralDfa1_0(0x200L);
+ case 98:
+ return jjMoveStringLiteralDfa1_0(0x800L);
+ case 102:
+ return jjMoveStringLiteralDfa1_0(0x4000L);
+ case 105:
+ return jjMoveStringLiteralDfa1_0(0x11000L);
+ case 110:
+ return jjMoveStringLiteralDfa1_0(0x8100L);
+ case 111:
+ return jjMoveStringLiteralDfa1_0(0x400L);
+ case 116:
+ return jjMoveStringLiteralDfa1_0(0x2000L);
+ default:
+ return jjMoveNfa_0(5, 0);
+ }
+ }
+
+ private int jjMoveStringLiteralDfa1_0(long active0) {
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ return jjMoveNfa_0(5, 0);
+ }
+ switch (curChar) {
+ case 61:
+ if ((active0 & 0x2000000L) != 0L) {
+ jjmatchedKind = 25;
+ jjmatchedPos = 1;
+ } else if ((active0 & 0x8000000L) != 0L) {
+ jjmatchedKind = 27;
+ jjmatchedPos = 1;
+ }
+ break;
+ case 62:
+ if ((active0 & 0x800000L) != 0L) {
+ jjmatchedKind = 23;
+ jjmatchedPos = 1;
+ }
+ break;
+ case 65:
+ return jjMoveStringLiteralDfa2_0(active0, 0x4000L);
+ case 69:
+ return jjMoveStringLiteralDfa2_0(active0, 0x800L);
+ case 78:
+ if ((active0 & 0x1000L) != 0L) {
+ jjmatchedKind = 12;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x200L);
+ case 79:
+ return jjMoveStringLiteralDfa2_0(active0, 0x100L);
+ case 82:
+ if ((active0 & 0x400L) != 0L) {
+ jjmatchedKind = 10;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x2000L);
+ case 83:
+ if ((active0 & 0x10000L) != 0L) {
+ jjmatchedKind = 16;
+ jjmatchedPos = 1;
+ }
+ break;
+ case 85:
+ return jjMoveStringLiteralDfa2_0(active0, 0x8000L);
+ case 97:
+ return jjMoveStringLiteralDfa2_0(active0, 0x4000L);
+ case 101:
+ return jjMoveStringLiteralDfa2_0(active0, 0x800L);
+ case 110:
+ if ((active0 & 0x1000L) != 0L) {
+ jjmatchedKind = 12;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x200L);
+ case 111:
+ return jjMoveStringLiteralDfa2_0(active0, 0x100L);
+ case 114:
+ if ((active0 & 0x400L) != 0L) {
+ jjmatchedKind = 10;
+ jjmatchedPos = 1;
+ }
+ return jjMoveStringLiteralDfa2_0(active0, 0x2000L);
+ case 115:
+ if ((active0 & 0x10000L) != 0L) {
+ jjmatchedKind = 16;
+ jjmatchedPos = 1;
+ }
+ break;
+ case 117:
+ return jjMoveStringLiteralDfa2_0(active0, 0x8000L);
+ default:
+ break;
+ }
+ return jjMoveNfa_0(5, 1);
+ }
+
+ private int jjMoveStringLiteralDfa2_0(long old0, long active0) {
+ if (((active0 &= old0)) == 0L)
+ return jjMoveNfa_0(5, 1);
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ return jjMoveNfa_0(5, 1);
+ }
+ switch (curChar) {
+ case 68:
+ if ((active0 & 0x200L) != 0L) {
+ jjmatchedKind = 9;
+ jjmatchedPos = 2;
+ }
+ break;
+ case 76:
+ return jjMoveStringLiteralDfa3_0(active0, 0xc000L);
+ case 84:
+ if ((active0 & 0x100L) != 0L) {
+ jjmatchedKind = 8;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x800L);
+ case 85:
+ return jjMoveStringLiteralDfa3_0(active0, 0x2000L);
+ case 100:
+ if ((active0 & 0x200L) != 0L) {
+ jjmatchedKind = 9;
+ jjmatchedPos = 2;
+ }
+ break;
+ case 108:
+ return jjMoveStringLiteralDfa3_0(active0, 0xc000L);
+ case 116:
+ if ((active0 & 0x100L) != 0L) {
+ jjmatchedKind = 8;
+ jjmatchedPos = 2;
+ }
+ return jjMoveStringLiteralDfa3_0(active0, 0x800L);
+ case 117:
+ return jjMoveStringLiteralDfa3_0(active0, 0x2000L);
+ default:
+ break;
+ }
+ return jjMoveNfa_0(5, 2);
+ }
+
+ private int jjMoveStringLiteralDfa3_0(long old0, long active0) {
+ if (((active0 &= old0)) == 0L)
+ return jjMoveNfa_0(5, 2);
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ return jjMoveNfa_0(5, 2);
+ }
+ switch (curChar) {
+ case 69:
+ if ((active0 & 0x2000L) != 0L) {
+ jjmatchedKind = 13;
+ jjmatchedPos = 3;
+ }
+ break;
+ case 76:
+ if ((active0 & 0x8000L) != 0L) {
+ jjmatchedKind = 15;
+ jjmatchedPos = 3;
+ }
+ break;
+ case 83:
+ return jjMoveStringLiteralDfa4_0(active0, 0x4000L);
+ case 87:
+ return jjMoveStringLiteralDfa4_0(active0, 0x800L);
+ case 101:
+ if ((active0 & 0x2000L) != 0L) {
+ jjmatchedKind = 13;
+ jjmatchedPos = 3;
+ }
+ break;
+ case 108:
+ if ((active0 & 0x8000L) != 0L) {
+ jjmatchedKind = 15;
+ jjmatchedPos = 3;
+ }
+ break;
+ case 115:
+ return jjMoveStringLiteralDfa4_0(active0, 0x4000L);
+ case 119:
+ return jjMoveStringLiteralDfa4_0(active0, 0x800L);
+ default:
+ break;
+ }
+ return jjMoveNfa_0(5, 3);
+ }
+
+ private int jjMoveStringLiteralDfa4_0(long old0, long active0) {
+ if (((active0 &= old0)) == 0L)
+ return jjMoveNfa_0(5, 3);
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ return jjMoveNfa_0(5, 3);
+ }
+ switch (curChar) {
+ case 69:
+ if ((active0 & 0x4000L) != 0L) {
+ jjmatchedKind = 14;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x800L);
+ case 101:
+ if ((active0 & 0x4000L) != 0L) {
+ jjmatchedKind = 14;
+ jjmatchedPos = 4;
+ }
+ return jjMoveStringLiteralDfa5_0(active0, 0x800L);
+ default:
+ break;
+ }
+ return jjMoveNfa_0(5, 4);
+ }
+
+ private int jjMoveStringLiteralDfa5_0(long old0, long active0) {
+ if (((active0 &= old0)) == 0L)
+ return jjMoveNfa_0(5, 4);
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ return jjMoveNfa_0(5, 4);
+ }
+ switch (curChar) {
+ case 69:
+ return jjMoveStringLiteralDfa6_0(active0, 0x800L);
+ case 101:
+ return jjMoveStringLiteralDfa6_0(active0, 0x800L);
+ default:
+ break;
+ }
+ return jjMoveNfa_0(5, 5);
+ }
+
+ private int jjMoveStringLiteralDfa6_0(long old0, long active0) {
+ if (((active0 &= old0)) == 0L)
+ return jjMoveNfa_0(5, 5);
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ return jjMoveNfa_0(5, 5);
+ }
+ switch (curChar) {
+ case 78:
+ if ((active0 & 0x800L) != 0L) {
+ jjmatchedKind = 11;
+ jjmatchedPos = 6;
+ }
+ break;
+ case 110:
+ if ((active0 & 0x800L) != 0L) {
+ jjmatchedKind = 11;
+ jjmatchedPos = 6;
+ }
+ break;
+ default:
+ break;
+ }
+ return jjMoveNfa_0(5, 6);
+ }
+
+ static final long[] JJ_BIT_VEC_0 = {
+ 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL
+ };
+ static final long[] JJ_BIT_VEC_2 = {
+ 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL
+ };
+
+ private int jjMoveNfa_0(int startState, int curPos) {
+ int strKind = jjmatchedKind;
+ int strPos = jjmatchedPos;
+ int seenUpto;
+ inputStream.backup(seenUpto = curPos + 1);
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ throw new Error("Internal Error");
+ }
+ curPos = 0;
+ int startsAt = 0;
+ jjnewStateCnt = 40;
+ int i = 1;
+ jjstateSet[0] = startState;
+ int kind = 0x7fffffff;
+ for (;;) {
+ if (++jjround == 0x7fffffff)
+ ReInitRounds();
+ if (curChar < 64) {
+ long l = 1L << curChar;
+ do {
+ switch (jjstateSet[--i]) {
+ case 5:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddStates(0, 3);
+ else if (curChar == 36) {
+ if (kind > 21)
+ kind = 21;
+ jjCheckNAdd(28);
+ } else if (curChar == 39)
+ jjCheckNAddStates(4, 6);
+ else if (curChar == 46)
+ jjCheckNAdd(18);
+ else if (curChar == 47)
+ jjstateSet[jjnewStateCnt++] = 6;
+ else if (curChar == 45)
+ jjstateSet[jjnewStateCnt++] = 0;
+ if ((0x3fe000000000000L & l) != 0L) {
+ if (kind > 17)
+ kind = 17;
+ jjCheckNAddTwoStates(15, 16);
+ } else if (curChar == 48) {
+ if (kind > 17)
+ kind = 17;
+ }
+ break;
+ case 0:
+ if (curChar == 45)
+ jjCheckNAddStates(7, 9);
+ break;
+ case 1:
+ if ((0xffffffffffffdbffL & l) != 0L)
+ jjCheckNAddStates(7, 9);
+ break;
+ case 2:
+ if ((0x2400L & l) != 0L && kind > 6)
+ kind = 6;
+ break;
+ case 3:
+ if (curChar == 10 && kind > 6)
+ kind = 6;
+ break;
+ case 4:
+ if (curChar == 13)
+ jjstateSet[jjnewStateCnt++] = 3;
+ break;
+ case 6:
+ if (curChar == 42)
+ jjCheckNAddTwoStates(7, 8);
+ break;
+ case 7:
+ if ((0xfffffbffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(7, 8);
+ break;
+ case 8:
+ if (curChar == 42)
+ jjCheckNAddStates(10, 12);
+ break;
+ case 9:
+ if ((0xffff7bffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(10, 8);
+ break;
+ case 10:
+ if ((0xfffffbffffffffffL & l) != 0L)
+ jjCheckNAddTwoStates(10, 8);
+ break;
+ case 11:
+ if (curChar == 47 && kind > 7)
+ kind = 7;
+ break;
+ case 12:
+ if (curChar == 47)
+ jjstateSet[jjnewStateCnt++] = 6;
+ break;
+ case 13:
+ if (curChar == 48 && kind > 17)
+ kind = 17;
+ break;
+ case 14:
+ if ((0x3fe000000000000L & l) == 0L)
+ break;
+ if (kind > 17)
+ kind = 17;
+ jjCheckNAddTwoStates(15, 16);
+ break;
+ case 15:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 17)
+ kind = 17;
+ jjCheckNAddTwoStates(15, 16);
+ break;
+ case 17:
+ if (curChar == 46)
+ jjCheckNAdd(18);
+ break;
+ case 18:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 18)
+ kind = 18;
+ jjCheckNAddTwoStates(18, 19);
+ break;
+ case 20:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(21);
+ break;
+ case 21:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 18)
+ kind = 18;
+ jjCheckNAdd(21);
+ break;
+ case 22:
+ case 23:
+ if (curChar == 39)
+ jjCheckNAddStates(4, 6);
+ break;
+ case 24:
+ if (curChar == 39)
+ jjstateSet[jjnewStateCnt++] = 23;
+ break;
+ case 25:
+ if ((0xffffff7fffffffffL & l) != 0L)
+ jjCheckNAddStates(4, 6);
+ break;
+ case 26:
+ if (curChar == 39 && kind > 20)
+ kind = 20;
+ break;
+ case 27:
+ if (curChar != 36)
+ break;
+ if (kind > 21)
+ kind = 21;
+ jjCheckNAdd(28);
+ break;
+ case 28:
+ if ((0x3ff001000000000L & l) == 0L)
+ break;
+ if (kind > 21)
+ kind = 21;
+ jjCheckNAdd(28);
+ break;
+ case 29:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddStates(0, 3);
+ break;
+ case 30:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(30, 31);
+ break;
+ case 31:
+ if (curChar != 46)
+ break;
+ if (kind > 18)
+ kind = 18;
+ jjCheckNAddTwoStates(32, 33);
+ break;
+ case 32:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 18)
+ kind = 18;
+ jjCheckNAddTwoStates(32, 33);
+ break;
+ case 34:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(35);
+ break;
+ case 35:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 18)
+ kind = 18;
+ jjCheckNAdd(35);
+ break;
+ case 36:
+ if ((0x3ff000000000000L & l) != 0L)
+ jjCheckNAddTwoStates(36, 37);
+ break;
+ case 38:
+ if ((0x280000000000L & l) != 0L)
+ jjCheckNAdd(39);
+ break;
+ case 39:
+ if ((0x3ff000000000000L & l) == 0L)
+ break;
+ if (kind > 18)
+ kind = 18;
+ jjCheckNAdd(39);
+ break;
+ default:
+ break;
+ }
+ } while (i != startsAt);
+ } else if (curChar < 128) {
+ long l = 1L << (curChar & 077);
+ do {
+ switch (jjstateSet[--i]) {
+ case 5:
+ case 28:
+ if ((0x7fffffe87fffffeL & l) == 0L)
+ break;
+ if (kind > 21)
+ kind = 21;
+ jjCheckNAdd(28);
+ break;
+ case 1:
+ jjAddStates(7, 9);
+ break;
+ case 7:
+ jjCheckNAddTwoStates(7, 8);
+ break;
+ case 9:
+ case 10:
+ jjCheckNAddTwoStates(10, 8);
+ break;
+ case 16:
+ if ((0x100000001000L & l) != 0L && kind > 17)
+ kind = 17;
+ break;
+ case 19:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(13, 14);
+ break;
+ case 25:
+ jjAddStates(4, 6);
+ break;
+ case 33:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(15, 16);
+ break;
+ case 37:
+ if ((0x2000000020L & l) != 0L)
+ jjAddStates(17, 18);
+ break;
+ default:
+ break;
+ }
+ } while (i != startsAt);
+ } else {
+ int hiByte = (int) (curChar >> 8);
+ int i1 = hiByte >> 6;
+ long l1 = 1L << (hiByte & 077);
+ int i2 = (curChar & 0xff) >> 6;
+ long l2 = 1L << (curChar & 077);
+ do {
+ switch (jjstateSet[--i]) {
+ case 1:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjAddStates(7, 9);
+ break;
+ case 7:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjCheckNAddTwoStates(7, 8);
+ break;
+ case 9:
+ case 10:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjCheckNAddTwoStates(10, 8);
+ break;
+ case 25:
+ if (jjCanMove_0(hiByte, i1, i2, l1, l2))
+ jjAddStates(4, 6);
+ break;
+ default:
+ break;
+ }
+ } while (i != startsAt);
+ }
+ if (kind != 0x7fffffff) {
+ jjmatchedKind = kind;
+ jjmatchedPos = curPos;
+ kind = 0x7fffffff;
+ }
+ ++curPos;
+ if ((i = jjnewStateCnt) == (startsAt = 40 - (jjnewStateCnt = startsAt)))
+ break;
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ break;
+ }
+ }
+ if (jjmatchedPos > strPos)
+ return curPos;
+
+ int toRet = Math.max(curPos, seenUpto);
+
+ if (curPos < toRet)
+ for (i = toRet - Math.min(curPos, seenUpto); i-- > 0; )
+ try {
+ curChar = inputStream.readChar();
+ } catch (java.io.IOException e) {
+ throw new Error("Internal Error : Please send a bug report.");
+ }
+
+ if (jjmatchedPos < strPos) {
+ jjmatchedKind = strKind;
+ jjmatchedPos = strPos;
+ } else if (jjmatchedPos == strPos && jjmatchedKind > strKind)
+ jjmatchedKind = strKind;
+
+ return toRet;
+ }
+
+ static final int[] JJ_NEXT_STATES = {
+ 30, 31, 36, 37, 24, 25, 26, 1, 2, 4, 8, 9, 11, 20, 21, 34,
+ 35, 38, 39,
+ };
+
+ private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) {
+ switch (hiByte) {
+ case 0:
+ return (JJ_BIT_VEC_2[i2] & l2) != 0L;
+ default:
+ if ((JJ_BIT_VEC_0[i1] & l1) != 0L)
+ return true;
+ return false;
+ }
+ }
+
+ /**
+ * Token literal values.
+ */
+ public static final String[] JJ_STR_LITERAL_IMAGES = {
+ "", null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, "\75", "\74\76", "\76",
+ "\76\75", "\74", "\74\75", "\50", "\54", "\51", "\53", "\55"};
+
+ /**
+ * Lexer state names.
+ */
+ public static final String[] LEX_STATE_NAMES = {
+ "DEFAULT",
+ };
+ static final long[] JJ_TO_TOKEN = {
+ 0x1fff7ff01L,
+ };
+ static final long[] JJ_TO_SKIP = {
+ 0xfeL,
+ };
+ static final long[] JJ_TO_SPECIAL = {
+ 0x3eL,
+ };
+ protected SimpleCharStream inputStream;
+ private final int[] jjrounds = new int[40];
+ private final int[] jjstateSet = new int[80];
+ protected char curChar;
+
+ /**
+ * Constructor.
+ */
+ public SelectorParserTokenManager(SimpleCharStream stream) {
+ if (SimpleCharStream.STATIC_FLAG)
+ throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
+ inputStream = stream;
+ }
+
+ /**
+ * Constructor.
+ */
+ public SelectorParserTokenManager(SimpleCharStream stream, int lexState) {
+ this(stream);
+ SwitchTo(lexState);
+ }
+
+ /**
+ * Reinitialise parser.
+ */
+ public void ReInit(SimpleCharStream stream) {
+ jjmatchedPos = jjnewStateCnt = 0;
+ curLexState = defaultLexState;
+ inputStream = stream;
+ ReInitRounds();
+ }
+
+ private void ReInitRounds() {
+ int i;
+ jjround = 0x80000001;
+ for (i = 40; i-- > 0; )
+ jjrounds[i] = 0x80000000;
+ }
+
+ /**
+ * Reinitialise parser.
+ */
+ public void ReInit(SimpleCharStream stream, int lexState) {
+ ReInit(stream);
+ SwitchTo(lexState);
+ }
+
+ /**
+ * Switch to specified lex state.
+ */
+ public void SwitchTo(int lexState) {
+ if (lexState >= 1 || lexState < 0)
+ throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.",
+ TokenMgrError.INVALID_LEXICAL_STATE);
+ else
+ curLexState = lexState;
+ }
+
+ protected Token jjFillToken() {
+ final Token t;
+ final String curTokenImage;
+ final int beginLine;
+ final int endLine;
+ final int beginColumn;
+ final int endColumn;
+ String im = JJ_STR_LITERAL_IMAGES[jjmatchedKind];
+ curTokenImage = (im == null) ? inputStream.GetImage() : im;
+ beginLine = inputStream.getBeginLine();
+ beginColumn = inputStream.getBeginColumn();
+ endLine = inputStream.getEndLine();
+ endColumn = inputStream.getEndColumn();
+ t = Token.newToken(jjmatchedKind, curTokenImage);
+
+ t.beginLine = beginLine;
+ t.endLine = endLine;
+ t.beginColumn = beginColumn;
+ t.endColumn = endColumn;
+
+ return t;
+ }
+
+ int curLexState = 0;
+ int defaultLexState = 0;
+ int jjnewStateCnt;
+ int jjround;
+ int jjmatchedPos;
+ int jjmatchedKind;
+
+ /**
+ * Get the next Token.
+ */
+ public Token getNextToken() {
+ Token specialToken = null;
+ Token matchedToken;
+ int curPos = 0;
+
+ EOFLoop:
+ for (;;) {
+ try {
+ curChar = inputStream.BeginToken();
+ } catch (java.io.IOException e) {
+ jjmatchedKind = 0;
+ matchedToken = jjFillToken();
+ matchedToken.specialToken = specialToken;
+ return matchedToken;
+ }
+
+ jjmatchedKind = 0x7fffffff;
+ jjmatchedPos = 0;
+ curPos = jjMoveStringLiteralDfa0_0();
+ if (jjmatchedKind != 0x7fffffff) {
+ if (jjmatchedPos + 1 < curPos)
+ inputStream.backup(curPos - jjmatchedPos - 1);
+ if ((JJ_TO_TOKEN[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) {
+ matchedToken = jjFillToken();
+ matchedToken.specialToken = specialToken;
+ return matchedToken;
+ } else {
+ if ((JJ_TO_SPECIAL[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) {
+ matchedToken = jjFillToken();
+ if (specialToken == null)
+ specialToken = matchedToken;
+ else {
+ matchedToken.specialToken = specialToken;
+ specialToken = specialToken.next = matchedToken;
+ }
+ }
+ continue EOFLoop;
+ }
+ }
+ int errorLine = inputStream.getEndLine();
+ int errorColumn = inputStream.getEndColumn();
+ String errorAfter = null;
+ boolean eofSeen = false;
+ try {
+ inputStream.readChar();
+ inputStream.backup(1);
+ } catch (java.io.IOException e1) {
+ eofSeen = true;
+ errorAfter = curPos <= 1 ? "" : inputStream.GetImage();
+ if (curChar == '\n' || curChar == '\r') {
+ errorLine++;
+ errorColumn = 0;
+ } else
+ errorColumn++;
+ }
+ if (!eofSeen) {
+ inputStream.backup(1);
+ errorAfter = curPos <= 1 ? "" : inputStream.GetImage();
+ }
+ throw new TokenMgrError(eofSeen, curLexState, errorLine, errorColumn, errorAfter, curChar,
+ TokenMgrError.LEXICAL_ERROR);
+ }
+ }
+
+ private void jjCheckNAdd(int state) {
+ if (jjrounds[state] != jjround) {
+ jjstateSet[jjnewStateCnt++] = state;
+ jjrounds[state] = jjround;
+ }
+ }
+
+ private void jjAddStates(int start, int end) {
+ do {
+ jjstateSet[jjnewStateCnt++] = JJ_NEXT_STATES[start];
+ } while (start++ != end);
+ }
+
+ private void jjCheckNAddTwoStates(int state1, int state2) {
+ jjCheckNAdd(state1);
+ jjCheckNAdd(state2);
+ }
+
+ private void jjCheckNAddStates(int start, int end) {
+ do {
+ jjCheckNAdd(JJ_NEXT_STATES[start]);
+ } while (start++ != end);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/9eeb2f7e/filter/src/main/java/org/apache/rocketmq/filter/parser/SimpleCharStream.java
----------------------------------------------------------------------
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/SimpleCharStream.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/SimpleCharStream.java
new file mode 100644
index 0000000..94a54b4
--- /dev/null
+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/SimpleCharStream.java
@@ -0,0 +1,502 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 5.0 */
+/* JavaCCOptions:STATIC=false,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package org.apache.rocketmq.filter.parser;
+
+/**
+ * An implementation of interface CharStream, where the stream is assumed to
+ * contain only ASCII characters (without unicode processing).
+ */
+
+public class SimpleCharStream {
+ /**
+ * Whether parser is static.
+ */
+ public static final boolean STATIC_FLAG = false;
+ int bufsize;
+ int available;
+ int tokenBegin;
+ /**
+ * Position in buffer.
+ */
+ public int bufpos = -1;
+ protected int bufline[];
+ protected int bufcolumn[];
+
+ protected int column = 0;
+ protected int line = 1;
+
+ protected boolean prevCharIsCR = false;
+ protected boolean prevCharIsLF = false;
+
+ protected java.io.Reader inputStream;
+
+ protected char[] buffer;
+ protected int maxNextCharInd = 0;
+ protected int inBuf = 0;
+ protected int tabSize = 8;
+
+ protected void setTabSize(int i) {
+ tabSize = i;
+ }
+
+ protected int getTabSize(int i) {
+ return tabSize;
+ }
+
+ protected void ExpandBuff(boolean wrapAround) {
+ char[] newbuffer = new char[bufsize + 2048];
+ int newbufline[] = new int[bufsize + 2048];
+ int newbufcolumn[] = new int[bufsize + 2048];
+
+ try {
+ if (wrapAround) {
+ System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ System.arraycopy(buffer, 0, newbuffer, bufsize - tokenBegin, bufpos);
+ buffer = newbuffer;
+
+ System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
+ bufline = newbufline;
+
+ System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
+ bufcolumn = newbufcolumn;
+
+ maxNextCharInd = bufpos += bufsize - tokenBegin;
+ } else {
+ System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
+ buffer = newbuffer;
+
+ System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
+ bufline = newbufline;
+
+ System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
+ bufcolumn = newbufcolumn;
+
+ maxNextCharInd = bufpos -= tokenBegin;
+ }
+ } catch (Throwable t) {
+ throw new Error(t.getMessage());
+ }
+
+ bufsize += 2048;
+ available = bufsize;
+ tokenBegin = 0;
+ }
+
+ protected void FillBuff() throws java.io.IOException {
+ if (maxNextCharInd == available) {
+ if (available == bufsize) {
+ if (tokenBegin > 2048) {
+ bufpos = maxNextCharInd = 0;
+ available = tokenBegin;
+ } else if (tokenBegin < 0)
+ bufpos = maxNextCharInd = 0;
+ else
+ ExpandBuff(false);
+ } else if (available > tokenBegin)
+ available = bufsize;
+ else if ((tokenBegin - available) < 2048)
+ ExpandBuff(true);
+ else
+ available = tokenBegin;
+ }
+
+ int i;
+ try {
+ if ((i = inputStream.read(buffer, maxNextCharInd, available - maxNextCharInd)) == -1) {
+ inputStream.close();
+ throw new java.io.IOException();
+ } else
+ maxNextCharInd += i;
+ return;
+ } catch (java.io.IOException e) {
+ --bufpos;
+ backup(0);
+ if (tokenBegin == -1)
+ tokenBegin = bufpos;
+ throw e;
+ }
+ }
+
+ /**
+ * Start.
+ */
+ public char BeginToken() throws java.io.IOException {
+ tokenBegin = -1;
+ char c = readChar();
+ tokenBegin = bufpos;
+
+ return c;
+ }
+
+ protected void UpdateLineColumn(char c) {
+ column++;
+
+ if (prevCharIsLF) {
+ prevCharIsLF = false;
+ line += column = 1;
+ } else if (prevCharIsCR) {
+ prevCharIsCR = false;
+ if (c == '\n') {
+ prevCharIsLF = true;
+ } else
+ line += column = 1;
+ }
+
+ switch (c) {
+ case '\r':
+ prevCharIsCR = true;
+ break;
+ case '\n':
+ prevCharIsLF = true;
+ break;
+ case '\t':
+ column--;
+ column += tabSize - (column % tabSize);
+ break;
+ default:
+ break;
+ }
+
+ bufline[bufpos] = line;
+ bufcolumn[bufpos] = column;
+ }
+
+ /**
+ * Read a character.
+ */
+ public char readChar() throws java.io.IOException {
+ if (inBuf > 0) {
+ --inBuf;
+
+ if (++bufpos == bufsize)
+ bufpos = 0;
+
+ return buffer[bufpos];
+ }
+
+ if (++bufpos >= maxNextCharInd)
+ FillBuff();
+
+ char c = buffer[bufpos];
+
+ UpdateLineColumn(c);
+ return c;
+ }
+
+ @Deprecated
+ /**
+ * @deprecated
+ * @see #getEndColumn
+ */
+
+ public int getColumn() {
+ return bufcolumn[bufpos];
+ }
+
+ @Deprecated
+ /**
+ * @deprecated
+ * @see #getEndLine
+ */
+
+ public int getLine() {
+ return bufline[bufpos];
+ }
+
+ /**
+ * Get token end column number.
+ */
+ public int getEndColumn() {
+ return bufcolumn[bufpos];
+ }
+
+ /**
+ * Get token end line number.
+ */
+ public int getEndLine() {
+ return bufline[bufpos];
+ }
+
+ /**
+ * Get token beginning column number.
+ */
+ public int getBeginColumn() {
+ return bufcolumn[tokenBegin];
+ }
+
+ /**
+ * Get token beginning line number.
+ */
+ public int getBeginLine() {
+ return bufline[tokenBegin];
+ }
+
+ /**
+ * Backup a number of characters.
+ */
+ public void backup(int amount) {
+
+ inBuf += amount;
+ if ((bufpos -= amount) < 0)
+ bufpos += bufsize;
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.Reader dstream, int startline,
+ int startcolumn, int buffersize) {
+ inputStream = dstream;
+ line = startline;
+ column = startcolumn - 1;
+
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.Reader dstream, int startline,
+ int startcolumn) {
+ this(dstream, startline, startcolumn, 4096);
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.Reader dstream) {
+ this(dstream, 1, 1, 4096);
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.Reader dstream, int startline,
+ int startcolumn, int buffersize) {
+ inputStream = dstream;
+ line = startline;
+ column = startcolumn - 1;
+
+ if (buffer == null || buffersize != buffer.length) {
+ available = bufsize = buffersize;
+ buffer = new char[buffersize];
+ bufline = new int[buffersize];
+ bufcolumn = new int[buffersize];
+ }
+ prevCharIsLF = prevCharIsCR = false;
+ tokenBegin = inBuf = maxNextCharInd = 0;
+ bufpos = -1;
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.Reader dstream, int startline,
+ int startcolumn) {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.Reader dstream) {
+ ReInit(dstream, 1, 1, 4096);
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+ int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException {
+ this(encoding == null ?
+ new java.io.InputStreamReader(dstream) :
+ new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.InputStream dstream, int startline,
+ int startcolumn, int buffersize) {
+ this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline,
+ int startcolumn) throws java.io.UnsupportedEncodingException {
+ this(dstream, encoding, startline, startcolumn, 4096);
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.InputStream dstream, int startline,
+ int startcolumn) {
+ this(dstream, startline, startcolumn, 4096);
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException {
+ this(dstream, encoding, 1, 1, 4096);
+ }
+
+ /**
+ * Constructor.
+ */
+ public SimpleCharStream(java.io.InputStream dstream) {
+ this(dstream, 1, 1, 4096);
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+ int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException {
+ ReInit(encoding == null ?
+ new java.io.InputStreamReader(dstream) :
+ new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.InputStream dstream, int startline,
+ int startcolumn, int buffersize) {
+ ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException {
+ ReInit(dstream, encoding, 1, 1, 4096);
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.InputStream dstream) {
+ ReInit(dstream, 1, 1, 4096);
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+ int startcolumn) throws java.io.UnsupportedEncodingException {
+ ReInit(dstream, encoding, startline, startcolumn, 4096);
+ }
+
+ /**
+ * Reinitialise.
+ */
+ public void ReInit(java.io.InputStream dstream, int startline,
+ int startcolumn) {
+ ReInit(dstream, startline, startcolumn, 4096);
+ }
+
+ /**
+ * Get token literal value.
+ */
+ public String GetImage() {
+ if (bufpos >= tokenBegin)
+ return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
+ else
+ return new String(buffer, tokenBegin, bufsize - tokenBegin) +
+ new String(buffer, 0, bufpos + 1);
+ }
+
+ /**
+ * Get the suffix.
+ */
+ public char[] GetSuffix(int len) {
+ char[] ret = new char[len];
+
+ if ((bufpos + 1) >= len)
+ System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
+ else {
+ System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
+ len - bufpos - 1);
+ System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
+ }
+
+ return ret;
+ }
+
+ /**
+ * Reset buffer when finished.
+ */
+ public void Done() {
+ buffer = null;
+ bufline = null;
+ bufcolumn = null;
+ }
+
+ /**
+ * Method to adjust line and column numbers for the start of a token.
+ */
+ public void adjustBeginLineColumn(int newLine, int newCol) {
+ int start = tokenBegin;
+ int len;
+
+ if (bufpos >= tokenBegin) {
+ len = bufpos - tokenBegin + inBuf + 1;
+ } else {
+ len = bufsize - tokenBegin + bufpos + 1 + inBuf;
+ }
+
+ int i = 0, j = 0, k = 0;
+ int nextColDiff = 0, columnDiff = 0;
+
+ while (i < len && bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) {
+ bufline[j] = newLine;
+ nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
+ bufcolumn[j] = newCol + columnDiff;
+ columnDiff = nextColDiff;
+ i++;
+ }
+
+ if (i < len) {
+ bufline[j] = newLine++;
+ bufcolumn[j] = newCol + columnDiff;
+
+ while (i++ < len) {
+ if (bufline[j = start % bufsize] != bufline[++start % bufsize])
+ bufline[j] = newLine++;
+ else
+ bufline[j] = newLine;
+ }
+ }
+
+ line = bufline[j];
+ column = bufcolumn[j];
+ }
+
+}
+/* JavaCC - OriginalChecksum=af79bfe4b18b4b4ea9720ffeb7e52fc5 (do not edit this line) */
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/9eeb2f7e/filter/src/main/java/org/apache/rocketmq/filter/parser/Token.java
----------------------------------------------------------------------
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/Token.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/Token.java
new file mode 100644
index 0000000..8e6a48a
--- /dev/null
+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/Token.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* Generated By:JavaCC: Do not edit this line. Token.java Version 5.0 */
+/* JavaCCOptions:TOKEN_EXTENDS=,KEEP_LINE_COL=null,SUPPORT_CLASS_VISIBILITY_PUBLIC=true */
+package org.apache.rocketmq.filter.parser;
+
+/**
+ * Describes the input token stream.
+ */
+
+public class Token implements java.io.Serializable {
+
+ /**
+ * The version identifier for this Serializable class.
+ * Increment only if the <i>serialized</i> form of the
+ * class changes.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * An integer that describes the kind of this token. This numbering
+ * system is determined by JavaCCParser, and a table of these numbers is
+ * stored in the file ...Constants.java.
+ */
+ public int kind;
+
+ /**
+ * The line number of the first character of this Token.
+ */
+ public int beginLine;
+ /**
+ * The column number of the first character of this Token.
+ */
+ public int beginColumn;
+ /**
+ * The line number of the last character of this Token.
+ */
+ public int endLine;
+ /**
+ * The column number of the last character of this Token.
+ */
+ public int endColumn;
+
+ /**
+ * The string image of the token.
+ */
+ public String image;
+
+ /**
+ * A reference to the next regular (non-special) token from the input
+ * stream. If this is the last token from the input stream, or if the
+ * token manager has not read tokens beyond this one, this field is
+ * set to null. This is true only if this token is also a regular
+ * token. Otherwise, see below for a description of the contents of
+ * this field.
+ */
+ public Token next;
+
+ /**
+ * This field is used to access special tokens that occur prior to this
+ * token, but after the immediately preceding regular (non-special) token.
+ * If there are no such special tokens, this field is set to null.
+ * When there are more than one such special token, this field refers
+ * to the last of these special tokens, which in turn refers to the next
+ * previous special token through its specialToken field, and so on
+ * until the first special token (whose specialToken field is null).
+ * The next fields of special tokens refer to other special tokens that
+ * immediately follow it (without an intervening regular token). If there
+ * is no such token, this field is null.
+ */
+ public Token specialToken;
+
+ /**
+ * An optional attribute value of the Token.
+ * Tokens which are not used as syntactic sugar will often contain
+ * meaningful values that will be used later on by the compiler or
+ * interpreter. This attribute value is often different from the image.
+ * Any subclass of Token that actually wants to return a non-null value can
+ * override this method as appropriate.
+ */
+ public Object getValue() {
+ return null;
+ }
+
+ /**
+ * No-argument constructor
+ */
+ public Token() {
+ }
+
+ /**
+ * Constructs a new token for the specified Image.
+ */
+ public Token(int kind) {
+ this(kind, null);
+ }
+
+ /**
+ * Constructs a new token for the specified Image and Kind.
+ */
+ public Token(int kind, String image) {
+ this.kind = kind;
+ this.image = image;
+ }
+
+ /**
+ * Returns the image.
+ */
+ public String toString() {
+ return image;
+ }
+
+ /**
+ * Returns a new Token object, by default. However, if you want, you
+ * can create and return subclass objects based on the value of ofKind.
+ * Simply add the cases to the switch for all those special cases.
+ * For example, if you have a subclass of Token called IDToken that
+ * you want to create if ofKind is ID, simply add something like :
+ * <p/>
+ * case MyParserConstants.ID : return new IDToken(ofKind, image);
+ * <p/>
+ * to the following switch statement. Then you can cast matchedToken
+ * variable to the appropriate type and use sit in your lexical actions.
+ */
+ public static Token newToken(int ofKind, String image) {
+ switch (ofKind) {
+ default:
+ return new Token(ofKind, image);
+ }
+ }
+
+ public static Token newToken(int ofKind) {
+ return newToken(ofKind, null);
+ }
+
+}
+/* JavaCC - OriginalChecksum=6b0af88eb45a551d929d3cdd9582f827 (do not edit this line) */
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/9eeb2f7e/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java
----------------------------------------------------------------------
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java b/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java
new file mode 100644
index 0000000..75d83e5
--- /dev/null
+++ b/filter/src/main/java/org/apache/rocketmq/filter/parser/TokenMgrError.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 5.0 */
+/* JavaCCOptions: */
+package org.apache.rocketmq.filter.parser;
+
+/**
+ * Token Manager Error.
+ */
+public class TokenMgrError extends Error {
+
+ /**
+ * The version identifier for this Serializable class.
+ * Increment only if the <i>serialized</i> form of the
+ * class changes.
+ */
+ private static final long serialVersionUID = 1L;
+
+ /*
+ * Ordinals for various reasons why an Error of this type can be thrown.
+ */
+
+ /**
+ * Lexical error occurred.
+ */
+ static final int LEXICAL_ERROR = 0;
+
+ /**
+ * An attempt was made to create a second instance of a static token manager.
+ */
+ static final int STATIC_LEXER_ERROR = 1;
+
+ /**
+ * Tried to change to an invalid lexical state.
+ */
+ static final int INVALID_LEXICAL_STATE = 2;
+
+ /**
+ * Detected (and bailed out of) an infinite loop in the token manager.
+ */
+ static final int LOOP_DETECTED = 3;
+
+ /**
+ * Indicates the reason why the exception is thrown. It will have
+ * one of the above 4 values.
+ */
+ int errorCode;
+
+ /**
+ * Replaces unprintable characters by their escaped (or unicode escaped)
+ * equivalents in the given string
+ */
+ protected static final String addEscapes(String str) {
+ StringBuffer retval = new StringBuffer();
+ char ch;
+ for (int i = 0; i < str.length(); i++) {
+ switch (str.charAt(i)) {
+ case 0:
+ continue;
+ case '\b':
+ retval.append("\\b");
+ continue;
+ case '\t':
+ retval.append("\\t");
+ continue;
+ case '\n':
+ retval.append("\\n");
+ continue;
+ case '\f':
+ retval.append("\\f");
+ continue;
+ case '\r':
+ retval.append("\\r");
+ continue;
+ case '\"':
+ retval.append("\\\"");
+ continue;
+ case '\'':
+ retval.append("\\\'");
+ continue;
+ case '\\':
+ retval.append("\\\\");
+ continue;
+ default:
+ if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) {
+ String s = "0000" + Integer.toString(ch, 16);
+ retval.append("\\u" + s.substring(s.length() - 4, s.length()));
+ } else {
+ retval.append(ch);
+ }
+ continue;
+ }
+ }
+ return retval.toString();
+ }
+
+ /**
+ * Returns a detailed message for the Error when it is thrown by the
+ * token manager to indicate a lexical error.
+ * Parameters :
+ * eofSeen : indicates if EOF caused the lexical error
+ * curLexState : lexical state in which this error occurred
+ * errorLine : line number when the error occurred
+ * errorColumn : column number when the error occurred
+ * errorAfter : prefix that was seen before this error occurred
+ * curchar : the offending character
+ * Note: You can customize the lexical error message by modifying this method.
+ */
+ protected static String LexicalError(boolean eofSeen, int lexState, int errorLine, int errorColumn,
+ String errorAfter, char curChar) {
+ return "Lexical error at line " +
+ errorLine + ", column " +
+ errorColumn + ". Encountered: " +
+ (eofSeen ?
+ "<EOF> " :
+ ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int) curChar + "), ") +
+ "after : \"" + addEscapes(errorAfter) + "\"";
+ }
+
+ /**
+ * You can also modify the body of this method to customize your error messages.
+ * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not
+ * of end-users concern, so you can return something like :
+ * <p/>
+ * "Internal Error : Please file a bug report .... "
+ * <p/>
+ * from this method for such cases in the release version of your parser.
+ */
+ public String getMessage() {
+ return super.getMessage();
+ }
+
+ /*
+ * Constructors of various flavors follow.
+ */
+
+ /**
+ * No arg constructor.
+ */
+ public TokenMgrError() {
+ }
+
+ /**
+ * Constructor with message and reason.
+ */
+ public TokenMgrError(String message, int reason) {
+ super(message);
+ errorCode = reason;
+ }
+
+ /**
+ * Full Constructor.
+ */
+ public TokenMgrError(boolean eofSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar,
+ int reason) {
+ this(LexicalError(eofSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason);
+ }
+}
+/* JavaCC - OriginalChecksum=e960778c8dcd73e167ed5bfddd59f288 (do not edit this line) */
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/9eeb2f7e/filter/src/main/java/org/apache/rocketmq/filter/util/BitsArray.java
----------------------------------------------------------------------
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/util/BitsArray.java b/filter/src/main/java/org/apache/rocketmq/filter/util/BitsArray.java
new file mode 100644
index 0000000..9866854
--- /dev/null
+++ b/filter/src/main/java/org/apache/rocketmq/filter/util/BitsArray.java
@@ -0,0 +1,260 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.filter.util;
+
+/**
+ * Wrapper of bytes array, in order to operate single bit easily.
+ */
+public class BitsArray implements Cloneable {
+
+ private byte[] bytes;
+ private int bitLength;
+
+ public static BitsArray create(int bitLength) {
+ return new BitsArray(bitLength);
+ }
+
+ public static BitsArray create(byte[] bytes, int bitLength) {
+ return new BitsArray(bytes, bitLength);
+ }
+
+ public static BitsArray create(byte[] bytes) {
+ return new BitsArray(bytes);
+ }
+
+ private BitsArray(int bitLength) {
+ this.bitLength = bitLength;
+ // init bytes
+ int temp = bitLength / Byte.SIZE;
+ if (bitLength % Byte.SIZE > 0) {
+ temp++;
+ }
+ bytes = new byte[temp];
+ for (int i = 0; i < bytes.length; i++) {
+ bytes[i] = (byte) 0x00;
+ }
+ }
+
+ private BitsArray(byte[] bytes, int bitLength) {
+ if (bytes == null || bytes.length < 1) {
+ throw new IllegalArgumentException("Bytes is empty!");
+ }
+
+ if (bitLength < 1) {
+ throw new IllegalArgumentException("Bit is less than 1.");
+ }
+
+ if (bitLength < bytes.length * Byte.SIZE) {
+ throw new IllegalArgumentException("BitLength is less than bytes.length() * " + Byte.SIZE);
+ }
+
+ this.bytes = new byte[bytes.length];
+ System.arraycopy(bytes, 0, this.bytes, 0, this.bytes.length);
+ this.bitLength = bitLength;
+ }
+
+ private BitsArray(byte[] bytes) {
+ if (bytes == null || bytes.length < 1) {
+ throw new IllegalArgumentException("Bytes is empty!");
+ }
+
+ this.bitLength = bytes.length * Byte.SIZE;
+ this.bytes = new byte[bytes.length];
+ System.arraycopy(bytes, 0, this.bytes, 0, this.bytes.length);
+ }
+
+ public int bitLength() {
+ return this.bitLength;
+ }
+
+ public int byteLength() {
+ return this.bytes.length;
+ }
+
+ public byte[] bytes() {
+ return this.bytes;
+ }
+
+ public void xor(final BitsArray other) {
+ checkInitialized(this);
+ checkInitialized(other);
+
+ int minByteLength = Math.min(this.byteLength(), other.byteLength());
+
+ for (int i = 0; i < minByteLength; i++) {
+ this.bytes[i] = (byte) (this.bytes[i] ^ other.getByte(i));
+ }
+ }
+
+ public void xor(int bitPos, boolean set) {
+ checkBitPosition(bitPos, this);
+
+ boolean value = getBit(bitPos);
+ if (value ^ set) {
+ setBit(bitPos, true);
+ } else {
+ setBit(bitPos, false);
+ }
+ }
+
+ public void or(final BitsArray other) {
+ checkInitialized(this);
+ checkInitialized(other);
+
+ int minByteLength = Math.min(this.byteLength(), other.byteLength());
+
+ for (int i = 0; i < minByteLength; i++) {
+ this.bytes[i] = (byte) (this.bytes[i] | other.getByte(i));
+ }
+ }
+
+ public void or(int bitPos, boolean set) {
+ checkBitPosition(bitPos, this);
+
+ if (set) {
+ setBit(bitPos, true);
+ }
+ }
+
+ public void and(final BitsArray other) {
+ checkInitialized(this);
+ checkInitialized(other);
+
+ int minByteLength = Math.min(this.byteLength(), other.byteLength());
+
+ for (int i = 0; i < minByteLength; i++) {
+ this.bytes[i] = (byte) (this.bytes[i] & other.getByte(i));
+ }
+ }
+
+ public void and(int bitPos, boolean set) {
+ checkBitPosition(bitPos, this);
+
+ if (!set) {
+ setBit(bitPos, false);
+ }
+ }
+
+ public void not(int bitPos) {
+ checkBitPosition(bitPos, this);
+
+ setBit(bitPos, !getBit(bitPos));
+ }
+
+ public void setBit(int bitPos, boolean set) {
+ checkBitPosition(bitPos, this);
+ int sub = subscript(bitPos);
+ int pos = position(bitPos);
+ if (set) {
+ this.bytes[sub] = (byte) (this.bytes[sub] | pos);
+ } else {
+ this.bytes[sub] = (byte) (this.bytes[sub] & ~pos);
+ }
+ }
+
+ public void setByte(int bytePos, byte set) {
+ checkBytePosition(bytePos, this);
+
+ this.bytes[bytePos] = set;
+ }
+
+ public boolean getBit(int bitPos) {
+ checkBitPosition(bitPos, this);
+
+ return (this.bytes[subscript(bitPos)] & position(bitPos)) != 0;
+ }
+
+ public byte getByte(int bytePos) {
+ checkBytePosition(bytePos, this);
+
+ return this.bytes[bytePos];
+ }
+
+ protected int subscript(int bitPos) {
+ return bitPos / Byte.SIZE;
+ }
+
+ protected int position(int bitPos) {
+ return 1 << bitPos % Byte.SIZE;
+ }
+
+ protected void checkBytePosition(int bytePos, BitsArray bitsArray) {
+ checkInitialized(bitsArray);
+ if (bytePos > bitsArray.byteLength()) {
+ throw new IllegalArgumentException("BytePos is greater than " + bytes.length);
+ }
+ if (bytePos < 0) {
+ throw new IllegalArgumentException("BytePos is less than 0");
+ }
+ }
+
+ protected void checkBitPosition(int bitPos, BitsArray bitsArray) {
+ checkInitialized(bitsArray);
+ if (bitPos > bitsArray.bitLength()) {
+ throw new IllegalArgumentException("BitPos is greater than " + bitLength);
+ }
+ if (bitPos < 0) {
+ throw new IllegalArgumentException("BitPos is less than 0");
+ }
+ }
+
+ protected void checkInitialized(BitsArray bitsArray) {
+ if (bitsArray.bytes() == null) {
+ throw new RuntimeException("Not initialized!");
+ }
+ }
+
+ public BitsArray clone() {
+ byte[] clone = new byte[this.byteLength()];
+
+ System.arraycopy(this.bytes, 0, clone, 0, this.byteLength());
+
+ return create(clone, bitLength());
+ }
+
+ @Override
+ public String toString() {
+ if (this.bytes == null) {
+ return "null";
+ }
+ StringBuilder stringBuilder = new StringBuilder(this.bytes.length * Byte.SIZE);
+ for (int i = this.bytes.length - 1; i >= 0; i--) {
+
+ int j = Byte.SIZE - 1;
+ if (i == this.bytes.length - 1 && this.bitLength % Byte.SIZE > 0) {
+ // not full byte
+ j = this.bitLength % Byte.SIZE;
+ }
+
+ for (; j >= 0; j--) {
+
+ byte mask = (byte) (1 << j);
+ if ((this.bytes[i] & mask) == mask) {
+ stringBuilder.append("1");
+ } else {
+ stringBuilder.append("0");
+ }
+ }
+ if (i % 8 == 0) {
+ stringBuilder.append("\n");
+ }
+ }
+
+ return stringBuilder.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/9eeb2f7e/filter/src/main/java/org/apache/rocketmq/filter/util/BloomFilter.java
----------------------------------------------------------------------
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/util/BloomFilter.java b/filter/src/main/java/org/apache/rocketmq/filter/util/BloomFilter.java
new file mode 100644
index 0000000..f610906
--- /dev/null
+++ b/filter/src/main/java/org/apache/rocketmq/filter/util/BloomFilter.java
@@ -0,0 +1,338 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.filter.util;
+
+import com.google.common.hash.Hashing;
+
+import java.nio.charset.Charset;
+
+/**
+ * Simple implement of bloom filter.
+ */
+public class BloomFilter {
+
+ public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+ // as error rate, 10/100 = 0.1
+ private int f = 10;
+ private int n = 128;
+
+ // hash function num, by calculation.
+ private int k;
+ // bit count, by calculation.
+ private int m;
+
+ /**
+ * Create bloom filter by error rate and mapping num.
+ *
+ * @param f error rate
+ * @param n num will mapping to bit
+ * @return
+ */
+ public static BloomFilter createByFn(int f, int n) {
+ return new BloomFilter(f, n);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param f error rate
+ * @param n num will mapping to bit
+ */
+ private BloomFilter(int f, int n) {
+ if (f < 1 || f >= 100) {
+ throw new IllegalArgumentException("f must be greater or equal than 1 and less than 100");
+ }
+ if (n < 1) {
+ throw new IllegalArgumentException("n must be greater than 0");
+ }
+
+ this.f = f;
+ this.n = n;
+
+ // set p = e^(-kn/m)
+ // f = (1 - p)^k = e^(kln(1-p))
+ // when p = 0.5, k = ln2 * (m/n), f = (1/2)^k = (0.618)^(m/n)
+ double errorRate = f / 100.0;
+ this.k = (int) Math.ceil(logMN(0.5, errorRate));
+
+ if (this.k < 1) {
+ throw new IllegalArgumentException("Hash function num is less than 1, maybe you should change the value of error rate or bit num!");
+ }
+
+ // m >= n*log2(1/f)*log2(e)
+ this.m = (int) Math.ceil(this.n * logMN(2, 1 / errorRate) * logMN(2, Math.E));
+ // m%8 = 0
+ this.m = (int) (Byte.SIZE * Math.ceil(this.m / (Byte.SIZE * 1.0)));
+ }
+
+ /**
+ * Calculate bit positions of {@code str}.
+ * <p>
+ * See "Less Hashing, Same Performance: Building a Better Bloom Filter" by Adam Kirsch and Michael
+ * Mitzenmacher.
+ * </p>
+ *
+ * @param str
+ * @return
+ */
+ public int[] calcBitPositions(String str) {
+ int[] bitPositions = new int[this.k];
+
+ long hash64 = Hashing.murmur3_128().hashString(str, UTF_8).asLong();
+
+ int hash1 = (int) hash64;
+ int hash2 = (int) (hash64 >>> 32);
+
+ for (int i = 1; i <= this.k; i++) {
+ int combinedHash = hash1 + (i * hash2);
+ // Flip all the bits if it's negative (guaranteed positive number)
+ if (combinedHash < 0) {
+ combinedHash = ~combinedHash;
+ }
+ bitPositions[i - 1] = combinedHash % this.m;
+ }
+
+ return bitPositions;
+ }
+
+ /**
+ * Calculate bit positions of {@code str} to construct {@code BloomFilterData}
+ *
+ * @param str
+ * @return
+ */
+ public BloomFilterData generate(String str) {
+ int[] bitPositions = calcBitPositions(str);
+
+ return new BloomFilterData(bitPositions, this.m);
+ }
+
+ /**
+ * Calculate bit positions of {@code str}, then set the related {@code bits} positions to 1.
+ *
+ * @param str
+ * @param bits
+ */
+ public void hashTo(String str, BitsArray bits) {
+ hashTo(calcBitPositions(str), bits);
+ }
+
+ /**
+ * Set the related {@code bits} positions to 1.
+ *
+ * @param bitPositions
+ * @param bits
+ */
+ public void hashTo(int[] bitPositions, BitsArray bits) {
+ check(bits);
+
+ for (int i : bitPositions) {
+ bits.setBit(i, true);
+ }
+ }
+
+ /**
+ * Extra check:
+ * <li>1. check {@code filterData} belong to this bloom filter.</li>
+ * <p>
+ * Then set the related {@code bits} positions to 1.
+ * </p>
+ *
+ * @param filterData
+ * @param bits
+ */
+ public void hashTo(BloomFilterData filterData, BitsArray bits) {
+ if (!isValid(filterData)) {
+ throw new IllegalArgumentException(
+ String.format("Bloom filter data may not belong to this filter! %s, %s",
+ filterData, this.toString())
+ );
+ }
+ hashTo(filterData.getBitPos(), bits);
+ }
+
+ /**
+ * Calculate bit positions of {@code str}, then check all the related {@code bits} positions is 1.
+ *
+ * @param str
+ * @param bits
+ * @return true: all the related {@code bits} positions is 1
+ */
+ public boolean isHit(String str, BitsArray bits) {
+ return isHit(calcBitPositions(str), bits);
+ }
+
+ /**
+ * Check all the related {@code bits} positions is 1.
+ *
+ * @param bitPositions
+ * @param bits
+ * @return true: all the related {@code bits} positions is 1
+ */
+ public boolean isHit(int[] bitPositions, BitsArray bits) {
+ check(bits);
+ boolean ret = bits.getBit(bitPositions[0]);
+ for (int i = 1; i < bitPositions.length; i++) {
+ ret &= bits.getBit(bitPositions[i]);
+ }
+ return ret;
+ }
+
+ /**
+ * Check all the related {@code bits} positions is 1.
+ *
+ * @param filterData
+ * @param bits
+ * @return true: all the related {@code bits} positions is 1
+ */
+ public boolean isHit(BloomFilterData filterData, BitsArray bits) {
+ if (!isValid(filterData)) {
+ throw new IllegalArgumentException(
+ String.format("Bloom filter data may not belong to this filter! %s, %s",
+ filterData, this.toString())
+ );
+ }
+ return isHit(filterData.getBitPos(), bits);
+ }
+
+ /**
+ * Check whether one of {@code bitPositions} has been occupied.
+ *
+ * @param bitPositions
+ * @param bits
+ * @return true: if all positions have been occupied.
+ */
+ public boolean checkFalseHit(int[] bitPositions, BitsArray bits) {
+ for (int j = 0; j < bitPositions.length; j++) {
+ int pos = bitPositions[j];
+
+ // check position of bits has been set.
+ // that mean no one occupy the position.
+ if (!bits.getBit(pos)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected void check(BitsArray bits) {
+ if (bits.bitLength() != this.m) {
+ throw new IllegalArgumentException(
+ String.format("Length(%d) of bits in BitsArray is not equal to %d!", bits.bitLength(), this.m)
+ );
+ }
+ }
+
+ /**
+ * Check {@code BloomFilterData} is valid, and belong to this bloom filter.
+ * <li>1. not null</li>
+ * <li>2. {@link org.apache.rocketmq.filter.util.BloomFilterData#getBitNum} must be equal to {@code m} </li>
+ * <li>3. {@link org.apache.rocketmq.filter.util.BloomFilterData#getBitPos} is not null</li>
+ * <li>4. {@link org.apache.rocketmq.filter.util.BloomFilterData#getBitPos}'s length is equal to {@code k}</li>
+ *
+ * @param filterData
+ * @return
+ */
+ public boolean isValid(BloomFilterData filterData) {
+ if (filterData == null
+ || filterData.getBitNum() != this.m
+ || filterData.getBitPos() == null
+ || filterData.getBitPos().length != this.k) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * error rate.
+ *
+ * @return
+ */
+ public int getF() {
+ return f;
+ }
+
+ /**
+ * expect mapping num.
+ *
+ * @return
+ */
+ public int getN() {
+ return n;
+ }
+
+ /**
+ * hash function num.
+ *
+ * @return
+ */
+ public int getK() {
+ return k;
+ }
+
+ /**
+ * total bit num.
+ *
+ * @return
+ */
+ public int getM() {
+ return m;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof BloomFilter))
+ return false;
+
+ BloomFilter that = (BloomFilter) o;
+
+ if (f != that.f)
+ return false;
+ if (k != that.k)
+ return false;
+ if (m != that.m)
+ return false;
+ if (n != that.n)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = f;
+ result = 31 * result + n;
+ result = 31 * result + k;
+ result = 31 * result + m;
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("f: %d, n: %d, k: %d, m: %d", f, n, k, m);
+ }
+
+ protected double logMN(double m, double n) {
+ return Math.log(n) / Math.log(m);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-rocketmq/blob/9eeb2f7e/filter/src/main/java/org/apache/rocketmq/filter/util/BloomFilterData.java
----------------------------------------------------------------------
diff --git a/filter/src/main/java/org/apache/rocketmq/filter/util/BloomFilterData.java b/filter/src/main/java/org/apache/rocketmq/filter/util/BloomFilterData.java
new file mode 100644
index 0000000..de02d92
--- /dev/null
+++ b/filter/src/main/java/org/apache/rocketmq/filter/util/BloomFilterData.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.rocketmq.filter.util;
+
+import java.util.Arrays;
+
+/**
+ * Data generated by bloom filter, include:
+ * <li>1. Bit positions allocated to requester;</li>
+ * <li>2. Total bit num when allocating;</li>
+ */
+public class BloomFilterData {
+
+ private int[] bitPos;
+ private int bitNum;
+
+ public BloomFilterData() {
+ }
+
+ public BloomFilterData(int[] bitPos, int bitNum) {
+ this.bitPos = bitPos;
+ this.bitNum = bitNum;
+ }
+
+ public int[] getBitPos() {
+ return bitPos;
+ }
+
+ public int getBitNum() {
+ return bitNum;
+ }
+
+ public void setBitPos(final int[] bitPos) {
+ this.bitPos = bitPos;
+ }
+
+ public void setBitNum(final int bitNum) {
+ this.bitNum = bitNum;
+ }
+
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (!(o instanceof BloomFilterData)) return false;
+
+ final BloomFilterData that = (BloomFilterData) o;
+
+ if (bitNum != that.bitNum) return false;
+ if (!Arrays.equals(bitPos, that.bitPos)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = bitPos != null ? Arrays.hashCode(bitPos) : 0;
+ result = 31 * result + bitNum;
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "BloomFilterData{" +
+ "bitPos=" + Arrays.toString(bitPos) +
+ ", bitNum=" + bitNum +
+ '}';
+ }
+}