blob: 2cd9d93a45c512f800a4afe014cfa054d8de8db3 [file] [log] [blame]
/*
* 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.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.uima.internal.util.Int2ObjHashMap;
import org.apache.uima.internal.util.Misc;
import org.apache.uima.internal.util.Obj2IntIdentityHashMap;
import org.apache.uima.jcas.cas.TOP;
/**
* Common de/serialization for plain binary and compressed binary form 4
* which both used to walk the cas using the sequential, incrementing id approach
*
* Lifecycle:
* There is 0/1 instance per CAS, representing the FSs at some point in time in that CAS.
*
* Creation:
* serialization (for delta serialization,
* the csds made when deserialization was done is reused, if available
* Updates cannot add to the reachables).
* non-delta deserialization
* delta deserialization uses previous one
*
* Reset:
* CAS Reset
* API call (for optimization - used after all delta deserializations into a particular CAS are complete.
*
* Logical constraints:
* - delta de/serialization must use an existing version of this,
* -- set during a previous non-delta de/serialization
* -- or created just in time via a scan of the cas
*/
public class CommonSerDesSequential {
public static final boolean TRACE_SETUP = false;
/**
* a map from a fs to its addr in the modeled heap, == v2 style addr
*
* created during serialization and deserialization
* used during serialization to create addr info for index info serialization
*
* For delta, the addr is the modeled addr for the full CAS including both above and below the line.
*/
final Obj2IntIdentityHashMap<TOP> fs2addr = new Obj2IntIdentityHashMap<>(TOP.class, TOP._singleton);
/**
* a map from the modelled (v2 style) FS addr to the V3 FS
* created when serializing (non-delta), deserializing (non-delta)
* augmented when deserializing(delta)
* used when deserializing (delta and non-delta)
* retained after deserializing (in case of subsequent delta (multiple) deserializations being combined)
*
* For delta, the addr is the modeled addr for the full CAS including both above and below the line.
*
*/
final Int2ObjHashMap<TOP, TOP> addr2fs = new Int2ObjHashMap<>(TOP.class);
/**
* The FSs in this list are not necessarily sequential, but is in ascending (simulated heap) order,
* needed for V2 compatibility of serialized forms.
* This is populated either during deserialization, or for serialization, from indexed + reachable.
*
* Before accessing this, any pending items must be merged (sorting done lazily)
*/
final private List<TOP> sortedFSs = new ArrayList<>(); // holds the FSs sorted by id
final private List<TOP> pending = new ArrayList<>(); // batches up FSs that need to be inserted into sortedFSs
/**
* The associated CAS
*/
final private CASImpl baseCas;
/**
* The first free (available) simulated heap addr, also the last addr + length of that
*/
private int heapEnd; // == the last addr + length of that
public CommonSerDesSequential(CASImpl cas) {
this.baseCas = cas.getBaseCAS();
}
public boolean isEmpty() {
return sortedFSs.isEmpty() && pending.isEmpty();
}
/**
* Must call in fs sorted order
* @param fs
*/
void addFS(TOP fs, int addr) {
addFS1(fs, addr);
sortedFSs.add(fs);
}
void addFS1(TOP fs, int addr) {
fs2addr.put(fs, addr);
addr2fs.put(addr, fs);
}
/**
* For out of order calls
* @param fs
*/
void addFSunordered(TOP fs, int addr) {
addFS1(fs, addr);
pending.add(fs);
}
void clear() {
sortedFSs.clear();
fs2addr.clear();
addr2fs.clear();
pending.clear();
heapEnd = 0;
}
/**
* Scan all indexed + reachable FSs, sorted, and
* - create two maps from those to/from the int offsets in the simulated main heap
* - add all the (filtered - above the mark) FSs to the sortedFSs
* - set the heapEnd
* @param mark null or the mark
* @param fromAddr often 1 but sometimes the mark next fsid
* @return all (not filtered) FSs sorted
*/
List<TOP> setup(MarkerImpl mark, int fromAddr) {
if (mark == null) {
clear();
}
// local value as "final" to permit use in lambda below
int nextAddr = fromAddr;
if (TRACE_SETUP) System.out.println("Cmn serDes sequential setup called by: " + Misc.getCaller());
List<TOP> all = new AllFSs(baseCas).getAllFSsAllViews_sofas_reachable().getAllFSsSorted();
List<TOP> filtered = CASImpl.filterAboveMark(all, mark);
for (TOP fs : filtered) {
addFS1(fs, nextAddr); // doesn't update sortedFSs, that will be done below in batch
if (TRACE_SETUP) {
System.out.format("Cmn serDes sequential setup: add FS id: %,4d addr: %,5d type: %s%n",
Integer.valueOf(fs._id),
Integer.valueOf(nextAddr),
fs._getTypeImpl().getShortName());
}
nextAddr += BinaryCasSerDes.getFsSpaceReq(fs, fs._getTypeImpl());
}
sortedFSs.addAll(filtered);
heapEnd = nextAddr;
return all;
// if (heapEnd == 0) {
// System.out.println("debug");
// }
}
// /**
// * called to augment an existing csds with information on FSs added after the mark was set
// * @param mark -
// */
// void setup() { setup(1, 1); }
// void walkSeqFSs(Consumer_T_withIOException<TOP> action) throws IOException {
// for (TOP fs : sortedFSs) {
// action.accept(fs);
// }
// }
//
/**
* @return sorted FSs above mark if mark set, otherwise all, sorted
*/
List<TOP> getSortedFSs() {
if (pending.size() != 0) {
merge();
}
return sortedFSs;
}
int getHeapEnd() { return heapEnd; }
void setHeapEnd(int heapEnd) {
this.heapEnd = heapEnd;
}
private void merge() {
Collections.sort(pending, FeatureStructureImplC::compare);
sortedFSs.addAll(pending);
pending.clear();
Collections.sort(sortedFSs, FeatureStructureImplC::compare);
}
}