shz.core.st.triest.ConcurrentTrieST Maven / Gradle / Ivy
package shz.core.st.triest;
import shz.core.tag.cxx.CLTag;
import shz.core.queue.a.LArrayQueue;
import shz.core.lock.ReadWriteLockHolder;
import shz.core.queue.a.CArrayQueue;
import shz.core.stack.l.LLinkedStack;
import shz.core.stack.a.ZArrayStack;
import shz.core.structure.CharIndex;
import java.io.Serializable;
import java.util.function.Predicate;
/**
* 基于单词查找树的符号表
*
* 在单词查找树中查找一个键或是插入一个键时,访问数组的次数最多为键的长度加1
*
* 字母表的大小为R,在一棵由N个随机键构造的单词查找树中,未命中查找平均所需检查的结点数量为~logRN
*
* 一棵单词查找树中的链接总数在RN到RNw之间,其中w为键的平均长度
*/
public abstract class ConcurrentTrieST> extends ReadWriteLockHolder implements Serializable {
private static final long serialVersionUID = -5032025392473348345L;
protected static abstract class Node> implements Serializable {
private static final long serialVersionUID = 7929990200196535868L;
public boolean leaf;
public T[] next;
protected Node(T[] next) {
this.next = next;
}
}
protected final CharIndex charIndex;
protected final int len;
protected T root;
protected ConcurrentTrieST(char[] chars) {
charIndex = CharIndex.of(chars);
len = chars.length;
}
protected final T get(T x, char[] a, int d) {
for (int i = 0; i < d; ++i) {
x = x.next[charIndex.idx(a[i])];
if (x == null) break;
}
return x;
}
public final void delete(char[] a) {
acceptWrite(() -> {
T p = get(root, a, a.length - 1);
if (p == null) return;
int i = charIndex.idx(a[a.length - 1]);
T x = p.next[i];
if (x == null) return;
x.leaf = false;
if (x.next == null) p.next[i] = null;
});
}
protected final LArrayQueue getChars0(Predicate super T> predicate, int limit) {
LArrayQueue result = LArrayQueue.of();
CArrayQueue key = CArrayQueue.of();
LLinkedStack> stack = LLinkedStack.of();
ZArrayStack remove = ZArrayStack.of();
push(stack, root, remove);
while (stack.size() > 0) {
if (limit > 0 && result.size() >= limit) break;
CLTag pop = stack.pop();
remove.pop();
key.offer(pop.tag);
if (pop.data.leaf && predicate.test(pop.data)) result.offer(key.toArray());
if (!push(stack, pop.data, remove)) {
key.removeTail();
while (remove.size() > 1 && remove.peek()) {
remove.pop();
key.removeTail();
}
}
}
return result;
}
private boolean push(LLinkedStack> stack, T x, ZArrayStack remove) {
if (x.next == null) return false;
remove.push(true);
boolean flag = false;
for (int i = 0; i < len; ++i) {
if (x.next[i] != null) {
flag = true;
stack.push(new CLTag<>(charIndex.chars[i], x.next[i]));
remove.push(false);
}
}
if (!flag) remove.pop();
return flag;
}
}