shz.core.st.tst.ConcurrentZTST Maven / Gradle / Ivy
package shz.core.st.tst;
import shz.core.queue.a.LArrayQueue;
import shz.core.queue.a.ZArrayQueue;
import shz.core.stack.l.LLinkedStack;
import java.util.function.Predicate;
/**
* 值为boolean类型的TST
*
* 8+48*n(n为元素个数)
*
* B=24+48*n
*/
public class ConcurrentZTST extends ConcurrentTST {
private static final long serialVersionUID = -5977852703607531704L;
/**
* 1+27+对齐填充=32
*
* B=48
*/
protected static final class Node extends ConcurrentTST.Node {
private static final long serialVersionUID = -5172268036588644429L;
public boolean val;
public Node(char c) {
super(c);
}
}
public static ConcurrentZTST of() {
return new ConcurrentZTST();
}
public final void put(char[] a, boolean val) {
acceptWrite(() -> root = put(root, a, val, 0));
}
protected final Node put(Node x, char[] a, boolean val, int d) {
if (x == null) x = new Node(a[d]);
if (a[d] < x.c) x.left = put(x.left, a, val, d);
else if (a[d] > x.c) x.right = put(x.right, a, val, d);
else if (d < a.length - 1) x.mid = put(x.mid, a, val, d + 1);
else {
x.val = val;
x.leaf = true;
}
return x;
}
public final Boolean get(char[] a, int n) {
return applyRead(() -> {
Node x = get(root, a, n);
return x == null || !x.leaf ? null : x.val;
});
}
public final Boolean get(char[] a) {
return get(a, a.length);
}
public final ZArrayQueue getAll() {
return applyRead(() -> get(root, false));
}
protected final ZArrayQueue get(Node x, boolean prefix) {
ZArrayQueue queue = ZArrayQueue.of();
if (x != null) {
LLinkedStack stack = LLinkedStack.of();
if (x.mid != null) stack.push(x.mid);
if (!prefix) {
if (x.left != null) stack.push(x.left);
if (x.right != null) stack.push(x.right);
}
while (!stack.isEmpty()) {
Node pop = stack.pop();
if (pop.leaf) queue.offer(pop.val);
push(stack, pop);
}
}
return queue;
}
private void push(LLinkedStack stack, Node x) {
if (x.left != null) stack.push(x.left);
if (x.mid != null) stack.push(x.mid);
if (x.right != null) stack.push(x.right);
}
public final ZArrayQueue getByPrefix(char[] prefix) {
return applyRead(() -> get(get(root, prefix, 0), true));
}
public final LArrayQueue getChars(Boolean predicate, int limit) {
return applyRead(() -> getChars0(x -> predicate == null || predicate == x.val, limit));
}
public final boolean computeIfAbsent(char[] a, Predicate func) {
Boolean oldVal = get(a);
if (oldVal != null) return oldVal;
return applyWrite(() -> {
Node x = get(root, a, 0);
if (x != null && x.leaf) return x.val;
boolean val = func.test(a);
root = put(root, a, val, 0);
return val;
});
}
}