/*
* 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 com.sun.jini.outrigger;
import java.util.Set;
/**
* Object that that represents a visibility transition of some
* entry.
*/
class EntryTransition {
/** The <code>EntryHandle</code> of the entry that changed */
final private EntryHandle handle;
/**
* If this is a transition to visibility and/or availability, what
* transaction the entry is now available/visible to. If
* <code>null</code> the entry transitioned to a state where it is
* available/visible to all.
*/
final private TransactableMgr txn;
/**
* <code>true</code> if the entry is transitioning from a state
* where it could not be taken to one where it could be,
* <code>false</code> otherwise.
*/
final private boolean available;
/**
* <code>true</code> if the entry is transitioning from a state
* where it could not be read to one where it could be,
* <code>false</code> otherwise.
*/
final private boolean visible;
/**
* <code>true</code> if the transition is a write or
* the commit of a write, <code>false</code> otherwise.
*/
final private boolean newEntry;
/**
* Set of watchers that need to remember that they have seen
* this transition already
*/
final private Set watchers = new java.util.HashSet();
/**
* Create a new <code>EntryTransition</code> object
* with the specified content.
* @param handle The <code>EntryHandle</code> of the
* the entry who's visibility is changing.
* @param txn If the entry is only visible in a particular
* transaction, the <code>Txn</code> for that
* transaction, and <code>null</code> otherwise.
* @param available <code>true</code> if the entry is
* transitioning from a state where it could not be
* taken to one where it could be,
* <code>false</code> otherwise.
* @param visible <code>true</code> if the entry is transitioning
* from a state where it could not be read to one
* where it could be, <code>false</code> otherwise.
* @param newEntry <code>true</code> if the entry is available and
* the transition is because of a write or a write
* that is being committed, <code>false</code>
* otherwise.
* @throws NullPointerException if handle is null.
*/
EntryTransition(EntryHandle handle, TransactableMgr txn, boolean available,
boolean visible, boolean newEntry)
{
if (handle == null)
throw new NullPointerException("entry must be non-null");
assert (!visible || (available && visible));
assert (!newEntry || (available && visible));
this.handle = handle;
this.txn = txn;
this.available = available;
this.visible = visible;
this.newEntry = newEntry;
}
/**
* Return the <code>EntryHandle</code> for entry undergoing the
* visibility transition.
* @return The handle for the entry undergoing the visibility
* transition.
*/
EntryHandle getHandle() {
return handle;
}
/**
* If this is a transition to visibility and/or availability, what
* transaction the entry is now available/visible to. If
* <code>null</code> the entry transitioned to a state where it is
* available/visible to all.
* @return the transaction the associated entry is now
* available/visible too
*/
TransactableMgr getTxn() {
return txn;
}
/**
* Returns <code>true</code> if this is a transition from a state
* where the entry could not be taken to one where it could be.
* Otherwise returns <code>false</code>. Note, <code>isVisible</code>
* returning <code>true</code> implies that <code>isAvailable</code>
* will also return <code>true</code>.
* @return <code>true</code> if this is a transition from a state
* where the entry could not be taken to one where it could be.
* Otherwise returns <code>false</code>
*/
boolean isAvailable() {
return available;
}
/**
* Returns <code>true</code> if this is a transition from a state
* where the entry could not be read to one where it could be.
* Otherwise returns <code>false</code>. Note, <code>isVisible</code>
* returning <code>true</code> implies that <code>isAvailable</code>
* will also return <code>true</code>.
* @return <code>true</code> if this is a transition from a state
* where the entry could not be read to one where it could be.
* Otherwise returns <code>false</code>
*/
boolean isVisible() {
return visible;
}
/**
* Return <code>true</code> if this transition represents a
* new entry becoming visible, otherwise return <code>false</code>.
* @return Return <code>true</code> if this transition represents a
* new entry becoming visible, otherwise return <code>false</code>.
*/
boolean isNewEntry() {
return newEntry;
}
/**
* Record that a given watcher has processed this Transition and
* does not need to again. Assumes that the <code>processedBy</code>
* and <code>hasProcessed</code> methods are only called from
* a single thread. <p>
*
* Note, we never remove watchers from the set of watchers that
* have processed this transition since in general we would only
* know to remove a watcher when this transition had already
* visited every template, at which point the entire
* EntryTransition object is eligible for GC (internally we could
* use a weak set, but once watchers start processing an
* EntryTransition, its life time is limited so it hardly seems
* worth the trouble)
*/
void processedBy(TransitionWatcher w) {
watchers.add(w);
}
/**
* Return <code>true</code> if the passed watcher has been passed
* to <code>processedBy</code>. Assumes that the <code>processedBy</code>
* and <code>hasProcessed</code> methods are only called from
* a single thread.
*/
boolean hasProcessed(TransitionWatcher w) {
return watchers.contains(w);
}
}