in uimaj-core/src/main/java/org/apache/uima/cas/impl/BinaryCasSerDes6.java [1873:2128]
public void deserializeAfterVersion(DataInputStream istream, boolean aIsDelta,
AllowPreexistingFS aAllowPreexistingFS) throws IOException {
allowPreexistingFS = aAllowPreexistingFS;
if (aAllowPreexistingFS == AllowPreexistingFS.ignore) {
throw new UnsupportedOperationException("AllowPreexistingFS.ignore not an allowed setting");
}
deserIn = istream;
isDelta = isReadingDelta = aIsDelta;
setupReadStreams();
/************************************************
* Read in the common string(s)
************************************************/
int lenCmnStrs = readVnumber(strChars_dis);
readCommonString = new String[lenCmnStrs];
for (int i = 0; i < lenCmnStrs; i++) {
readCommonString[i] = DataIO.readUTFv(strChars_dis);
}
only1CommonString = lenCmnStrs == 1;
/***************************
* Prepare to walk main heap
***************************/
int nbrNewFSsInTarget = readVnumber(control_dis);
// is nbr of FSs serialized (excluding mods) in v3
// is totalMappedHeapSize in v2
int totalMappedHeapSize = bcsd.isBeforeV3 ? nbrNewFSsInTarget : -1;
if (bcsd.isBeforeV3) {
nbrNewFSsInTarget = -1; // for safety
}
// stringTableOffset = isReadingDelta ? (stringHeapObj.getSize() - 1) : 0;
nextFsId = isReadingDelta ? cas.peekNextFsId() : 0;
// if (!isReadingDelta) {
// heapObj.reinitSizeOnly(1);
// heap = heapObj.heap;
// }
Arrays.fill(prevHeapInstanceWithIntValues, null);
prevFsWithLongValues.clear();
if (nextFsId == 0) {
nextFsId = 1; // slot 0 not serialized, it's null / 0
}
// @formatter:off
// For Delta CAS,
// Reuse previously computed map of addr <--> seq for existing FSs below mark line
// map of seq(this CAS) <--> seq(incoming)
// that accounts for type code mismatch using typeMapper
// note: rest of maps computed incrementally as we deserialize
// Two possibilities: The CAS has a type, but the incoming is missing that type (services)
// The incoming has a type, but the CAS is missing it - (deser from file)
// Below the merge line: only the 1st is possible
// Above the merge line: only the 2nd is possible
// @formatter:on
if (isReadingDelta) {
if (!reuseInfoProvided) {
throw new IllegalStateException("Reading Delta into CAS not serialized from");
}
}
fixupsNeeded.clear();
// preventFsGc.clear();
// these two values are used when incrementing to the next before v3 heap addr
TypeImpl tgtType;
lastArrayLength = 0;
/**********************************************************
* Read in new FSs being deserialized and add them to heap
**********************************************************/
// @formatter:off
// currentFsId is ID of next to be deserialized FS
// only incremented when something is "stored", not skipped
// nextFsAddr only used for loop termination , pre v3
// could be gt than fsId, because some FSs are "skipped" in deserialization
// @formatter:n
// currentFsId only used in error message
for (int currentFsId = nextFsId, nbrFSs = 0, nextFsAddr = 1; bcsd.isBeforeV3
? nextFsAddr < totalMappedHeapSize
: nbrFSs < nbrNewFSsInTarget; nbrFSs++, nextFsAddr += bcsd.isBeforeV3
? tgtType.getFsSpaceReq(lastArrayLength)
: 0) {
final int tgtTypeCode = readVnumber(typeCode_dis); // get type code
// final int adjTgtTypeCode = tgtTypeCode + ((this.bcsd.isBeforeV3 && tgtTypeCode >
// TypeSystemConstants.lastBuiltinV2TypeCode)
// ? TypeSystemConstants.numberOfNewBuiltInsSinceV2
// : 0);
tgtType = (isTypeMapping ? tgtTs : srcTs).getTypeForCode(tgtTypeCode);
if (tgtType == null) {
/**
* Deserializing Compressed Form 6, a type code: {0} has no corresponding type. currentFsId:
* {1} nbrFSs: {2} nextFsAddr: {3}
*/
throw new CASRuntimeException(CASRuntimeException.DESER_FORM_6_BAD_TYPE_CODE, tgtTypeCode,
currentFsId, nbrFSs, nextFsAddr);
}
final TypeImpl srcType = isTypeMapping ? typeMapper.mapTypeCodeTgt2Src(tgtTypeCode) : tgtType;
final boolean storeIt = srcType != null;
// A receiving client from a service always
// has a superset of the service's types due to type merging so this
// won't happen for that use case. But
// a deserialize-from-file could hit this if the receiving type system
// deleted a type.
// The strategy for deserializing heap refs depends on finding
// the prev value for that type. This must be done in the context
// of the sending CAS's type system
// SlotKind slotKind = srcType.slotKind;
if (storeIt) {
// we can skip the cache for prev values if the value will not be stored.
// typeImpl = tgtType;
initPrevIntValue(tgtType);
}
// typeInfo = storeIt ? srcTypeInfo : tgtTypeInfo; // if !storeIt, then srcTypeInfo is null.
// fsStartIndexes.addSrcAddrForTgt(currentFsId, storeIt);
if (TRACE_DES) {
System.out.format("Des: fsnbr %,4d fsid %,4d adjTgtTypeCode: %,3d %13s srcTypeCode: %s%n",
nbrFSs, cas.getLastUsedFsId() + 1, tgtTypeCode, tgtType.getShortName(),
null == srcType ? "<null>" : Integer.toString(srcType.getCode()));
}
if (tgtType.isArray()) {
readArray(storeIt, srcType, tgtType);
} else {
// @formatter:off
/**
* is not array, handle features
* If storing the value, create the FS unless it's a Sofa or a subtype of AnnotationBase
* Those are deferred until the slots are known, because they're needed
* as part of the creation of the FS due to final values.
*/
// @formatter:on
if (storeIt) {
if (!srcTs.annotBaseType.subsumes(srcType) && // defer subtypes of AnnotationBase
srcTs.sofaType != srcType) { // defer sofa types
createCurrentFs(srcType, cas);
} else {
currentFs = null;
singleFsDefer.clear();
sofaRef = null;
sofaNum = -1;
sofaName = null;
sofaMimeType = null;
}
}
// is normal type with slots, not an array
if (isTypeMapping && storeIt) {
for (FeatureImpl tgtFeat : tgtType.getFeatureImpls()) {
final FeatureImpl srcFeat = typeMapper.getSrcFeature(tgtType, tgtFeat);
readByKind(currentFs, tgtFeat, srcFeat, storeIt, tgtType);
}
} else {
for (FeatureImpl tgtFeat : tgtType.getFeatureImpls()) {
readByKind(currentFs, tgtFeat, tgtFeat, storeIt, tgtType);
}
}
if (currentFs == null) {
// @formatter:off
/**
* Create single deferred FS
* Either: Sofa (has final fields) or
* Subtype of AnnotationBase - needs to be in the right view
*
* For the latter, handle document annotation specially
*/
// @formatter:on
if (srcTs.sofaType == srcType) {
if (cas.hasView(sofaName)) {
// sofa was already created, by an annotationBase subtype deserialized prior to this
// one
currentFs = (TOP) cas.getView(sofaName).getSofa();
} else {
currentFs = cas.createSofa(sofaNum, sofaName, sofaMimeType);
}
} else {
CASImpl view = null == sofaRef ? cas.getInitialView() // https://issues.apache.org/jira/browse/UIMA-5588
: (CASImpl) cas.getView(sofaRef);
// if (srcType.getCode() == TypeSystemConstants.docTypeCode) {
// currentFs = view.getDocumentAnnotation(); // creates the document annotation if it
// doesn't exist
//
// // we could remove this from the indexes until deserialization is over, but then,
// other calls to getDocumentAnnotation
// // would end up creating additional instances
// } else {
createCurrentFs(srcType, view);
// }
}
if (srcType.getCode() == TypeSystemConstants.docTypeCode) {
boolean wasRemoved = cas.removeFromCorruptableIndexAnyView(currentFs,
cas.getAddbackSingle());
for (Runnable r : singleFsDefer) {
r.run();
}
cas.addbackSingleIfWasRemoved(wasRemoved, currentFs);
} else {
for (Runnable r : singleFsDefer) {
r.run();
}
}
} // end of handling deferred current fs
} // of not-an-array
// if (storeIt) {
// prevFsByType[srcType.getCode()] = currentFs; // make this one the "prev" one for subsequent
// testing
// //debug
// assert(currentFs._id == currentFsId);
// }
// todo need to incr src heap by amt filtered (in case some slots missing,
// need to incr tgt (for checking end) by unfiltered amount
// need to fixup final heap to account for skipped slots
// need to have read skip slots not present in src
// targetHeapUsed += incrToNextFs(heap, currentFsId, tgtTypeInfo); // typeInfo is target type
// info
fsStartIndexes.addSrcFsForTgt(currentFs, storeIt);
currentFsId += storeIt ? cas.lastV2IdIncr() : 0;
} // end of for loop over items in main heap
for (Runnable r : fixupsNeeded) {
r.run();
}
for (Runnable r : uimaSerializableFixups) {
r.run();
}
// process the index information
readIndexedFeatureStructures();
// for delta, process below-the-line updates
if (isReadingDelta) {
new ReadModifiedFSs().readModifiedFSs();
}
// preventFsGc.clear();
closeDataInputs();
// System.out.format("Deserialize took %,d ms%n", System.currentTimeMillis() - startTime1);
}