/* | |
* 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.aae.controller; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.Set; | |
import java.util.concurrent.ConcurrentHashMap; | |
import org.apache.uima.UIMAFramework; | |
import org.apache.uima.aae.UIMAEE_Constants; | |
import org.apache.uima.aae.InProcessCache.CacheEntry; | |
import org.apache.uima.aae.delegate.Delegate; | |
import org.apache.uima.flow.FinalStep; | |
import org.apache.uima.util.Level; | |
public class LocalCache extends ConcurrentHashMap<String, LocalCache.CasStateEntry> { | |
private static final long serialVersionUID = 1L; | |
private static final Class CLASS_NAME = LocalCache.class; | |
private AnalysisEngineController controller; | |
public LocalCache(AnalysisEngineController aController) { | |
controller = aController; | |
} | |
public CasStateEntry createCasStateEntry(String aCasReferenceId) { | |
CasStateEntry entry = new CasStateEntry(aCasReferenceId); | |
super.put(aCasReferenceId, entry); | |
return entry; | |
} | |
public CasStateEntry lookupEntry(String aCasReferenceId) { | |
if (super.containsKey(aCasReferenceId)) { | |
return super.get(aCasReferenceId); | |
} | |
return null; | |
} | |
public String lookupInputCasReferenceId(String aCasReferenceId) { | |
String parentCasReferenceId = null; | |
if (this.containsKey(aCasReferenceId)) { | |
CasStateEntry entry = (CasStateEntry) get(aCasReferenceId); | |
if (entry != null && entry.isSubordinate()) { | |
// recursively call each parent until we get to the top of the | |
// Cas hierarchy | |
parentCasReferenceId = lookupInputCasReferenceId(entry.getInputCasReferenceId()); | |
} else { | |
return aCasReferenceId; | |
} | |
} | |
return parentCasReferenceId; | |
} | |
public String lookupInputCasReferenceId(CasStateEntry entry) { | |
String parentCasReferenceId = null; | |
if (entry.isSubordinate()) { | |
// recursively call each parent until we get to the top of the | |
// Cas hierarchy | |
parentCasReferenceId = lookupInputCasReferenceId((CasStateEntry) get(entry | |
.getInputCasReferenceId())); | |
} else { | |
return entry.getCasReferenceId(); | |
} | |
return parentCasReferenceId; | |
} | |
public void dumpContents() { | |
dumpContents(false); | |
} | |
public synchronized void dumpContents(boolean dump2Stdout) { | |
int count = 0; | |
if (UIMAFramework.getLogger().isLoggable(Level.FINEST)) { | |
StringBuffer sb = new StringBuffer("\n"); | |
for (Iterator it = entrySet().iterator(); it.hasNext();) { | |
Map.Entry entry = (Map.Entry) it.next(); | |
CasStateEntry casStateEntry = (CasStateEntry) entry.getValue(); | |
if (casStateEntry == null) { | |
continue; | |
} | |
count++; | |
if (casStateEntry.isSubordinate()) { | |
sb.append(entry.getKey() + " Number Of Child CASes In Play:" | |
+ casStateEntry.getSubordinateCasInPlayCount() + " Parent CAS id:" | |
+ casStateEntry.getInputCasReferenceId()); | |
} else { | |
sb.append(entry.getKey() + " *** Input CAS. Number Of Child CASes In Play:" | |
+ casStateEntry.getSubordinateCasInPlayCount()); | |
} | |
if (casStateEntry.isWaitingForRelease()) { | |
sb.append(" <<< Reached Final State in Controller:" + controller.getComponentName()); | |
} | |
sb.append("\n"); | |
} | |
UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINEST, CLASS_NAME.getName(), "dumpContents", | |
UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_show_cache_entry_key__FINEST", | |
new Object[] { controller.getComponentName(), count, sb.toString() }); | |
if ( dump2Stdout ) { | |
System.out.println(sb.toString()); | |
} | |
sb.setLength(0); | |
} else if (UIMAFramework.getLogger().isLoggable(Level.FINE)) { | |
int inFinalState = 0; | |
for (Iterator it = entrySet().iterator(); it.hasNext();) { | |
Map.Entry entry = (Map.Entry) it.next(); | |
CasStateEntry casStateEntry = (CasStateEntry) entry.getValue(); | |
count++; | |
if (casStateEntry != null && casStateEntry.isWaitingForRelease()) { | |
inFinalState++; | |
} | |
} | |
UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, CLASS_NAME.getName(), "dumpContents", | |
UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, "UIMAEE_show_abbrev_cache_stats___FINE", | |
new Object[] { controller.getComponentName(), count, inFinalState }); | |
} | |
} | |
public synchronized void remove(String aCasReferenceId) { | |
if (aCasReferenceId != null && containsKey(aCasReferenceId)) { | |
if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.FINE)) { | |
UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, getClass().getName(), "remove", | |
UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, | |
"UIMAEE_remove_cache_entry_for_cas__FINE", new Object[] { aCasReferenceId }); | |
} | |
super.remove(aCasReferenceId); | |
this.notifyAll(); | |
} else if (aCasReferenceId == null) { | |
if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.FINE)) { | |
UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, getClass().getName(), "remove", | |
UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, | |
"UIMAEE_cas_is_null_remove_from_cache_failed__FINE"); | |
} | |
} else { | |
if (UIMAFramework.getLogger(CLASS_NAME).isLoggable(Level.FINE)) { | |
UIMAFramework.getLogger(CLASS_NAME).logrb(Level.FINE, getClass().getName(), "remove", | |
UIMAEE_Constants.JMS_LOG_RESOURCE_BUNDLE, | |
"UIMAEE_cas_is_invalid_remove_from_cache_failed__FINE", | |
new Object[] { aCasReferenceId }); | |
} | |
} | |
} | |
public CasStateEntry getTopCasAncestor(String casReferenceId) throws Exception { | |
if (!containsKey(casReferenceId)) { | |
return null; | |
} | |
CasStateEntry casStateEntry = lookupEntry(casReferenceId); | |
if (casStateEntry.isSubordinate()) { | |
// Recurse until the top CAS reference Id is found | |
return getTopCasAncestor(casStateEntry.getInputCasReferenceId()); | |
} | |
// Return the top ancestor CAS id | |
return casStateEntry; | |
} | |
public static class CasStateEntry { | |
private String casReferenceId; | |
private volatile boolean waitingForRealease; | |
private volatile boolean pendingReply; | |
private volatile boolean subordinateCAS; | |
private volatile boolean replyReceived; | |
private volatile boolean failed; | |
private volatile boolean dropped; | |
private List<Throwable> exceptionList = new ArrayList<Throwable>(); | |
private FinalStep step; | |
private int state; | |
private int subordinateCasInPlayCount; | |
private Object childCountMux = new Object(); | |
private String inputCasReferenceId; | |
private int numberOfParallelDelegates = 1; | |
private Delegate lastDelegate = null; | |
private int howManyDelegatesResponded = 0; | |
private Endpoint freeCasNotificationEndpoint; | |
private volatile boolean deliveryToClientFailed; | |
public boolean deliveryToClientFailed() { | |
return deliveryToClientFailed; | |
} | |
public void setDeliveryToClientFailed() { | |
this.deliveryToClientFailed = true; | |
} | |
public boolean isDropped() { | |
return dropped; | |
} | |
public void setDropped(boolean dropped) { | |
this.dropped = dropped; | |
} | |
public Endpoint getFreeCasNotificationEndpoint() { | |
return freeCasNotificationEndpoint; | |
} | |
public void setFreeCasNotificationEndpoint(Endpoint freeCasNotificationEndpoint) { | |
this.freeCasNotificationEndpoint = freeCasNotificationEndpoint; | |
} | |
public CasStateEntry(String aCasReferenceId) { | |
casReferenceId = aCasReferenceId; | |
} | |
public void setLastDelegate(Delegate aDelegate) { | |
lastDelegate = aDelegate; | |
} | |
public Delegate getLastDelegate() { | |
return lastDelegate; | |
} | |
public String getCasReferenceId() { | |
return casReferenceId; | |
} | |
public String getInputCasReferenceId() { | |
return inputCasReferenceId; | |
} | |
public void setInputCasReferenceId(String anInputCasReferenceId) { | |
inputCasReferenceId = anInputCasReferenceId; | |
subordinateCAS = true; | |
} | |
public void setWaitingForRelease(boolean flag) { | |
waitingForRealease = flag; | |
} | |
public boolean isWaitingForRelease() { | |
return waitingForRealease; | |
} | |
public void setFinalStep(FinalStep step) { | |
this.step = step; | |
} | |
public FinalStep getFinalStep() { | |
return step; | |
} | |
public int getState() { | |
return state; | |
} | |
public void setState(int aState) { | |
state = aState; | |
} | |
public boolean isSubordinate() { | |
return subordinateCAS; | |
} | |
public int getSubordinateCasInPlayCount() { | |
synchronized (childCountMux) { | |
return subordinateCasInPlayCount; | |
} | |
} | |
public void incrementSubordinateCasInPlayCount() { | |
synchronized (childCountMux) { | |
subordinateCasInPlayCount++; | |
} | |
} | |
public int decrementSubordinateCasInPlayCount() { | |
synchronized (childCountMux) { | |
if (subordinateCasInPlayCount > 0) { | |
subordinateCasInPlayCount--; | |
} | |
return subordinateCasInPlayCount; | |
} | |
} | |
public boolean isPendingReply() { | |
return pendingReply; | |
} | |
public void setPendingReply(boolean pendingReply) { | |
this.pendingReply = pendingReply; | |
} | |
public void setReplyReceived() { | |
replyReceived = true; | |
} | |
public boolean isReplyReceived() { | |
return replyReceived; | |
} | |
public void resetReplyReceived() { | |
replyReceived = false; | |
} | |
public synchronized void incrementHowManyDelegatesResponded() { | |
if (howManyDelegatesResponded < numberOfParallelDelegates) { | |
howManyDelegatesResponded++; | |
} | |
} | |
public synchronized int howManyDelegatesResponded() { | |
return howManyDelegatesResponded; | |
} | |
public synchronized void resetDelegateResponded() { | |
howManyDelegatesResponded = 0; | |
} | |
public void setNumberOfParallelDelegates(int aNumberOfParallelDelegates) { | |
numberOfParallelDelegates = aNumberOfParallelDelegates; | |
} | |
public int getNumberOfParallelDelegates() { | |
return numberOfParallelDelegates; | |
} | |
public boolean isFailed() { | |
return failed; | |
} | |
public void setFailed() { | |
this.failed = true; | |
} | |
public void addThrowable(Throwable t) { | |
exceptionList.add(t); | |
} | |
public List<Throwable> getErrors() { | |
return exceptionList; | |
} | |
} | |
} |