/* * Decompiled with CFR 0.152. */ package com.google.common.base; import com.google.common.annotations.GwtIncompatible; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.CharMatcher; import java.util.BitSet; @GwtIncompatible(value="no precomputation is done in GWT") final class SmallCharMatcher extends CharMatcher.FastMatcher { static final int MAX_SIZE = 1023; private final char[] table; private final boolean containsZero; private final long filter; private static final int C1 = -862048943; private static final int C2 = 461845907; private static final double DESIRED_LOAD_FACTOR = 0.5; private SmallCharMatcher(char[] table, long filter, boolean containsZero, String description) { super(description); this.table = table; this.filter = filter; this.containsZero = containsZero; } static int smear(int hashCode) { return 461845907 * Integer.rotateLeft(hashCode * -862048943, 15); } private boolean checkFilter(int c) { return 1L == (1L & this.filter >> c); } @VisibleForTesting static int chooseTableSize(int setSize) { if (setSize == 1) { return 2; } int tableSize = Integer.highestOneBit(setSize - 1) << 1; while ((double)tableSize * 0.5 < (double)setSize) { tableSize <<= 1; } return tableSize; } static CharMatcher from(BitSet chars, String description) { long filter = 0L; int size = chars.cardinality(); boolean containsZero = chars.get(0); char[] table = new char[SmallCharMatcher.chooseTableSize(size)]; int mask = table.length - 1; int c = chars.nextSetBit(0); while (c != -1) { filter |= 1L << c; int index = SmallCharMatcher.smear(c) & mask; while (true) { if (table[index] == '\u0000') break; index = index + 1 & mask; } table[index] = (char)c; c = chars.nextSetBit(c + 1); } return new SmallCharMatcher(table, filter, containsZero, description); } @Override public boolean matches(char c) { int startingIndex; if (c == '\u0000') { return this.containsZero; } if (!this.checkFilter(c)) { return false; } int mask = this.table.length - 1; int index = startingIndex = SmallCharMatcher.smear(c) & mask; do { if (this.table[index] == '\u0000') { return false; } if (this.table[index] != c) continue; return true; } while ((index = index + 1 & mask) != startingIndex); return false; } @Override void setBits(BitSet table) { if (this.containsZero) { table.set(0); } for (char c : this.table) { if (c == '\u0000') continue; table.set(c); } } }