package de.jpaw.bonaparte.core;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import de.jpaw.bonaparte.pojos.meta.ObjectReference;
/** A composer which convertes the data into an immutable ByteArray.
* Due to the possible self-similarity, child objects can participate in the parent's serialized form.
*
* @author Michael Bischoff
*
*/
public class ByteArrayComposerWithCache extends ByteArrayComposer {
static public class OffsetInfo {
// BonaPortable object;
int start;
int length;
int minReferencedObject;
}
private OffsetInfo current = null;
private Integer currentObjectIndex = -1;
private List<OffsetInfo> mem = new ArrayList<OffsetInfo>(200);
private Stack<Integer> backtrack = new Stack<Integer>(); // nesting depth. The current
public ByteArrayComposerWithCache() {
super();
}
public ByteArrayComposerWithCache(ObjectReuseStrategy reuseStrategy) {
super(reuseStrategy);
}
@Override
public void writeRecord(BonaCustom o) {
super.reset();
mem.clear();
backtrack.clear();
current = null;
currentObjectIndex = -1;
startRecord();
addField(StaticMeta.OUTER_BONAPORTABLE, o);
terminateRecord();
backtrack.clear();
}
@Override
public void startObject(ObjectReference di, BonaCustom obj) {
backtrack.push(currentObjectIndex);
currentObjectIndex = getNumberOfObjectsSerialized()-1;
OffsetInfo current = new OffsetInfo();
current.start = getLength();
current.minReferencedObject = currentObjectIndex;
mem.add(current);
super.startObject(di, obj);
}
@Override
public void terminateObject(ObjectReference di, BonaCustom obj) {
super.terminateObject(di, obj);
current.length = getLength() - current.start;
// descend to the previous one. Compute referenced objects index
currentObjectIndex = backtrack.pop();
int tmp = current.minReferencedObject;
current = mem.get(currentObjectIndex);
if (tmp < current.minReferencedObject)
current.minReferencedObject = tmp;
}
@Override
protected void notifyReuse(int referencedIndex) {
if (referencedIndex < current.minReferencedObject)
current.minReferencedObject = referencedIndex;
}
}