Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* JBoss, Home of Professional Open Source
* Copyright 2006, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
* (C) 2005-2006,
* @author JBoss Inc.
*/
/*
* Copyright (C) 1998, 1999, 2000, 2001,
*
* Arjuna Solutions Limited,
* Newcastle upon Tyne,
* Tyne and Wear,
* UK.
*
* $Id: ActionHierarchy.java 2342 2006-03-30 13:06:17Z $
*/
package com.arjuna.ats.arjuna.coordinator;
import java.io.IOException;
import java.io.PrintWriter;
import com.arjuna.ats.arjuna.common.Uid;
import com.arjuna.ats.arjuna.logging.tsLogger;
import com.arjuna.ats.arjuna.state.InputBuffer;
import com.arjuna.ats.arjuna.state.OutputBuffer;
import com.arjuna.ats.internal.arjuna.common.UidHelper;
/**
* Class that represents the transaction hierarchy. This class
* can cope with transaction hierarchies of arbitrary depth.
*
* @author Mark Little ([email protected])
* @version $Id: ActionHierarchy.java 2342 2006-03-30 13:06:17Z $
* @since 1.0.
*/
public class ActionHierarchy
{
/**
* Create a new (blank) hierarchy with sufficient space for the
* specified number of transactions. Once this space is exhausted,
* additional space will be obtained dynamically.
*/
public ActionHierarchy (int depth)
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActionHierarchy::ActionHierarchy(" + depth + ")");
}
hierarchy = null;
maxHierarchyDepth = depth;
currentDepth = 0;
if (maxHierarchyDepth > 0)
{
hierarchy = new ActionInfo[maxHierarchyDepth];
for (int i = 0; i < maxHierarchyDepth; i++)
hierarchy[i] = null;
}
}
/**
* Create a new copy of the specified transaction hierarchy.
*/
public ActionHierarchy (ActionHierarchy theCopy)
{
hierarchy = null;
maxHierarchyDepth = theCopy.maxHierarchyDepth;
currentDepth = theCopy.currentDepth;
if (maxHierarchyDepth > 0)
{
hierarchy = new ActionInfo[maxHierarchyDepth];
for (int i = 0; i < maxHierarchyDepth; i++)
hierarchy[i] = null;
}
for (int i = 0; i < currentDepth; i++)
{
hierarchy[i] = new ActionInfo(theCopy.hierarchy[i]);
}
}
/**
* Print out the transaction hierarchy.
*/
public void print (PrintWriter strm)
{
strm.println("\tCurrent depth : "+currentDepth);
if (currentDepth == 0)
strm.println("\tAction Uids : NULL");
else
{
strm.println("\tAction Uids :");
/*
* No need to check if hierarchy[i] is set, since currentDepth
* implies it is.
*/
for (int i = 0; i < currentDepth; i++)
strm.println("\t\t"+hierarchy[i].actionUid);
}
}
/**
* Create a copy of the specified transaction hierarchy. Any
* hierarchy currently maintained by this object will be
* lost in favour of the new hierarchy.
*
* We check for self-assignment.
*/
public synchronized void copy (ActionHierarchy c)
{
/* Beware of A = A */
if (this == c)
return;
if (hierarchy != null)
hierarchy = null;
currentDepth = c.currentDepth;
maxHierarchyDepth = c.maxHierarchyDepth;
if (maxHierarchyDepth > 0)
{
hierarchy = new ActionInfo[maxHierarchyDepth];
for (int i = 0; i < maxHierarchyDepth; i++)
hierarchy[i] = null;
}
for (int i = 0; i < currentDepth; i++)
hierarchy[i] = new ActionInfo(c.hierarchy[i]);
}
/**
* Overloads Object.equals.
*/
public final boolean equals (ActionHierarchy other)
{
boolean same = true;
if (currentDepth == other.depth())
{
for (int i = 0; i < currentDepth; i++)
{
if (hierarchy[i].notEquals(other.getActionInfo(i)))
{
same = false;
break;
}
}
}
else
same = false;
return same;
}
/**
* Insert new entry growing table as needed.
* Transaction id will be added as a top-level transaction.
*
* @return true if successful, false
* otherwise.
*/
public final boolean add (Uid actionId)
{
return add(actionId, ActionType.TOP_LEVEL);
}
/**
* Add the transaction id at the specified level.
*
* @return true if successful, false
* otherwise.
*/
public final boolean add (Uid actionId, int at)
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActionHierarchy::add(" + actionId + ", " + at + ")");
}
boolean result = true;
if (currentDepth >= maxHierarchyDepth)
{
ActionInfo[] newHier = null;
int newDepth = (maxHierarchyDepth + 1) * 2; /* Ensure non zero */
newHier = new ActionInfo[newDepth];
if (newHier != null)
{
maxHierarchyDepth = newDepth;
for (int i = 0; i < currentDepth; i++)
newHier[i] = hierarchy[i];
for (int i = currentDepth; i < newDepth; i++)
newHier[i] = null;
hierarchy = newHier;
newHier = null;
}
else
result = false;
}
if (result)
{
if (hierarchy[currentDepth] == null)
hierarchy[currentDepth] = new ActionInfo();
/*
* What if at == TOPLEVEL and currentDepth != 0?!
*/
hierarchy[currentDepth].actionUid = new Uid(actionId);
hierarchy[currentDepth++].actionType = at;
}
return result;
}
/**
* Scan hierarchy looking for a particular Uid starting at deepest
* and going up. Do NOT go past any top level action.
*
* @return true if is ancestor, false
* otherwise.
*/
public final boolean isAncestor (Uid target)
{
boolean result = false;
for (int i = currentDepth - 1; (i >= 0) && (!result); i--)
{
if (hierarchy[i].actionUid.equals(target))
{
result = true;
break;
}
else
{
if (hierarchy[i].actionType == ActionType.TOP_LEVEL)
break;
}
}
return result;
}
/**
* Pack the hierarchy into the buffer.
*/
public void pack (OutputBuffer state) throws IOException
{
state.packInt(currentDepth);
for (int i = 0; i < currentDepth; i++)
{
UidHelper.packInto(hierarchy[i].actionUid, state);
state.packInt(hierarchy[i].actionType);
}
}
/**
* CAREFULLY unpack the 'new' hierarchy. We unpack into
* a temporary to ensure that the current hierarchy is not corrupted.
*/
public void unpack (InputBuffer state) throws IOException
{
int newDepth = 0;
ActionHierarchy newHier = null;
ActionInfo temp = new ActionInfo();
newDepth = state.unpackInt();
try
{
newHier = new ActionHierarchy(newDepth);
}
catch (OutOfMemoryError ex)
{
IOException ioException = new IOException(tsLogger.i18NLogger.get_coordinator_ActionHierarchy_1());
ioException.initCause(ex);
throw ioException;
}
for (int i = 0; i < newDepth; i++)
{
temp.actionUid = UidHelper.unpackFrom(state);
temp.actionType = state.unpackInt();
newHier.add(temp.actionUid, temp.actionType);
}
/*
* We don't need to copy this if we got here. We can
* simply assign to it, and let the garbage collector
* figure things out.
*/
hierarchy = newHier.hierarchy;
currentDepth = newHier.currentDepth;
maxHierarchyDepth = newHier.maxHierarchyDepth;
newHier.hierarchy = null;
newHier = null;
}
/**
* Remove the deepest nested transaction from the hierarchy.
*/
public final void forgetDeepest ()
{
if (currentDepth > 0)
{
hierarchy[--currentDepth] = null;
}
}
/**
* Find common prefix in two hierarchies.
*
* @return the index of the first common ancestor.
*/
public final int findCommonPrefix (ActionHierarchy oldHierarchy)
{
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActionHierarchy::findCommonPrefix()");
}
int common = 0;
int max = oldHierarchy.depth();
while ((common < currentDepth) && (common < max) &&
(hierarchy[common].equals(oldHierarchy.getActionInfo(common))))
{
common++;
}
if (tsLogger.logger.isTraceEnabled()) {
tsLogger.logger.trace("ActionHierarchy::::findCommonPrefix(): prefix is " + common);
}
return common;
}
/**
* Returns the current depth of the hierarchy.
*
* @return the hierarchy depth.
*/
public synchronized final int depth ()
{
return currentDepth;
}
/**
* Returns the transaction id of the most deeply nested transaction.
*
* @return the Uid of the deepest transaction.
*/
public synchronized final Uid getDeepestActionUid ()
{
if (currentDepth > 0)
return hierarchy[currentDepth-1].actionUid;
else
return Uid.nullUid();
}
/**
* @return the identity of the transaction at the specified level
* in the hierarchy.
*/
public synchronized final Uid getActionUid (int typeIndex)
{
return hierarchy[typeIndex].actionUid;
}
/**
* @return the ActionInfo for the transaction at the
* specified level. ActionInfo is not a public class so this is of
* limited use outside of the transaction system.
*/
public synchronized final ActionInfo getActionInfo (int typeIndex)
{
return hierarchy[typeIndex];
}
public static final int DEFAULT_HIERARCHY_DEPTH = 5;
private ActionInfo[] hierarchy;
private int maxHierarchyDepth;
private int currentDepth;
}