Spaces:
Build error
Build error
package net.minecraft.client.searchtree; | |
import com.google.common.collect.Lists; | |
import com.google.common.collect.Sets; | |
import com.mojang.logging.LogUtils; | |
import it.unimi.dsi.fastutil.Arrays; | |
import it.unimi.dsi.fastutil.Swapper; | |
import it.unimi.dsi.fastutil.ints.IntArrayList; | |
import it.unimi.dsi.fastutil.ints.IntComparator; | |
import it.unimi.dsi.fastutil.ints.IntList; | |
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; | |
import it.unimi.dsi.fastutil.ints.IntSet; | |
import java.util.Collections; | |
import java.util.List; | |
import java.util.Set; | |
import net.minecraftforge.api.distmarker.Dist; | |
import net.minecraftforge.api.distmarker.OnlyIn; | |
import org.slf4j.Logger; | |
public class SuffixArray<T> { | |
private static final boolean DEBUG_COMPARISONS = Boolean.parseBoolean(System.getProperty("SuffixArray.printComparisons", "false")); | |
private static final boolean DEBUG_ARRAY = Boolean.parseBoolean(System.getProperty("SuffixArray.printArray", "false")); | |
private static final Logger LOGGER = LogUtils.getLogger(); | |
private static final int END_OF_TEXT_MARKER = -1; | |
private static final int END_OF_DATA = -2; | |
protected final List<T> list = Lists.newArrayList(); | |
private final IntList chars = new IntArrayList(); | |
private final IntList wordStarts = new IntArrayList(); | |
private IntList suffixToT = new IntArrayList(); | |
private IntList offsets = new IntArrayList(); | |
private int maxStringLength; | |
public void add(T p_119971_, String p_119972_) { | |
this.maxStringLength = Math.max(this.maxStringLength, p_119972_.length()); | |
int i = this.list.size(); | |
this.list.add(p_119971_); | |
this.wordStarts.add(this.chars.size()); | |
for (int j = 0; j < p_119972_.length(); j++) { | |
this.suffixToT.add(i); | |
this.offsets.add(j); | |
this.chars.add(p_119972_.charAt(j)); | |
} | |
this.suffixToT.add(i); | |
this.offsets.add(p_119972_.length()); | |
this.chars.add(-1); | |
} | |
public void generate() { | |
int i = this.chars.size(); | |
int[] aint = new int[i]; | |
int[] aint1 = new int[i]; | |
int[] aint2 = new int[i]; | |
int[] aint3 = new int[i]; | |
IntComparator intcomparator = (p_194458_, p_194459_) -> aint1[p_194458_] == aint1[p_194459_] | |
? Integer.compare(aint2[p_194458_], aint2[p_194459_]) | |
: Integer.compare(aint1[p_194458_], aint1[p_194459_]); | |
Swapper swapper = (p_194464_, p_194465_) -> { | |
if (p_194464_ != p_194465_) { | |
int i2 = aint1[p_194464_]; | |
aint1[p_194464_] = aint1[p_194465_]; | |
aint1[p_194465_] = i2; | |
i2 = aint2[p_194464_]; | |
aint2[p_194464_] = aint2[p_194465_]; | |
aint2[p_194465_] = i2; | |
i2 = aint3[p_194464_]; | |
aint3[p_194464_] = aint3[p_194465_]; | |
aint3[p_194465_] = i2; | |
} | |
}; | |
for (int j = 0; j < i; j++) { | |
aint[j] = this.chars.getInt(j); | |
} | |
int k1 = 1; | |
for (int k = Math.min(i, this.maxStringLength); k1 * 2 < k; k1 *= 2) { | |
for (int l = 0; l < i; aint3[l] = l++) { | |
aint1[l] = aint[l]; | |
aint2[l] = l + k1 < i ? aint[l + k1] : -2; | |
} | |
Arrays.quickSort(0, i, intcomparator, swapper); | |
for (int l1 = 0; l1 < i; l1++) { | |
if (l1 > 0 && aint1[l1] == aint1[l1 - 1] && aint2[l1] == aint2[l1 - 1]) { | |
aint[aint3[l1]] = aint[aint3[l1 - 1]]; | |
} else { | |
aint[aint3[l1]] = l1; | |
} | |
} | |
} | |
IntList intlist1 = this.suffixToT; | |
IntList intlist = this.offsets; | |
this.suffixToT = new IntArrayList(intlist1.size()); | |
this.offsets = new IntArrayList(intlist.size()); | |
for (int i1 = 0; i1 < i; i1++) { | |
int j1 = aint3[i1]; | |
this.suffixToT.add(intlist1.getInt(j1)); | |
this.offsets.add(intlist.getInt(j1)); | |
} | |
if (DEBUG_ARRAY) { | |
this.print(); | |
} | |
} | |
private void print() { | |
for (int i = 0; i < this.suffixToT.size(); i++) { | |
LOGGER.debug("{} {}", i, this.getString(i)); | |
} | |
LOGGER.debug(""); | |
} | |
private String getString(int p_119969_) { | |
int i = this.offsets.getInt(p_119969_); | |
int j = this.wordStarts.getInt(this.suffixToT.getInt(p_119969_)); | |
StringBuilder stringbuilder = new StringBuilder(); | |
for (int k = 0; j + k < this.chars.size(); k++) { | |
if (k == i) { | |
stringbuilder.append('^'); | |
} | |
int l = this.chars.getInt(j + k); | |
if (l == -1) { | |
break; | |
} | |
stringbuilder.append((char)l); | |
} | |
return stringbuilder.toString(); | |
} | |
private int compare(String p_119976_, int p_119977_) { | |
int i = this.wordStarts.getInt(this.suffixToT.getInt(p_119977_)); | |
int j = this.offsets.getInt(p_119977_); | |
for (int k = 0; k < p_119976_.length(); k++) { | |
int l = this.chars.getInt(i + j + k); | |
if (l == -1) { | |
return 1; | |
} | |
char c0 = p_119976_.charAt(k); | |
char c1 = (char)l; | |
if (c0 < c1) { | |
return -1; | |
} | |
if (c0 > c1) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
public List<T> search(String p_119974_) { | |
int i = this.suffixToT.size(); | |
int j = 0; | |
int k = i; | |
while (j < k) { | |
int l = j + (k - j) / 2; | |
int i1 = this.compare(p_119974_, l); | |
if (DEBUG_COMPARISONS) { | |
LOGGER.debug("comparing lower \"{}\" with {} \"{}\": {}", p_119974_, l, this.getString(l), i1); | |
} | |
if (i1 > 0) { | |
j = l + 1; | |
} else { | |
k = l; | |
} | |
} | |
if (j >= 0 && j < i) { | |
int i2 = j; | |
k = i; | |
while (j < k) { | |
int j2 = j + (k - j) / 2; | |
int j1 = this.compare(p_119974_, j2); | |
if (DEBUG_COMPARISONS) { | |
LOGGER.debug("comparing upper \"{}\" with {} \"{}\": {}", p_119974_, j2, this.getString(j2), j1); | |
} | |
if (j1 >= 0) { | |
j = j2 + 1; | |
} else { | |
k = j2; | |
} | |
} | |
int k2 = j; | |
IntSet intset = new IntOpenHashSet(); | |
for (int k1 = i2; k1 < k2; k1++) { | |
intset.add(this.suffixToT.getInt(k1)); | |
} | |
int[] aint = intset.toIntArray(); | |
java.util.Arrays.sort(aint); | |
Set<T> set = Sets.newLinkedHashSet(); | |
for (int l1 : aint) { | |
set.add(this.list.get(l1)); | |
} | |
return Lists.newArrayList(set); | |
} else { | |
return Collections.emptyList(); | |
} | |
} | |
} |