OptExactInfo.java revision 1088:7e62d98d4625
1/* 2 * Permission is hereby granted, free of charge, to any person obtaining a copy of 3 * this software and associated documentation files (the "Software"), to deal in 4 * the Software without restriction, including without limitation the rights to 5 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 6 * of the Software, and to permit persons to whom the Software is furnished to do 7 * so, subject to the following conditions: 8 * 9 * The above copyright notice and this permission notice shall be included in all 10 * copies or substantial portions of the Software. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 18 * SOFTWARE. 19 */ 20package jdk.nashorn.internal.runtime.regexp.joni; 21 22final class OptExactInfo { 23 static final int OPT_EXACT_MAXLEN = 24; 24 25 final MinMaxLen mmd = new MinMaxLen(); 26 final OptAnchorInfo anchor = new OptAnchorInfo(); 27 28 boolean reachEnd; 29 boolean ignoreCase; 30 31 final char chars[] = new char[OPT_EXACT_MAXLEN]; 32 int length; 33 34 boolean isFull() { 35 return length >= OPT_EXACT_MAXLEN; 36 } 37 38 void clear() { 39 mmd.clear(); 40 anchor.clear(); 41 42 reachEnd = false; 43 ignoreCase = false; 44 length = 0; 45 } 46 47 void copy(final OptExactInfo other) { 48 mmd.copy(other.mmd); 49 anchor.copy(other.anchor); 50 reachEnd = other.reachEnd; 51 ignoreCase = other.ignoreCase; 52 length = other.length; 53 54 System.arraycopy(other.chars, 0, chars, 0, OPT_EXACT_MAXLEN); 55 } 56 57 void concat(final OptExactInfo other) { 58 if (!ignoreCase && other.ignoreCase) { 59 if (length >= other.length) { 60 return; /* avoid */ 61 } 62 ignoreCase = true; 63 } 64 65 int p = 0; // add->s; 66 final int end = p + other.length; 67 68 int i; 69 for (i = length; p < end;) { 70 if (i + 1 > OPT_EXACT_MAXLEN) { 71 break; 72 } 73 chars[i++] = other.chars[p++]; 74 } 75 76 length = i; 77 reachEnd = (p == end ? other.reachEnd : false); 78 79 final OptAnchorInfo tmp = new OptAnchorInfo(); 80 tmp.concat(anchor, other.anchor, 1, 1); 81 if (!other.reachEnd) { 82 tmp.rightAnchor = 0; 83 } 84 anchor.copy(tmp); 85 } 86 87 // ?? raw is not used here 88 void concatStr(final char[] lchars, final int pp, final int end, final boolean raw) { 89 int i; 90 int p = pp; 91 for (i = length; p < end && i < OPT_EXACT_MAXLEN;) { 92 if (i + 1 > OPT_EXACT_MAXLEN) { 93 break; 94 } 95 chars[i++] = lchars[p++]; 96 } 97 98 length = i; 99 } 100 101 void altMerge(final OptExactInfo other, final OptEnvironment env) { 102 if (other.length == 0 || length == 0) { 103 clear(); 104 return; 105 } 106 107 if (!mmd.equal(other.mmd)) { 108 clear(); 109 return; 110 } 111 112 int i; 113 for (i = 0; i < length && i < other.length; i++) { 114 if (chars[i] != other.chars[i]) { 115 break; 116 } 117 } 118 119 if (!other.reachEnd || i<other.length || i<length) { 120 reachEnd = false; 121 } 122 123 length = i; 124 ignoreCase |= other.ignoreCase; 125 126 anchor.altMerge(other.anchor); 127 128 if (!reachEnd) { 129 anchor.rightAnchor = 0; 130 } 131 } 132 133 134 void select(final OptExactInfo alt) { 135 int v1 = length; 136 int v2 = alt.length; 137 138 if (v2 == 0) { 139 return; 140 } else if (v1 == 0) { 141 copy(alt); 142 return; 143 } else if (v1 <= 2 && v2 <= 2) { 144 /* ByteValTable[x] is big value --> low price */ 145 v2 = OptMapInfo.positionValue(chars[0] & 0xff); 146 v1 = OptMapInfo.positionValue(alt.chars[0] & 0xff); 147 148 if (length > 1) { 149 v1 += 5; 150 } 151 if (alt.length > 1) { 152 v2 += 5; 153 } 154 } 155 156 if (!ignoreCase) { 157 v1 *= 2; 158 } 159 if (!alt.ignoreCase) { 160 v2 *= 2; 161 } 162 163 if (mmd.compareDistanceValue(alt.mmd, v1, v2) > 0) { 164 copy(alt); 165 } 166 } 167 168 // comp_opt_exact_or_map_info 169 private static final int COMP_EM_BASE = 20; 170 int compare(final OptMapInfo m) { 171 if (m.value <= 0) { 172 return -1; 173 } 174 175 final int ve = COMP_EM_BASE * length * (ignoreCase ? 1 : 2); 176 final int vm = COMP_EM_BASE * 5 * 2 / m.value; 177 178 return mmd.compareDistanceValue(m.mmd, ve, vm); 179 } 180} 181