[jbosscache-commits] JBoss Cache SVN: r6854 - in core/branches/flat/src/main/java/org/jboss/starobrno: context and 1 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Oct 7 12:22:08 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-10-07 12:22:07 -0400 (Tue, 07 Oct 2008)
New Revision: 6854

Added:
   core/branches/flat/src/main/java/org/jboss/starobrno/DataContainer.java
   core/branches/flat/src/main/java/org/jboss/starobrno/UnsortedDataContainer.java
   core/branches/flat/src/main/java/org/jboss/starobrno/context/
   core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContext.java
   core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContextImpl.java
   core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/
   core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryImpl.java
   core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryReference.java
   core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/MVCCEntry.java
   core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/NullMarkerEntry.java
   core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/ReadCommittedEntry.java
   core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/RepeatableReadEntry.java
Log:
Another pint of Starobrno


Added: core/branches/flat/src/main/java/org/jboss/starobrno/DataContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/DataContainer.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/DataContainer.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno;
+
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * // TODO: MANIK: Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public interface DataContainer<K, V>
+{
+   Set<Entry<K, V>> getEntries();
+
+   Entry<K, V> getEntry(K k);
+
+   void putEntry(Entry<K, V> entry);
+
+   boolean exists(Entry<K, V> entry);
+}

Added: core/branches/flat/src/main/java/org/jboss/starobrno/UnsortedDataContainer.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/UnsortedDataContainer.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/UnsortedDataContainer.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,62 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno;
+
+import java.util.LinkedHashSet;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * // TODO: crappy and inefficient - but just a placeholder for now.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class UnsortedDataContainer<K, V> implements DataContainer<K, V>
+{
+   Set<Entry<K, V>> entries = new LinkedHashSet<Entry<K, V>>();
+
+   public Set<Entry<K, V>> getEntries()
+   {
+      return entries;
+   }
+
+   public Entry<K, V> getEntry(K k)
+   {
+      if (k == null) throw new NullPointerException("I don't like nulls!");
+      for (Entry<K, V> e : entries)
+      {
+         if (k.equals(e.getKey())) return e;
+      }
+      return null;
+   }
+
+   public void putEntry(Entry<K, V> kvEntry)
+   {
+      entries.add(kvEntry);
+   }
+
+   public boolean exists(Entry<K, V> kvEntry)
+   {
+      return getEntry(kvEntry.getKey()) != null;
+   }
+}

Added: core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContext.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContext.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContext.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,108 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.context;
+
+import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jboss.cache.transaction.TransactionContext;
+import org.jboss.starobrno.mvcc.MVCCEntry;
+
+import javax.transaction.Transaction;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * // TODO: MANIK: Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public interface InvocationContext
+{
+   MVCCEntry lookupEntry(Object key);
+
+   Map<Object, MVCCEntry> getLookedUpEntries();
+
+   void putLookedUpEntry(MVCCEntry e);
+
+   void putLookedUpEntries(Set<MVCCEntry> lookedUpEntries);
+
+   void clearLookedUpEntries();
+
+   void setLocalRollbackOnly(boolean localRollbackOnly);
+
+   Transaction getTransaction();
+
+   void setTransaction(Transaction transaction);
+
+   TransactionContext getTransactionContext();
+
+   void setTransactionContext(TransactionContext transactionContext);
+
+   GlobalTransaction getGlobalTransaction();
+
+   void setGlobalTransaction(GlobalTransaction globalTransaction);
+
+   Option getOptionOverrides();
+
+   boolean isOptionsUninitialised();
+
+   void setOptionOverrides(Option optionOverrides);
+
+   boolean isOriginLocal();
+
+   List<Object> getKeysLocked();
+
+   void addAllKeysLocked(List<Object> keysLocked);
+
+   void addKeyLocked(Object keyLocked);
+
+   void removeKeyLocked(Object keyLocked);
+
+   void clearKeysLocked();
+
+   boolean hasLockedKey(Object key);
+
+   boolean isLockingSuppressed();
+
+   void setOriginLocal(boolean originLocal);
+
+   boolean isLocalRollbackOnly();
+
+   void reset();
+
+   InvocationContext copy();
+
+   void setState(InvocationContext template);
+
+   long getLockAcquisitionTimeout(long timeout);
+
+   void setCommand(VisitableCommand cacheCommand);
+
+   VisitableCommand getCommand();
+
+   boolean isValidTransaction();
+
+   void throwIfNeeded(Throwable e) throws Throwable;
+}

Added: core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContextImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContextImpl.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationContextImpl.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,619 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.context;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.NodeSPI;
+import org.jboss.cache.commands.VisitableCommand;
+import org.jboss.cache.config.Option;
+import org.jboss.cache.marshall.MethodCall;
+import org.jboss.cache.transaction.GlobalTransaction;
+import org.jboss.cache.transaction.TransactionContext;
+import org.jboss.cache.transaction.TransactionTable;
+import org.jboss.cache.util.Immutables;
+import org.jboss.starobrno.mvcc.MVCCEntry;
+
+import javax.transaction.Transaction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * // TODO: MANIK: Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class InvocationContextImpl implements InvocationContext
+{
+   private static final Log log = LogFactory.getLog(InvocationContext.class);
+   private static final boolean trace = log.isTraceEnabled();
+
+   private Transaction transaction;
+   private GlobalTransaction globalTransaction;
+   protected TransactionContext transactionContext;
+   private Option optionOverrides;
+   // defaults to true.
+   private boolean originLocal = true;
+   private boolean localRollbackOnly;
+   @Deprecated
+   private MethodCall methodCall;
+   @Deprecated
+   private VisitableCommand command;
+
+   /**
+    * LinkedHashSet of locks acquired by the invocation. We use a LinkedHashSet because we need efficient Set semantics
+    * but also need guaranteed ordering for use by lock release code (see JBCCACHE-874).
+    * <p/>
+    * This needs to be unchecked since we support both MVCC (Fqns held here) or legacy Opt/Pess locking (NodeLocks held here).
+    * once we drop support for opt/pess locks we can genericise this to contain Fqns. - Manik Surtani, June 2008
+    */
+   protected LinkedHashSet<Object> invocationLocks;
+   private HashMap<Object, MVCCEntry> lookedUpEntries = null;
+
+   /**
+    * Retrieves a node from the registry of looked up nodes in the current scope.
+    * <p/>
+    * If a transaction is in progress, implementations should delegate to {@link org.jboss.cache.transaction.MVCCTransactionContext#lookUpNode(Fqn)}
+    * <p/>
+    *
+    * @param fqn fqn to look up
+    * @return a node, or null if it cannot be found.
+    */
+   public MVCCEntry lookupEntry(Object k)
+   {
+      // TODO: Fix this after we have a Transaction context that works.
+//      if (transactionContext != null) return transactionContext.lookupEntry(k);
+//      return lookedUpEntries == null ? null : lookedUpEntries.get(k);
+      return null;
+   }
+
+   /**
+    * Puts an entry in the registry of looked up nodes in the current scope.
+    * <p/>
+    * If a transaction is in progress, implementations should delegate to {@link org.jboss.cache.transaction.MVCCTransactionContext#putLookedUpNode(Fqn, NodeSPI)}
+    * <p/>
+    *
+    * @param f fqn to add
+    * @param n node to add
+    */
+   public void putLookedUpEntry(MVCCEntry e)
+   {
+      // TODO: Fix this after we have a Transaction context that works.
+
+//      if (transactionContext != null)
+//         transactionContext.putLookedUpEntry(e);
+//      else
+//      {
+//         if (lookedUpEntries == null) lookedUpEntries = new HashMap<Object, MVCCEntry>(4);
+//         lookedUpEntries.put(e.getKey(), e);
+//      }
+   }
+
+   public void putLookedUpEntries(Set<MVCCEntry> lookedUpEntries)
+   {
+      // TODO: Fix this after we have a Transaction context that works.
+//      if (transactionContext != null)
+//         transactionContext.putLookedUpEntries(lookedUpEntries);
+//      else
+//      {
+//         if (this.lookedUpEntries == null)
+//            this.lookedUpEntries = new HashMap<Object, MVCCEntry>();
+//
+//         for (MVCCEntry e: lookedUpEntries) this.lookedUpEntries.put(e.getKey(), e);
+//      }
+   }
+
+   /**
+    * Clears the registry of looked up nodes.
+    * <p/>
+    * If a transaction is in progress, implementations should delegate to {@link org.jboss.cache.transaction.MVCCTransactionContext#clearLookedUpNodes()}.
+    */
+   public void clearLookedUpEntries()
+   {
+      // TODO: see if we can reinstate common behaviour once we have the ICI calling ctx.reset() instead of ctx.clearLookedUpNodes()
+//      if (transactionContext != null)
+//         transactionContext.clearLookedUpNodes();
+//      else
+
+      if (lookedUpEntries != null) lookedUpEntries.clear();
+   }
+
+   /**
+    * Retrieves a map of nodes looked up within the current invocation's scope.
+    * <p/>
+    * If a transaction is in progress, implementations should delegate to {@link org.jboss.cache.transaction.MVCCTransactionContext#getLookedUpNodes()}.
+    * <p/>
+    *
+    * @return a map of looked up nodes.
+    */
+   @SuppressWarnings("unchecked")
+   public Map<Object, MVCCEntry> getLookedUpEntries()
+   {
+      // TODO: Fix this after we have a Transaction context that works.
+//      if (transactionContext != null) return transactionContext.getLookedUpNodes();
+//      return (Map<Fqn, NodeSPI>) (lookedUpEntries == null ? Collections.emptyMap() : lookedUpEntries);
+      return null;
+   }
+
+   @SuppressWarnings("unchecked")
+   public InvocationContext copy()
+   {
+      InvocationContextImpl copy = new InvocationContextImpl();
+      doCopy(copy);
+      if (lookedUpEntries != null) copy.lookedUpEntries = (HashMap<Object, MVCCEntry>) lookedUpEntries.clone();
+      return copy;
+   }
+
+
+   /**
+    * Marks teh context as only rolling back.
+    *
+    * @param localRollbackOnly if true, the context is only rolling back.
+    */
+   public void setLocalRollbackOnly(boolean localRollbackOnly)
+   {
+      this.localRollbackOnly = localRollbackOnly;
+   }
+
+   /**
+    * Retrieves the transaction associated with this invocation
+    *
+    * @return The transaction associated with this invocation
+    */
+   public Transaction getTransaction()
+   {
+      return transaction;
+   }
+
+   /**
+    * Sets a transaction object on the invocation context.
+    *
+    * @param transaction transaction to set
+    */
+   public void setTransaction(Transaction transaction)
+   {
+      this.transaction = transaction;
+   }
+
+   /**
+    * @return the transaction entry associated with the current transaction, or null if the current thread is not associated with a transaction.
+    * @since 2.2.0
+    */
+   public TransactionContext getTransactionContext()
+   {
+      return transactionContext;
+   }
+
+   /**
+    * Sets the transaction context to be associated with the current thread.
+    *
+    * @param transactionContext transaction context to set
+    * @since 2.2.0
+    */
+   public void setTransactionContext(TransactionContext transactionContext)
+   {
+      this.transactionContext = transactionContext;
+   }
+
+   /**
+    * Retrieves the global transaction associated with this invocation
+    *
+    * @return the global transaction associated with this invocation
+    */
+   public GlobalTransaction getGlobalTransaction()
+   {
+      return globalTransaction;
+   }
+
+   /**
+    * Sets the global transaction associated with this invocation
+    *
+    * @param globalTransaction global transaction to set
+    */
+   public void setGlobalTransaction(GlobalTransaction globalTransaction)
+   {
+      this.globalTransaction = globalTransaction;
+   }
+
+
+   /**
+    * Retrieves the option overrides associated with this invocation
+    *
+    * @return the option overrides associated with this invocation
+    */
+   public Option getOptionOverrides()
+   {
+      if (optionOverrides == null)
+      {
+         optionOverrides = new Option();
+      }
+      return optionOverrides;
+   }
+
+   /**
+    * @return true of no options have been set on this context, false otherwise.
+    */
+   public boolean isOptionsUninitialised()
+   {
+      return optionOverrides == null;
+   }
+
+   /**
+    * Sets the option overrides to be associated with this invocation
+    *
+    * @param optionOverrides options to set
+    */
+   public void setOptionOverrides(Option optionOverrides)
+   {
+      this.optionOverrides = optionOverrides;
+   }
+
+   /**
+    * Tests if this invocation originated locally or from a remote cache.
+    *
+    * @return true if the invocation originated locally.
+    */
+   public boolean isOriginLocal()
+   {
+      return originLocal;
+   }
+
+   /**
+    * Returns an immutable,  defensive copy of the List of locks currently maintained for the current scope.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should retrieve these locks from the {@link org.jboss.cache.transaction.TransactionContext}.
+    * Retrieving locks from this method should always ensure they are retrieved from  the appropriate scope.
+    * <p/>
+    * Note that currently (as of 3.0.0) this list is unchecked.  This is to allow support for both MVCC (which uses Fqns as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to return <tt>List<Fqn></tt>.
+    *
+    * @return locks held in current scope.
+    */
+   @SuppressWarnings("unchecked")
+   public List getKeysLocked()
+   {
+      // first check transactional scope
+      if (transactionContext != null) return transactionContext.getLocks();
+      return invocationLocks == null || invocationLocks.isEmpty() ? Collections.emptyList() : Immutables.immutableListConvert(invocationLocks);
+   }
+
+   /**
+    * Adds a List of locks to the currently maintained collection of locks acquired.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should record locks on the {@link org.jboss.cache.transaction.TransactionContext}.
+    * Adding locks using this method should always ensure they are applied to the appropriate scope.
+    * <p/>
+    * Note that currently (as of 3.0.0) this list is unchecked.  This is to allow support for both MVCC (which uses Fqns as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to accept <tt>List<Fqn></tt>.
+    *
+    * @param locks locks to add
+    */
+   @SuppressWarnings("unchecked")
+   public void addAllKeysLocked(List locks)
+   {
+      // first check transactional scope
+      if (transactionContext != null)
+      {
+         transactionContext.addAllLocks(locks);
+      }
+      else
+      {
+         // no need to worry about concurrency here - a context is only valid for a single thread.
+         if (invocationLocks == null) invocationLocks = new LinkedHashSet(4);
+         invocationLocks.addAll(locks);
+      }
+   }
+
+   /**
+    * Adds a lock to the currently maintained collection of locks acquired.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should record this lock on the {@link org.jboss.cache.transaction.TransactionContext}.
+    * Using this method should always ensure that the appropriate scope is used.
+    * <p/>
+    * Note that currently (as of 3.0.0) this lock is weakly typed.  This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
+    *
+    * @param lock lock to add
+    */
+   @SuppressWarnings("unchecked")
+   public void addKeyLocked(Object lock)
+   {
+      // first check transactional scope
+      if (transactionContext != null)
+      {
+         transactionContext.addLock(lock);
+      }
+      else
+      {
+         // no need to worry about concurrency here - a context is only valid for a single thread.
+         if (invocationLocks == null) invocationLocks = new LinkedHashSet(4);
+         invocationLocks.add(lock);
+      }
+   }
+
+   /**
+    * Removes a lock from the currently maintained collection of locks acquired.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should remove this lock from the {@link org.jboss.cache.transaction.TransactionContext}.
+    * Using this method should always ensure that the lock is removed from the appropriate scope.
+    * <p/>
+    * Note that currently (as of 3.0.0) this lock is weakly typed.  This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
+    *
+    * @param lock lock to remove
+    */
+   @SuppressWarnings("unchecked")
+   public void removeKeyLocked(Object lock)
+   {
+      // first check transactional scope
+      if (transactionContext != null)
+      {
+         transactionContext.removeLock(lock);
+      }
+      else
+      {
+         // no need to worry about concurrency here - a context is only valid for a single thread.
+         if (invocationLocks != null) invocationLocks.remove(lock);
+      }
+   }
+
+   /**
+    * Clears all locks from the currently maintained collection of locks acquired.
+    * <p/>
+    * Note that if a transaction is in scope, implementations should clear locks from the {@link org.jboss.cache.transaction.TransactionContext}.
+    * Using this method should always ensure locks are cleared in the appropriate scope.
+    * <p/>
+    * Note that currently (as of 3.0.0) this lock is weakly typed.  This is to allow support for both MVCC (which uses {@link Fqn}s as locks)
+    * as well as legacy Optimistic and Pessimistic Locking schemes (which use {@link org.jboss.cache.lock.NodeLock} as locks).  Once support for
+    * legacy node locking schemes are dropped, this method will be more strongly typed to accept {@link Fqn}.
+    */
+   public void clearKeysLocked()
+   {
+      // first check transactional scope
+      if (transactionContext != null)
+      {
+         transactionContext.clearLocks();
+      }
+      else
+      {
+         // no need to worry about concurrency here - a context is only valid for a single thread.
+         if (invocationLocks != null) invocationLocks.clear();
+      }
+   }
+
+   /**
+    * Note that if a transaction is in scope, implementations should test this lock from on {@link org.jboss.cache.transaction.TransactionContext}.
+    * Using this method should always ensure locks checked in the appropriate scope.
+    *
+    * @param lock lock to test
+    * @return true if the lock being tested is already held in the current scope, false otherwise.
+    */
+   public boolean hasLockedKey(Object lock)
+   {
+      // first check transactional scope
+      if (transactionContext != null)
+      {
+         return transactionContext.hasLock(lock);
+      }
+      else
+      {
+         return invocationLocks != null && invocationLocks.contains(lock);
+      }
+   }
+
+   /**
+    * @return true if options exist to suppress locking - false otherwise.  Note that this is only used by the {@link org.jboss.cache.interceptors.PessimisticLockInterceptor}.
+    */
+   public boolean isLockingSuppressed()
+   {
+      return getOptionOverrides() != null && getOptionOverrides().isSuppressLocking();
+   }
+
+   /**
+    * If set to true, the invocation is assumed to have originated locally.  If set to false,
+    * assumed to have originated from a remote cache.
+    *
+    * @param originLocal flag to set
+    */
+   public void setOriginLocal(boolean originLocal)
+   {
+      this.originLocal = originLocal;
+   }
+
+   /**
+    * @return true if the current transaction is set to rollback only.
+    */
+   public boolean isLocalRollbackOnly()
+   {
+      return localRollbackOnly;
+   }
+
+   /**
+    * Resets the context, freeing up any references.
+    */
+   public void reset()
+   {
+      transaction = null;
+      globalTransaction = null;
+      optionOverrides = null;
+      originLocal = true;
+      invocationLocks = null;
+      methodCall = null;
+      command = null;
+      if (lookedUpEntries != null)
+      {
+         lookedUpEntries.clear();
+         lookedUpEntries = null;
+      }
+   }
+
+   /**
+    * Sets the state of the InvocationContext based on the template context passed in
+    *
+    * @param template template to copy from
+    */
+   public void setState(InvocationContext template)
+   {
+      if (template == null)
+      {
+         throw new NullPointerException("Template InvocationContext passed in to InvocationContext.setState() passed in is null");
+      }
+
+      this.setGlobalTransaction(template.getGlobalTransaction());
+      this.setLocalRollbackOnly(template.isLocalRollbackOnly());
+      this.setOptionOverrides(template.getOptionOverrides());
+      this.setOriginLocal(template.isOriginLocal());
+      this.setTransaction(template.getTransaction());
+   }
+
+   /**
+    * @return the method call associated with this invocation
+    */
+   @Deprecated
+   @SuppressWarnings("deprecation")
+   public MethodCall getMethodCall()
+   {
+      if (methodCall == null)
+      {
+         methodCall = createMethodCall();
+      }
+      return methodCall;
+   }
+
+   @SuppressWarnings("deprecation")
+   private MethodCall createMethodCall()
+   {
+      if (command == null) return null;
+      MethodCall call = new MethodCall();
+      call.setMethodId(command.getCommandId());
+      call.setArgs(command.getParameters());
+      return call;
+   }
+
+   /**
+    * Sets the method call associated with this invocation.
+    *
+    * @param methodCall methodcall to set
+    * @deprecated not used anymore.  Interceptors will get a {@link org.jboss.cache.commands.ReplicableCommand} instance passed in along with an InvocationContext.
+    */
+   @Deprecated
+   public void setMethodCall(MethodCall methodCall)
+   {
+      this.methodCall = methodCall;
+   }
+
+   /**
+    * If the lock acquisition timeout is overridden for current call using an option, then return that one.
+    * If not overridden, return default value.
+    *
+    * @param timeout timeout to fall back to
+    * @return timeout to use
+    */
+   public long getLockAcquisitionTimeout(long timeout)
+   {
+      // TODO: this stuff really doesn't belong here.  Put it somewhere else.
+      if (getOptionOverrides() != null
+            && getOptionOverrides().getLockAcquisitionTimeout() >= 0)
+      {
+         timeout = getOptionOverrides().getLockAcquisitionTimeout();
+      }
+      return timeout;
+   }
+
+   /**
+    * This is only used for backward compatibility with old interceptors implementation and should <b>NOT</b> be
+    * use by any new custom interceptors. The commands is now passed in as the second param in each implementing
+    * handlers (handler = method in ChainedInterceptor class)
+    *
+    * @param cacheCommand command to set
+    */
+   @Deprecated
+   @SuppressWarnings("deprecation")
+   public void setCommand(VisitableCommand cacheCommand)
+   {
+      this.command = cacheCommand;
+   }
+
+   /**
+    * @return command that is in scope
+    * @see #setCommand(org.jboss.cache.commands.VisitableCommand)
+    */
+   @Deprecated
+   @SuppressWarnings("deprecation")
+   public VisitableCommand getCommand()
+   {
+      return command;
+   }
+
+   /**
+    * @return true if there is current transaction associated with the invocation, and this transaction is in a valid state.
+    */
+   public boolean isValidTransaction()
+   {
+      // ought to move to the transaction context
+      return transaction != null && TransactionTable.isValid(transaction);
+   }
+
+   /**
+    * Throws the given throwable provided no options suppress or prevent this from happening.
+    *
+    * @param e throwable to throw
+    * @throws Throwable if allowed to throw one.
+    */
+   public void throwIfNeeded(Throwable e) throws Throwable
+   {
+      // TODO: this stuff really doesn't belong here.  Put it somewhere else.
+      Option optionOverride = getOptionOverrides();
+      boolean shouldRethtrow = optionOverride == null || !optionOverride.isFailSilently();
+      if (!shouldRethtrow)
+      {
+         if (trace)
+            log.trace("There was a problem handling this request, but failSilently was set, so suppressing exception", e);
+         return;
+      }
+      throw e;
+   }
+
+   @SuppressWarnings("unchecked")
+   protected void doCopy(InvocationContext c)
+   {
+      InvocationContextImpl copy = (InvocationContextImpl) c;
+      copy.command = command;
+      copy.globalTransaction = globalTransaction;
+      copy.invocationLocks = invocationLocks == null ? null : new LinkedHashSet(invocationLocks);
+      copy.localRollbackOnly = localRollbackOnly;
+      copy.optionOverrides = optionOverrides == null ? null : optionOverrides.copy();
+      copy.originLocal = originLocal;
+      copy.transaction = transaction;
+      copy.transactionContext = transactionContext;
+   }
+}

Added: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryImpl.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryImpl.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryImpl.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,95 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.mvcc;
+
+import java.util.Map.Entry;
+
+/**
+ * A basic map entry
+ */
+public class EntryImpl<K, V> implements Entry<K, V>
+{
+   private K key;
+   private V value;
+
+   public EntryImpl()
+   {
+   }
+
+   public EntryImpl(Entry<K, V> e)
+   {
+      this.key = e.getKey();
+      this.value = e.getValue();
+   }
+
+   public EntryImpl(K key, V value)
+   {
+      this.key = key;
+      this.value = value;
+   }
+
+   public K getKey()
+   {
+      return key;
+   }
+
+   public V getValue()
+   {
+      return value;
+   }
+
+   public V setValue(V value)
+   {
+      V oldValue = this.value;
+      this.value = value;
+      return oldValue;
+   }
+
+   public boolean equals(Object o)
+   {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      EntryImpl entry = (EntryImpl) o;
+
+      if (key != null ? !key.equals(entry.key) : entry.key != null) return false;
+      if (value != null ? !value.equals(entry.value) : entry.value != null) return false;
+
+      return true;
+   }
+
+   public int hashCode()
+   {
+      int result;
+      result = (key != null ? key.hashCode() : 0);
+      result = 31 * result + (value != null ? value.hashCode() : 0);
+      return result;
+   }
+
+   public String toString()
+   {
+      return "EntryImpl{" +
+            "key=" + key +
+            ", value=" + value +
+            '}';
+   }
+}

Copied: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryReference.java (from rev 6851, core/branches/flat/src/main/java/org/jboss/cache/mvcc/NodeReference.java)
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryReference.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryReference.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,106 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.mvcc;
+
+import net.jcip.annotations.ThreadSafe;
+
+import java.util.Map.Entry;
+
+/**
+ * A node reference that delegates all calls to a different {@link org.jboss.cache.InternalNode}.  Simple indirection
+ * is all this class does, allowing other processes to change the delegate.
+ * <p/>
+ * The delegate is a volatile field so the class is thread safe.
+ * <p/>
+ * This is used to wrap all {@link org.jboss.cache.invocation.NodeInvocationDelegate}s in the {@link org.jboss.cache.DataContainer}
+ * when using {@link org.jboss.cache.config.Configuration.NodeLockingScheme#MVCC} and {@link org.jboss.cache.lock.IsolationLevel#READ_COMMITTED}.
+ * <p/>
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @see org.jboss.cache.mvcc.ReadCommittedNode
+ * @since 3.0
+ */
+ at ThreadSafe
+public class EntryReference<K, V> implements Entry<K, V>
+{
+   transient volatile Entry<K, V> delegate;
+
+   public EntryReference(Entry<K, V> delegate)
+   {
+      this.delegate = delegate;
+   }
+
+   /**
+    * @return the InternalNode being delegated to.
+    */
+   public final Entry<K, V> getDelegate()
+   {
+      return delegate;
+   }
+
+   public K getKey()
+   {
+      return delegate.getKey();
+   }
+
+   public V getValue()
+   {
+      return delegate.getValue();
+   }
+
+   public V setValue(V value)
+   {
+      return delegate.setValue(value);
+   }
+
+   @Override
+   public boolean equals(Object o)
+   {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      EntryReference that = (EntryReference) o;
+
+      if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false;
+
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return (delegate != null ? delegate.hashCode() : 0);
+   }
+
+   @Override
+   public String toString()
+   {
+      return "EntryReference{" +
+            "delegate=" + delegate +
+            '}';
+   }
+
+   public void setDelegate(Entry entry)
+   {
+      delegate = entry;
+   }
+}
\ No newline at end of file

Added: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/MVCCEntry.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/MVCCEntry.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/MVCCEntry.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.mvcc;
+
+import org.jboss.cache.InvocationContext;
+import org.jboss.starobrno.DataContainer;
+
+import java.util.Map.Entry;
+
+/**
+ * // TODO: MANIK: Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public interface MVCCEntry extends Entry
+{
+   boolean isNullEntry();
+
+   void copyForUpdate(DataContainer container, boolean writeSkewCheck);
+
+   void commitUpdate(InvocationContext ctx, DataContainer container);
+
+   void rollbackUpdate();
+
+   boolean isChanged();
+
+   boolean isCreated();
+
+   void setCreated(boolean created);
+
+   boolean isDeleted();
+
+   void setDeleted(boolean deleted);
+
+   boolean isValid();
+
+   void setValid(boolean valid);
+}

Copied: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/NullMarkerEntry.java (from rev 6851, core/branches/flat/src/main/java/org/jboss/cache/mvcc/NullMarkerNode.java)
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/NullMarkerEntry.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/NullMarkerEntry.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,75 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.mvcc;
+
+import org.jboss.starobrno.DataContainer;
+
+/**
+ * A marker node to represent a null node for repeatable read, so that a read that returns a null can continue to return
+ * null.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class NullMarkerEntry extends RepeatableReadEntry
+{
+   public NullMarkerEntry()
+   {
+      super(null);
+   }
+
+   /**
+    * @return always returns true
+    */
+   @Override
+   public boolean isNullEntry()
+   {
+      return true;
+   }
+
+   /**
+    * @return always returns true so that any get commands, upon getting this node, will ignore the node as though it were removed.
+    */
+   @Override
+   public boolean isDeleted()
+   {
+      return true;
+   }
+
+   /**
+    * @return always returns true so that any get commands, upon getting this node, will ignore the node as though it were invalid.
+    */
+   @Override
+   public boolean isValid()
+   {
+      return false;
+   }
+
+   /**
+    * A no-op.
+    */
+   @Override
+   public void copyForUpdate(DataContainer d, boolean b)
+   {
+      // no op
+   }
+}
\ No newline at end of file

Copied: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/ReadCommittedEntry.java (from rev 6851, core/branches/flat/src/main/java/org/jboss/cache/mvcc/ReadCommittedNode.java)
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/ReadCommittedEntry.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/ReadCommittedEntry.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,226 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.mvcc;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.mvcc.ReadCommittedNode;
+import org.jboss.starobrno.DataContainer;
+import static org.jboss.starobrno.mvcc.ReadCommittedEntry.Flags.*;
+
+import java.util.Map.Entry;
+
+/**
+ * A node delegate that encapsulates read committed semantics when writes are initiated, committed or rolled back.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class ReadCommittedEntry implements MVCCEntry
+{
+   private static final Log log = LogFactory.getLog(ReadCommittedNode.class);
+   private static final boolean trace = log.isTraceEnabled();
+
+   protected volatile Entry entry, backup;
+   protected byte flags = 0;
+
+   public Object getKey()
+   {
+      return entry.getKey();
+   }
+
+   public Object getValue()
+   {
+      return entry.getValue();
+   }
+
+   public Object setValue(Object value)
+   {
+      return entry.setValue(value);
+   }
+
+   protected static enum Flags
+   {
+      CHANGED(0x1), CREATED(0x2), DELETED(0x4), VALID(0x8);
+      final byte mask;
+
+      Flags(int mask)
+      {
+         this.mask = (byte) mask;
+      }
+   }
+
+   @SuppressWarnings("unchecked")
+   public ReadCommittedEntry(Entry entry)
+   {
+      setValid(true);
+      this.entry = entry;
+   }
+
+   /**
+    * Tests whether a flag is set.
+    *
+    * @param flag flag to test
+    * @return true if set, false otherwise.
+    */
+   protected final boolean isFlagSet(Flags flag)
+   {
+      return (flags & flag.mask) != 0;
+   }
+
+   /**
+    * Unility method that sets the value of the given flag to true.
+    *
+    * @param flag flag to set
+    */
+   protected final void setFlag(Flags flag)
+   {
+      flags |= flag.mask;
+   }
+
+   /**
+    * Utility method that sets the value of the flag to false.
+    *
+    * @param flag flag to unset
+    */
+   protected final void unsetFlag(Flags flag)
+   {
+      flags &= ~flag.mask;
+   }
+
+   public boolean isNullEntry()
+   {
+      return false;
+   }
+
+   public void copyForUpdate(DataContainer container, boolean writeSkewCheck)
+   {
+      if (isFlagSet(CHANGED)) return; // already copied
+
+      setFlag(CHANGED);  // mark as changed
+      if (!isFlagSet(CREATED)) // if newly created, then nothing to copy.
+      {
+         backup = entry;
+         // don't copy the NodeReference but the InternalNode that the NodeReference delegates to.
+         Entry backupDelegationTarget = ((EntryReference) backup).getDelegate();
+         entry = copyEntry(backupDelegationTarget);
+      }
+   }
+
+   protected Entry copyEntry(Entry e)
+   {
+      if (e instanceof EntryReference)
+      {
+         return new EntryReference(copyEntry(e));
+      }
+      else
+      {
+         return new EntryImpl(e);
+      }
+   }
+
+   @SuppressWarnings("unchecked")
+   public void commitUpdate(InvocationContext ctx, DataContainer container)
+   {
+      // only do stuff if there are changes.
+      if (isFlagSet(CHANGED))
+      {
+         if (trace)
+            log.trace("Updating entry [" + getKey() + "].  deleted=" + isDeleted() + " valid=" + isValid() + " changed=" + isChanged() + " created=" + isFlagSet(CREATED));
+         updateEntry(container);
+         container.putEntry(entry);
+         reset();
+      }
+   }
+
+   private void reset()
+   {
+      backup = null;
+      flags = 0;
+      setValid(true);
+   }
+
+   /**
+    * Updates state changes on the current node in the underlying data structure.
+    *
+    * @param ctx           invocation context
+    * @param dataContainer data container
+    */
+   @SuppressWarnings("unchecked")
+   protected void updateEntry(DataContainer dataContainer)
+   {
+      // swap refs
+      if (!isFlagSet(CREATED)) ((EntryReference) backup).setDelegate(entry);
+      entry = backup;
+   }
+
+   public void rollbackUpdate()
+   {
+      entry = backup;
+      reset();
+   }
+
+   public boolean isChanged()
+   {
+      return isFlagSet(CHANGED);
+   }
+
+   public boolean isValid()
+   {
+      return isFlagSet(VALID);
+   }
+
+   public void setValid(boolean valid)
+   {
+      if (valid)
+         setFlag(VALID);
+      else
+         unsetFlag(VALID);
+   }
+
+   public boolean isCreated()
+   {
+      return isFlagSet(CREATED);
+   }
+
+   public void setCreated(boolean created)
+   {
+      if (created)
+         setFlag(CREATED);
+      else
+         unsetFlag(CREATED);
+   }
+
+   public boolean isDeleted()
+   {
+      return isFlagSet(DELETED);
+   }
+
+   public void setDeleted(boolean deleted)
+   {
+      if (deleted)
+         setFlag(DELETED);
+      else
+         unsetFlag(DELETED);
+   }
+}
\ No newline at end of file

Copied: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/RepeatableReadEntry.java (from rev 6851, core/branches/flat/src/main/java/org/jboss/cache/mvcc/RepeatableReadNode.java)
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/RepeatableReadEntry.java	                        (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/RepeatableReadEntry.java	2008-10-07 16:22:07 UTC (rev 6854)
@@ -0,0 +1,80 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY 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 along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.starobrno.mvcc;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.mvcc.RepeatableReadNode;
+import org.jboss.cache.optimistic.DataVersioningException;
+import org.jboss.starobrno.DataContainer;
+import static org.jboss.starobrno.mvcc.ReadCommittedEntry.Flags.CHANGED;
+
+import java.util.Map.Entry;
+
+/**
+ * A node delegate that encapsulates repeatable read semantics when writes are initiated, committed or rolled back.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 3.0
+ */
+public class RepeatableReadEntry extends ReadCommittedEntry
+{
+   private static final Log log = LogFactory.getLog(RepeatableReadNode.class);
+
+   public RepeatableReadEntry(Entry entry)
+   {
+      super(entry);
+   }
+
+   @Override
+   public void copyForUpdate(DataContainer container, boolean writeSkewCheck)
+   {
+      if (isFlagSet(CHANGED)) return; // already copied
+
+      // mark node as changed.
+      setFlag(CHANGED);
+
+      if (writeSkewCheck)
+      {
+         // check for write skew.
+         Entry actualEntry = null; // get this from somewhere - container.peekInternalNode(fqn, true);
+
+         if (actualEntry != null && actualEntry != entry)
+         {
+            String errormsg = new StringBuilder().append("Detected write skew on key [").append(getKey()).append("].  Another process has changed the node since we last read it!").toString();
+            if (log.isWarnEnabled()) log.warn(errormsg + ".  Unable to copy node for update.");
+            throw new DataVersioningException(errormsg);
+         }
+      }
+
+      // make a backup copy
+      backup = entry;
+      entry = copyEntry(backup);
+   }
+
+   @Override
+   @SuppressWarnings("unchecked")
+   protected void updateEntry(DataContainer dataContainer)
+   {
+      entry = backup;
+   }
+}
\ No newline at end of file




More information about the jbosscache-commits mailing list