obsidian-launcher/src/com/google/common/base/SmallCharMatcher.java
2022-08-09 23:00:29 -07:00

100 lines
3 KiB
Java

/*
* 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);
}
}
}