113 lines
3.5 KiB
Java
113 lines
3.5 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*
|
|
* Could not load the following classes:
|
|
* it.unimi.dsi.fastutil.ints.IntOpenHashSet
|
|
* it.unimi.dsi.fastutil.ints.IntSet
|
|
* org.jspecify.annotations.Nullable
|
|
*/
|
|
package net.minecraft.client.gui.font;
|
|
|
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
|
import it.unimi.dsi.fastutil.ints.IntSet;
|
|
import java.util.Arrays;
|
|
import java.util.function.IntFunction;
|
|
import org.jspecify.annotations.Nullable;
|
|
|
|
public class CodepointMap<T> {
|
|
private static final int BLOCK_BITS = 8;
|
|
private static final int BLOCK_SIZE = 256;
|
|
private static final int IN_BLOCK_MASK = 255;
|
|
private static final int MAX_BLOCK = 4351;
|
|
private static final int BLOCK_COUNT = 4352;
|
|
private final T[] empty;
|
|
private final @Nullable T[][] blockMap;
|
|
private final IntFunction<T[]> blockConstructor;
|
|
|
|
public CodepointMap(IntFunction<T[]> blockConstructor, IntFunction<T[][]> blockMapConstructor) {
|
|
this.empty = blockConstructor.apply(256);
|
|
this.blockMap = blockMapConstructor.apply(4352);
|
|
Arrays.fill(this.blockMap, this.empty);
|
|
this.blockConstructor = blockConstructor;
|
|
}
|
|
|
|
public void clear() {
|
|
Arrays.fill(this.blockMap, this.empty);
|
|
}
|
|
|
|
public @Nullable T get(int codepoint) {
|
|
int block = codepoint >> 8;
|
|
int offset = codepoint & 0xFF;
|
|
return this.blockMap[block][offset];
|
|
}
|
|
|
|
public @Nullable T put(int codepoint, T value) {
|
|
int block = codepoint >> 8;
|
|
int offset = codepoint & 0xFF;
|
|
T[] blockData = this.blockMap[block];
|
|
if (blockData == this.empty) {
|
|
blockData = this.blockConstructor.apply(256);
|
|
this.blockMap[block] = blockData;
|
|
blockData[offset] = value;
|
|
return null;
|
|
}
|
|
T previous = blockData[offset];
|
|
blockData[offset] = value;
|
|
return previous;
|
|
}
|
|
|
|
public T computeIfAbsent(int codepoint, IntFunction<T> mapper) {
|
|
int block = codepoint >> 8;
|
|
T[] blockData = this.blockMap[block];
|
|
int offset = codepoint & 0xFF;
|
|
T current = blockData[offset];
|
|
if (current != null) {
|
|
return current;
|
|
}
|
|
if (blockData == this.empty) {
|
|
blockData = this.blockConstructor.apply(256);
|
|
this.blockMap[block] = blockData;
|
|
}
|
|
T result = mapper.apply(codepoint);
|
|
blockData[offset] = result;
|
|
return result;
|
|
}
|
|
|
|
public @Nullable T remove(int codepoint) {
|
|
int block = codepoint >> 8;
|
|
int offset = codepoint & 0xFF;
|
|
T[] blockData = this.blockMap[block];
|
|
if (blockData == this.empty) {
|
|
return null;
|
|
}
|
|
T previous = blockData[offset];
|
|
blockData[offset] = null;
|
|
return previous;
|
|
}
|
|
|
|
public void forEach(Output<T> output) {
|
|
for (int block = 0; block < this.blockMap.length; ++block) {
|
|
T[] blockData = this.blockMap[block];
|
|
if (blockData == this.empty) continue;
|
|
for (int offset = 0; offset < blockData.length; ++offset) {
|
|
T value = blockData[offset];
|
|
if (value == null) continue;
|
|
int codepoint = block << 8 | offset;
|
|
output.accept(codepoint, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
public IntSet keySet() {
|
|
IntOpenHashSet result = new IntOpenHashSet();
|
|
this.forEach((codepoint, value) -> result.add(codepoint));
|
|
return result;
|
|
}
|
|
|
|
@FunctionalInterface
|
|
public static interface Output<T> {
|
|
public void accept(int var1, T var2);
|
|
}
|
|
}
|
|
|