/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.uima.cas.impl;
import java.util.HashMap;
import java.util.Map;
import org.apache.uima.internal.util.IntVector;
import org.apache.uima.internal.util.rb_trees.Int2IntRBT;
import org.apache.uima.internal.util.rb_trees.IntRedBlackTree;
/**
* Manage the conversion of Items (FSrefs) to relative sequential index number, and back
* Manage the difference in two type systems
* both size of the FSs and
* handling excluded types
*
* During serialization, these maps are constructed before serialization.
* During deserialization, these maps are constructed while things are being deserialized, and
* then used in a "fixup" call at the end.
* This allows for forward references.
*
* For delta deserialization, the base part of these maps (for below-the-line) is
* constructed by scanning up to the mark.
*/
public class CasSeqAddrMaps {
/**
* map from a target FS sequence nbr to a source address.
* value is 0 if the target instance doesn't exist in the source
* (this doesn't occur for receiving remote CASes back
* (because src ts is always a superset of tgt ts),
* but can occur while deserializing from Disk.
*
* First seq number is 0.
*/
final private IntVector tgtSeq2SrcAddr;
// /**
// * (Not Used, currently)
// * map from a source seq number to a target seq number.
// * value is -1 if the source FS is not in the target
// */
// final private IntVector srcSeq2TgtSeq = new IntVector();
// /**
// * (Not Used, currently)
// * map from a target seq number to a target address.
// */
// final private IntVector tgtSeq2TgtAddr = new IntVector(); // used for comparing
/**
* map from source address to target sequence number.
* if source is not in target, value = -1;
*/
final private Int2IntRBT srcAddr2TgtSeq;
/**
* info needed to do a map from target aux heap to source aux heap
* Used when applying delta modifications "below the line" to these elements
* Assumes any target ts element exists in source ts, so target is a subset
* (due to type merging, when delta cas is used to return updates from service)
*/
/**
* Indexed by AuxHeap kind:
*/
// final private List<List<AuxSkip>> skips = new ArrayList<List<AuxSkip>>(AuxHeap.values().length);
//
// { // initialize instance block
// for (int i = 0; i < skips.size(); i++) {
// skips.add(new ArrayList<AuxSkip>());
// }
// }
private int nextTgt = 0;
public CasSeqAddrMaps() {
// this call makes the first real seq number == 1.
// seq 0 refers to the NULL fs value at heap location 0.
this.tgtSeq2SrcAddr = new IntVector();
this.srcAddr2TgtSeq = new Int2IntRBT();
addItemAddr(0, 0, true);
}
public CasSeqAddrMaps(IntVector tgtSeq2SrcAddr, Int2IntRBT srcAddr2TgtSeq) {
this.tgtSeq2SrcAddr = tgtSeq2SrcAddr;
this.srcAddr2TgtSeq = srcAddr2TgtSeq;
}
/**
* Add a new FS address - done during prescan of source
* Must call in heap scan order
* @param addr
* @param inTarget true if this type is in the target
*/
public void addItemAddr(int srcAddr, int tgtAddr, boolean inTarget) {
if (inTarget) {
tgtSeq2SrcAddr.add(srcAddr);
// tgtSeq2TgtAddr.add(tgtAddr);
}
srcAddr2TgtSeq.put(srcAddr, inTarget ? nextTgt++ : -1);
// // debug
// if (srcAddr < 525) {
// System.out.format("Adding to srcAddr2TgtSeq: addr: %d tgtSeq: %d, type=%s%n", srcAddr, inTarget ? i : 0,
// );
// }
// srcSeq2TgtSeq.add(inTarget ? nextTgt++ : 0);
}
// /**
// * record skipped entries in an Aux heap
// * @param auxHeap which heap this is for
// * @param srcSkipIndex the index of the first skipped slot in the src heap
// * @param srcSkipSize the number of entries skipped
// */
// public void recordSkippedAuxHeap(AuxHeap auxHeap, int srcSkipIndex, int srcSkipSize) {
// skips.get(auxHeap.ordinal()).add(new AuxSkip(srcSkipIndex, srcSkipSize));
// }
/**
* Called during deserialize to incrementally add
* @param srcAddr
* @param inSrc
*/
public void addSrcAddrForTgt(int srcAddr, boolean inSrc) {
if (inSrc) {
srcAddr2TgtSeq.put(srcAddr, nextTgt);
// srcSeq2TgtSeq.add(nextTgt);
tgtSeq2SrcAddr.add(srcAddr);
} else {
tgtSeq2SrcAddr.add(0);
}
// tgtSeq2TgtAddr.add(-1); // not used I hope - need to check TODO
nextTgt++;
}
/**
*
* @param seq
* @return 0 means target seq doesn't exist in source CAS
*/
public int getSrcAddrFromTgtSeq(int seq) {
return tgtSeq2SrcAddr.get(seq);
}
// public int getTgtAddrFromTgtSeq(int seq) {
// return tgtSeq2TgtAddr.get(seq);
// }
// public int getMappedItemAddr(int index) {
// if (null == typeMapper) {
// return tgtIndexToSeq.get(index);
// } else {
// return tgtItemIndexToAddr.get(index);
// }
// }
/**
* returns -1 if src addr not in target seq
*/
public int getTgtSeqFromSrcAddr(int itemAddr) {
// System.out.println(" " + itemAddr);
return srcAddr2TgtSeq.getMostlyClose(itemAddr);
}
public int getNumberSrcFss() {
return srcAddr2TgtSeq.size();
}
CasSeqAddrMaps copy() {
CasSeqAddrMaps c = new CasSeqAddrMaps(tgtSeq2SrcAddr.copy(), srcAddr2TgtSeq.copy());
c.nextTgt = nextTgt;
return c;
}
}