feat: 优化请求数量记录栈

fix: 修复计算过程中会出现数据包过大的问题
This commit is contained in:
C-H716 2025-10-30 20:58:52 +08:00
parent fe626c7a82
commit 330b80dfec
2 changed files with 86 additions and 19 deletions

View File

@ -40,6 +40,23 @@ public class ScaledProcessingPattern implements IPatternDetails {
return original;
}
@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (o == null) return false;
// 比较另一个缩放样板比较其 original 字段
if (o instanceof ScaledProcessingPattern sp) {
return this.original.equals(sp.getOriginal());
}
// 委托给原始样板的 equals比如遇到原始的 AEProcessingPattern
return this.original.equals(o);
}
@Override
public final int hashCode() {
return original.hashCode();
}
@Override
public AEItemKey getDefinition() {
return definition;

View File

@ -1,44 +1,94 @@
package com.extendedae_plus.util.smartDoubling;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* Thread-local stack holder for requested amounts to support nested requests.
* 请求数量线程本地栈用于支持嵌套请求避免不同请求间的干扰
* <p>
* 每个线程都有自己独立的 LongStack不会与其他线程共享
* 使用 long[] 而非 Long 对象避免装箱开销与 GC 压力
*/
public final class RequestedAmountHolder {
private static final ThreadLocal<Deque<Long>> HOLDER = ThreadLocal.withInitial(ArrayDeque::new);
// 每个线程独立持有一个 LongStack 实例
private static final ThreadLocal<LongStack> HOLDER = ThreadLocal.withInitial(LongStack::new);
// 栈深度上限防止异常递归导致 OOM
private static final int MAX_DEPTH = 16777216;
private RequestedAmountHolder() {
}
/**
* Push a requested amount onto the thread-local stack.
* 将一个请求数量压入当前线程的栈顶
*
* @param v 要压入的请求值
*/
public static void push(long v) {
Deque<Long> dq = HOLDER.get();
dq.push(v);
HOLDER.get().push(v);
}
/**
* Pop the top value from the thread-local stack. Safe if empty.
* 从当前线程的栈顶弹出一个值
* 若栈为空则安全忽略
*/
public static void pop() {
Deque<Long> dq = HOLDER.get();
if (dq.isEmpty()) {
return;
}
dq.pop();
HOLDER.get().pop();
}
/**
* Peek the current requested amount or return 0 if none.
* 获取当前线程栈顶的请求数量
* 若栈为空则返回 0
*
* @return 当前请求数量或 0
*/
public static long get() {
Deque<Long> dq = HOLDER.get();
Long v = dq.peek();
return v == null ? 0L : v;
return HOLDER.get().peek();
}
}
/**
* 清空当前线程的栈
* 若栈过大会在清空时重置容量防止占用过多内存
*/
public static void clear() {
HOLDER.get().clear();
}
/**
* 一个轻量级的 long 基础类型栈实现
* <p>
* - 无装箱开销 Long 节省内存避免 GC 压力
* - 每个线程独占实例无需同步
* - 自动扩容机制容量不够时按倍数增长
*/
private static final class LongStack {
private long[] data = new long[16]; // 初始容量
private int size = 0; // 当前栈深
void push(long v) {
if (size == data.length) {
long[] n = new long[data.length * 2]; // 扩容为原容量的 2
System.arraycopy(data, 0, n, 0, data.length);
data = n;
}
data[size++] = v;
}
void pop() {
if (size > 0) size--;
}
long peek() {
return size == 0 ? 0L : data[size - 1];
}
int depth() {
return size;
}
void clear() {
// 若数组容量过大则在清空时重置为初始容量
if (data.length > 1024) {
data = new long[16];
}
size = 0;
}
}
}