Removed requirement for AttributesUpdater to be stateful

Used a clever trick on StatList.StatIterator, where read stats can be pushed onto the list starting from the front. The result is a sorted list not containing elements which were not added back.
This commit is contained in:
Collin Smith
2020-09-07 01:15:55 -07:00
parent f121cc8a7a
commit aadc9d2de8
2 changed files with 22 additions and 11 deletions

View File

@ -10,7 +10,6 @@ public final class AttributesUpdater {
private static final Logger log = LogManager.getLogger(AttributesUpdater.class);
private final UpdateSequence SEQUENCER = new UpdateSequence(this);
private final StatList cache = StatList.obtainLarge(); // easier than implementing StatList#remove
public UpdateSequence update(final Attributes attrs, final CharStats.Entry charStats) {
return update(attrs, attrs, charStats);
@ -76,34 +75,31 @@ public final class AttributesUpdater {
final StatListGetter rem,
final Attributes opBase,
final CharStats.Entry charStats) {
// should pass values from rem to agg if applicable
final StatListBuilder cache = this.cache.clear().buildList();
for (StatGetter stat : rem) {
for (final StatList.StatIterator it = rem.statIterator(); it.hasNext();) {
final StatGetter stat = it.next();
final ItemStatCost.Entry entry = stat.entry();
try {
MDC.put("applyStat", stat.id());
final int op = entry.op;
if (op > 0) {
if (log.traceEnabled()) log.trace("Applying stat({}) op({})", stat.debugString(), op);
op(agg, cache, opBase, charStats, stat);
op(agg, it, opBase, charStats, stat);
} else if (base.contains(stat)) {
if (log.traceEnabled()) log.trace("Aggregating stat({})", stat.debugString());
agg.add(stat);
} else {
if (log.traceEnabled()) log.trace("Propagating stat({})", stat.debugString());
cache.add(stat);
it.pushback();
}
} finally {
MDC.remove("applyStat");
}
}
rem.parent().setAll(cache.build());
}
static void op(
final StatListBuilder agg,
final StatListBuilder rem,
final StatList.StatIterator it,
final Attributes opBase,
final CharStats.Entry charStats,
final StatGetter stat) {
@ -133,7 +129,7 @@ public final class AttributesUpdater {
}
if (ops == 0) {
rem.add(stat);
it.pushback();
} else if (ops < expectedOps) {
log.warn("{} stats were not op'd", ops);
}

View File

@ -736,11 +736,14 @@ public final class StatList {
public final class StatIterator implements Iterator<StatGetter> {
final StatGetter stat = new StatGetter(StatList.this);
int list; /** used for {@link #pushback} */
int head; /** used for {@link #pushback} */
int index;
int endIndex;
StatIterator reset(final int list) {
index = startingOffset(list);
this.list = list;
head = index = startingOffset(list);
endIndex = endingOffset(list);
return this;
}
@ -755,6 +758,18 @@ public final class StatList {
return stat.update(index++);
}
/**
* Recycles the previously read stat by re-adding it onto a new list being
* formed at the start of this list while iteration is occurring. This
* method effectively breaks the old list and shrinks it to a subset of
* entries.
*/
void pushback() {
assert head < index : "head(" + head + ") cannot pass index(" + index + ")";
StatList.this.set(head++, stat.id(), stat.param(), stat.value(), stat.entry());
setEndingOffset(list, head);
}
@Override
public void remove() {
throw new UnsupportedOperationException();