CompoundOperationMap.java
package org.mozilla.javascript;
import java.util.Iterator;
/**
* This class represents a compound operation performed on a non-thread safe map. As such it does
* the minimum work possible and does not enforce locking, instead it simply records whether the map
* has been mutated as part of the operation to allow the underlying map to delegate operations as
* required.
*/
public class CompoundOperationMap implements SlotMap, AutoCloseable {
protected final SlotMapOwner owner;
protected SlotMap map;
boolean touched = false;
public CompoundOperationMap(SlotMapOwner owner) {
this.owner = owner;
this.map = owner.getMap();
}
protected void updateMap(boolean resetTouched) {
if (touched) {
map = owner.getMap();
touched = resetTouched ? false : touched;
}
}
public boolean isTouched() {
return touched;
}
@Override
public void add(SlotMapOwner owner, Slot newSlot) {
map.add(owner, newSlot);
touched = true;
}
@Override
public <S extends Slot> S compute(
SlotMapOwner owner, Object key, int index, SlotComputer<S> compute) {
updateMap(true);
var res = map.compute(owner, this, key, index, compute);
touched = true;
return res;
}
@Override
public <S extends Slot> S compute(
SlotMapOwner owner,
CompoundOperationMap compoundOp,
Object key,
int index,
SlotComputer<S> compute) {
assert (compoundOp == this);
updateMap(true);
var res = map.compute(owner, this, key, index, compute);
touched = true;
return res;
}
@Override
public int dirtySize() {
updateMap(false);
return map.dirtySize();
}
@Override
public boolean isEmpty() {
updateMap(false);
return map.isEmpty();
}
@Override
public Slot modify(SlotMapOwner owner, Object key, int index, int attributes) {
updateMap(true);
var res = map.modify(owner, key, index, attributes);
touched = true;
return res;
}
@Override
public Slot query(Object key, int index) {
updateMap(false);
return map.query(key, index);
}
@Override
public int size() {
updateMap(false);
return map.size();
}
@Override
public Iterator<Slot> iterator() {
updateMap(false);
return map.iterator();
}
@Override
public void close() {
// This version doesn't need to do anything on clean up.
}
}