From jbosscache-commits at lists.jboss.org Tue Oct 7 12:22:08 2008 Content-Type: multipart/mixed; boundary="===============6952425969858258532==" MIME-Version: 1.0 From: jbosscache-commits at lists.jboss.org To: jbosscache-commits at lists.jboss.org Subject: [jbosscache-commits] JBoss Cache SVN: r6854 - in core/branches/flat/src/main/java/org/jboss/starobrno: context and 1 other directories. Date: Tue, 07 Oct 2008 12:22:08 -0400 Message-ID: --===============6952425969858258532== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: manik.surtani(a)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/UnsortedDataContain= er.java core/branches/flat/src/main/java/org/jboss/starobrno/context/ core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationC= ontext.java core/branches/flat/src/main/java/org/jboss/starobrno/context/InvocationC= ontextImpl.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/NullMarkerEntr= y.java core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/ReadCommittedE= ntry.java core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/RepeatableRead= Entry.java Log: Another pint of Starobrno Added: core/branches/flat/src/main/java/org/jboss/starobrno/DataContainer.j= ava =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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 (manik(a)jbo= ss.org) + * @since 3.0 + */ +public interface DataContainer +{ + Set> getEntries(); + + Entry getEntry(K k); + + void putEntry(Entry entry); + + boolean exists(Entry entry); +} Added: core/branches/flat/src/main/java/org/jboss/starobrno/UnsortedDataCon= tainer.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/UnsortedDataContai= ner.java (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/UnsortedDataContai= ner.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 (manik(a)jbo= ss.org) + * @since 3.0 + */ +public class UnsortedDataContainer implements DataContainer +{ + Set> entries =3D new LinkedHashSet>(); + + public Set> getEntries() + { + return entries; + } + + public Entry getEntry(K k) + { + if (k =3D=3D null) throw new NullPointerException("I don't like null= s!"); + for (Entry e : entries) + { + if (k.equals(e.getKey())) return e; + } + return null; + } + + public void putEntry(Entry kvEntry) + { + entries.add(kvEntry); + } + + public boolean exists(Entry kvEntry) + { + return getEntry(kvEntry.getKey()) !=3D null; + } +} Added: core/branches/flat/src/main/java/org/jboss/starobrno/context/Invocat= ionContext.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/context/Invocation= Context.java (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/context/Invocation= Context.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 (manik(a)jbo= ss.org) + * @since 3.0 + */ +public interface InvocationContext +{ + MVCCEntry lookupEntry(Object key); + + Map getLookedUpEntries(); + + void putLookedUpEntry(MVCCEntry e); + + void putLookedUpEntries(Set 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 getKeysLocked(); + + void addAllKeysLocked(List 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/Invocat= ionContextImpl.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/context/Invocation= ContextImpl.java (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/context/Invocation= ContextImpl.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 (manik(a)jbo= ss.org) + * @since 3.0 + */ +public class InvocationContextImpl implements InvocationContext +{ + private static final Log log =3D LogFactory.getLog(InvocationContext.cl= ass); + private static final boolean trace =3D log.isTraceEnabled(); + + private Transaction transaction; + private GlobalTransaction globalTransaction; + protected TransactionContext transactionContext; + private Option optionOverrides; + // defaults to true. + private boolean originLocal =3D true; + private boolean localRollbackOnly; + @Deprecated + private MethodCall methodCall; + @Deprecated + private VisitableCommand command; + + /** + * LinkedHashSet of locks acquired by the invocation. We use a LinkedHa= shSet because we need efficient Set semantics + * but also need guaranteed ordering for use by lock release code (see = JBCCACHE-874). + *

+ * This needs to be unchecked since we support both MVCC (Fqns held her= e) or legacy Opt/Pess locking (NodeLocks held here). + * once we drop support for opt/pess locks we can genericise this to co= ntain Fqns. - Manik Surtani, June 2008 + */ + protected LinkedHashSet invocationLocks; + private HashMap lookedUpEntries =3D null; + + /** + * Retrieves a node from the registry of looked up nodes in the current= scope. + *

+ * If a transaction is in progress, implementations should delegate to = {@link org.jboss.cache.transaction.MVCCTransactionContext#lookUpNode(Fqn)} + *

+ * + * @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 !=3D null) return transactionContext.lookup= Entry(k); +// return lookedUpEntries =3D=3D null ? null : lookedUpEntries.get(k); + return null; + } + + /** + * Puts an entry in the registry of looked up nodes in the current scop= e. + *

+ * If a transaction is in progress, implementations should delegate to = {@link org.jboss.cache.transaction.MVCCTransactionContext#putLookedUpNode(F= qn, NodeSPI)} + *

+ * + * @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 !=3D null) +// transactionContext.putLookedUpEntry(e); +// else +// { +// if (lookedUpEntries =3D=3D null) lookedUpEntries =3D new HashMa= p(4); +// lookedUpEntries.put(e.getKey(), e); +// } + } + + public void putLookedUpEntries(Set lookedUpEntries) + { + // TODO: Fix this after we have a Transaction context that works. +// if (transactionContext !=3D null) +// transactionContext.putLookedUpEntries(lookedUpEntries); +// else +// { +// if (this.lookedUpEntries =3D=3D null) +// this.lookedUpEntries =3D new HashMap(); +// +// for (MVCCEntry e: lookedUpEntries) this.lookedUpEntries.put(e.g= etKey(), e); +// } + } + + /** + * Clears the registry of looked up nodes. + *

+ * If a transaction is in progress, implementations should delegate to = {@link org.jboss.cache.transaction.MVCCTransactionContext#clearLookedUpNode= s()}. + */ + public void clearLookedUpEntries() + { + // TODO: see if we can reinstate common behaviour once we have the I= CI calling ctx.reset() instead of ctx.clearLookedUpNodes() +// if (transactionContext !=3D null) +// transactionContext.clearLookedUpNodes(); +// else + + if (lookedUpEntries !=3D null) lookedUpEntries.clear(); + } + + /** + * Retrieves a map of nodes looked up within the current invocation's s= cope. + *

+ * If a transaction is in progress, implementations should delegate to = {@link org.jboss.cache.transaction.MVCCTransactionContext#getLookedUpNodes(= )}. + *

+ * + * @return a map of looked up nodes. + */ + @SuppressWarnings("unchecked") + public Map getLookedUpEntries() + { + // TODO: Fix this after we have a Transaction context that works. +// if (transactionContext !=3D null) return transactionContext.getLoo= kedUpNodes(); +// return (Map) (lookedUpEntries =3D=3D null ? Collecti= ons.emptyMap() : lookedUpEntries); + return null; + } + + @SuppressWarnings("unchecked") + public InvocationContext copy() + { + InvocationContextImpl copy =3D new InvocationContextImpl(); + doCopy(copy); + if (lookedUpEntries !=3D null) copy.lookedUpEntries =3D (HashMap) 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 =3D 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 =3D transaction; + } + + /** + * @return the transaction entry associated with the current transactio= n, 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 threa= d. + * + * @param transactionContext transaction context to set + * @since 2.2.0 + */ + public void setTransactionContext(TransactionContext transactionContext) + { + this.transactionContext =3D 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 =3D globalTransaction; + } + + + /** + * Retrieves the option overrides associated with this invocation + * + * @return the option overrides associated with this invocation + */ + public Option getOptionOverrides() + { + if (optionOverrides =3D=3D null) + { + optionOverrides =3D new Option(); + } + return optionOverrides; + } + + /** + * @return true of no options have been set on this context, false othe= rwise. + */ + public boolean isOptionsUninitialised() + { + return optionOverrides =3D=3D null; + } + + /** + * Sets the option overrides to be associated with this invocation + * + * @param optionOverrides options to set + */ + public void setOptionOverrides(Option optionOverrides) + { + this.optionOverrides =3D 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. + *

+ * Note that if a transaction is in scope, implementations should retri= eve these locks from the {@link org.jboss.cache.transaction.TransactionCont= ext}. + * Retrieving locks from this method should always ensure they are retr= ieved from the appropriate scope. + *

+ * Note that currently (as of 3.0.0) this list is unchecked. This is t= o 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 st= rongly typed to return List. + * + * @return locks held in current scope. + */ + @SuppressWarnings("unchecked") + public List getKeysLocked() + { + // first check transactional scope + if (transactionContext !=3D null) return transactionContext.getLocks= (); + return invocationLocks =3D=3D null || invocationLocks.isEmpty() ? Co= llections.emptyList() : Immutables.immutableListConvert(invocationLocks); + } + + /** + * Adds a List of locks to the currently maintained collection of locks= acquired. + *

+ * Note that if a transaction is in scope, implementations should recor= d locks on the {@link org.jboss.cache.transaction.TransactionContext}. + * Adding locks using this method should always ensure they are applied= to the appropriate scope. + *

+ * Note that currently (as of 3.0.0) this list is unchecked. This is t= o 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 st= rongly typed to accept List. + * + * @param locks locks to add + */ + @SuppressWarnings("unchecked") + public void addAllKeysLocked(List locks) + { + // first check transactional scope + if (transactionContext !=3D null) + { + transactionContext.addAllLocks(locks); + } + else + { + // no need to worry about concurrency here - a context is only va= lid for a single thread. + if (invocationLocks =3D=3D null) invocationLocks =3D new LinkedHa= shSet(4); + invocationLocks.addAll(locks); + } + } + + /** + * Adds a lock to the currently maintained collection of locks acquired. + *

+ * Note that if a transaction is in scope, implementations should recor= d this lock on the {@link org.jboss.cache.transaction.TransactionContext}. + * Using this method should always ensure that the appropriate scope is= used. + *

+ * Note that currently (as of 3.0.0) this lock is weakly typed. This i= s 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 st= rongly typed to accept {@link Fqn}. + * + * @param lock lock to add + */ + @SuppressWarnings("unchecked") + public void addKeyLocked(Object lock) + { + // first check transactional scope + if (transactionContext !=3D null) + { + transactionContext.addLock(lock); + } + else + { + // no need to worry about concurrency here - a context is only va= lid for a single thread. + if (invocationLocks =3D=3D null) invocationLocks =3D new LinkedHa= shSet(4); + invocationLocks.add(lock); + } + } + + /** + * Removes a lock from the currently maintained collection of locks acq= uired. + *

+ * Note that if a transaction is in scope, implementations should remov= e 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. + *

+ * Note that currently (as of 3.0.0) this lock is weakly typed. This i= s 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 st= rongly typed to accept {@link Fqn}. + * + * @param lock lock to remove + */ + @SuppressWarnings("unchecked") + public void removeKeyLocked(Object lock) + { + // first check transactional scope + if (transactionContext !=3D null) + { + transactionContext.removeLock(lock); + } + else + { + // no need to worry about concurrency here - a context is only va= lid for a single thread. + if (invocationLocks !=3D null) invocationLocks.remove(lock); + } + } + + /** + * Clears all locks from the currently maintained collection of locks a= cquired. + *

+ * 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 appr= opriate scope. + *

+ * Note that currently (as of 3.0.0) this lock is weakly typed. This i= s 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 st= rongly typed to accept {@link Fqn}. + */ + public void clearKeysLocked() + { + // first check transactional scope + if (transactionContext !=3D null) + { + transactionContext.clearLocks(); + } + else + { + // no need to worry about concurrency here - a context is only va= lid for a single thread. + if (invocationLocks !=3D 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 appropri= ate 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 !=3D null) + { + return transactionContext.hasLock(lock); + } + else + { + return invocationLocks !=3D 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.Pe= ssimisticLockInterceptor}. + */ + public boolean isLockingSuppressed() + { + return getOptionOverrides() !=3D null && getOptionOverrides().isSupp= ressLocking(); + } + + /** + * 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 =3D 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 =3D null; + globalTransaction =3D null; + optionOverrides =3D null; + originLocal =3D true; + invocationLocks =3D null; + methodCall =3D null; + command =3D null; + if (lookedUpEntries !=3D null) + { + lookedUpEntries.clear(); + lookedUpEntries =3D null; + } + } + + /** + * Sets the state of the InvocationContext based on the template contex= t passed in + * + * @param template template to copy from + */ + public void setState(InvocationContext template) + { + if (template =3D=3D 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 =3D=3D null) + { + methodCall =3D createMethodCall(); + } + return methodCall; + } + + @SuppressWarnings("deprecation") + private MethodCall createMethodCall() + { + if (command =3D=3D null) return null; + MethodCall call =3D 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.jb= oss.cache.commands.ReplicableCommand} instance passed in along with an Invo= cationContext. + */ + @Deprecated + public void setMethodCall(MethodCall methodCall) + { + this.methodCall =3D 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 el= se. + if (getOptionOverrides() !=3D null + && getOptionOverrides().getLockAcquisitionTimeout() >=3D 0) + { + timeout =3D getOptionOverrides().getLockAcquisitionTimeout(); + } + return timeout; + } + + /** + * This is only used for backward compatibility with old interceptors i= mplementation and should NOT be + * use by any new custom interceptors. The commands is now passed in as= the second param in each implementing + * handlers (handler =3D method in ChainedInterceptor class) + * + * @param cacheCommand command to set + */ + @Deprecated + @SuppressWarnings("deprecation") + public void setCommand(VisitableCommand cacheCommand) + { + this.command =3D 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 inv= ocation, and this transaction is in a valid state. + */ + public boolean isValidTransaction() + { + // ought to move to the transaction context + return transaction !=3D null && TransactionTable.isValid(transaction= ); + } + + /** + * Throws the given throwable provided no options suppress or prevent t= his 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 el= se. + Option optionOverride =3D getOptionOverrides(); + boolean shouldRethtrow =3D optionOverride =3D=3D null || !optionOver= ride.isFailSilently(); + if (!shouldRethtrow) + { + if (trace) + log.trace("There was a problem handling this request, but fail= Silently was set, so suppressing exception", e); + return; + } + throw e; + } + + @SuppressWarnings("unchecked") + protected void doCopy(InvocationContext c) + { + InvocationContextImpl copy =3D (InvocationContextImpl) c; + copy.command =3D command; + copy.globalTransaction =3D globalTransaction; + copy.invocationLocks =3D invocationLocks =3D=3D null ? null : new Li= nkedHashSet(invocationLocks); + copy.localRollbackOnly =3D localRollbackOnly; + copy.optionOverrides =3D optionOverrides =3D=3D null ? null : option= Overrides.copy(); + copy.originLocal =3D originLocal; + copy.transaction =3D transaction; + copy.transactionContext =3D transactionContext; + } +} Added: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryImpl.= java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryImpl.jav= a (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryImpl.jav= a 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 implements Entry +{ + private K key; + private V value; + + public EntryImpl() + { + } + + public EntryImpl(Entry e) + { + this.key =3D e.getKey(); + this.value =3D e.getValue(); + } + + public EntryImpl(K key, V value) + { + this.key =3D key; + this.value =3D value; + } + + public K getKey() + { + return key; + } + + public V getValue() + { + return value; + } + + public V setValue(V value) + { + V oldValue =3D this.value; + this.value =3D value; + return oldValue; + } + + public boolean equals(Object o) + { + if (this =3D=3D o) return true; + if (o =3D=3D null || getClass() !=3D o.getClass()) return false; + + EntryImpl entry =3D (EntryImpl) o; + + if (key !=3D null ? !key.equals(entry.key) : entry.key !=3D null) re= turn false; + if (value !=3D null ? !value.equals(entry.value) : entry.value !=3D = null) return false; + + return true; + } + + public int hashCode() + { + int result; + result =3D (key !=3D null ? key.hashCode() : 0); + result =3D 31 * result + (value !=3D null ? value.hashCode() : 0); + return result; + } + + public String toString() + { + return "EntryImpl{" + + "key=3D" + key + + ", value=3D" + value + + '}'; + } +} Copied: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryRefe= rence.java (from rev 6851, core/branches/flat/src/main/java/org/jboss/cache= /mvcc/NodeReference.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryReferenc= e.java (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/EntryReferenc= e.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 contribut= ors + * 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.jbo= ss.cache.InternalNode}. Simple indirection + * is all this class does, allowing other processes to change the delegate. + *

+ * The delegate is a volatile field so the class is thread safe. + *

+ * This is used to wrap all {@link org.jboss.cache.invocation.NodeInvocati= onDelegate}s in the {@link org.jboss.cache.DataContainer} + * when using {@link org.jboss.cache.config.Configuration.NodeLockingSchem= e#MVCC} and {@link org.jboss.cache.lock.IsolationLevel#READ_COMMITTED}. + *

+ * + * @author Manik Surtani (manik(a)jbo= ss.org) + * @see org.jboss.cache.mvcc.ReadCommittedNode + * @since 3.0 + */ +(a)ThreadSafe +public class EntryReference implements Entry +{ + transient volatile Entry delegate; + + public EntryReference(Entry delegate) + { + this.delegate =3D delegate; + } + + /** + * @return the InternalNode being delegated to. + */ + public final Entry 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 =3D=3D o) return true; + if (o =3D=3D null || getClass() !=3D o.getClass()) return false; + + EntryReference that =3D (EntryReference) o; + + if (delegate !=3D null ? !delegate.equals(that.delegate) : that.dele= gate !=3D null) return false; + + return true; + } + + @Override + public int hashCode() + { + return (delegate !=3D null ? delegate.hashCode() : 0); + } + + @Override + public String toString() + { + return "EntryReference{" + + "delegate=3D" + delegate + + '}'; + } + + public void setDelegate(Entry entry) + { + delegate =3D entry; + } +} \ No newline at end of file Added: core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/MVCCEntry.= java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/MVCCEntry.jav= a (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/MVCCEntry.jav= a 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 (manik(a)jbo= ss.org) + * @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/NullMarke= rEntry.java (from rev 6851, core/branches/flat/src/main/java/org/jboss/cach= e/mvcc/NullMarkerNode.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/NullMarkerEnt= ry.java (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/NullMarkerEnt= ry.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 contribut= ors + * 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 r= ead that returns a null can continue to return + * null. + * + * @author Manik Surtani (manik(a)jbo= ss.org) + * @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 t= his 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 t= his 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/ReadCommi= ttedEntry.java (from rev 6851, core/branches/flat/src/main/java/org/jboss/c= ache/mvcc/ReadCommittedNode.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/ReadCommitted= Entry.java (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/ReadCommitted= Entry.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 contribut= ors + * 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 (manik(a)jbo= ss.org) + * @since 3.0 + */ +public class ReadCommittedEntry implements MVCCEntry +{ + private static final Log log =3D LogFactory.getLog(ReadCommittedNode.cl= ass); + private static final boolean trace =3D log.isTraceEnabled(); + + protected volatile Entry entry, backup; + protected byte flags =3D 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 =3D (byte) mask; + } + } + + @SuppressWarnings("unchecked") + public ReadCommittedEntry(Entry entry) + { + setValid(true); + this.entry =3D 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) !=3D 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 |=3D 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 &=3D ~flag.mask; + } + + public boolean isNullEntry() + { + return false; + } + + public void copyForUpdate(DataContainer container, boolean writeSkewChe= ck) + { + if (isFlagSet(CHANGED)) return; // already copied + + setFlag(CHANGED); // mark as changed + if (!isFlagSet(CREATED)) // if newly created, then nothing to copy. + { + backup =3D entry; + // don't copy the NodeReference but the InternalNode that the Nod= eReference delegates to. + Entry backupDelegationTarget =3D ((EntryReference) backup).getDel= egate(); + entry =3D 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=3D" + i= sDeleted() + " valid=3D" + isValid() + " changed=3D" + isChanged() + " crea= ted=3D" + isFlagSet(CREATED)); + updateEntry(container); + container.putEntry(entry); + reset(); + } + } + + private void reset() + { + backup =3D null; + flags =3D 0; + setValid(true); + } + + /** + * Updates state changes on the current node in the underlying data str= ucture. + * + * @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 =3D backup; + } + + public void rollbackUpdate() + { + entry =3D 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/Repeatabl= eReadEntry.java (from rev 6851, core/branches/flat/src/main/java/org/jboss/= cache/mvcc/RepeatableReadNode.java) =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/RepeatableRea= dEntry.java (rev 0) +++ core/branches/flat/src/main/java/org/jboss/starobrno/mvcc/RepeatableRea= dEntry.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 contribut= ors + * 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 (manik(a)jbo= ss.org) + * @since 3.0 + */ +public class RepeatableReadEntry extends ReadCommittedEntry +{ + private static final Log log =3D LogFactory.getLog(RepeatableReadNode.c= lass); + + public RepeatableReadEntry(Entry entry) + { + super(entry); + } + + @Override + public void copyForUpdate(DataContainer container, boolean writeSkewChe= ck) + { + if (isFlagSet(CHANGED)) return; // already copied + + // mark node as changed. + setFlag(CHANGED); + + if (writeSkewCheck) + { + // check for write skew. + Entry actualEntry =3D null; // get this from somewhere - containe= r.peekInternalNode(fqn, true); + + if (actualEntry !=3D null && actualEntry !=3D entry) + { + String errormsg =3D new StringBuilder().append("Detected write= skew on key [").append(getKey()).append("]. Another process has changed t= he node since we last read it!").toString(); + if (log.isWarnEnabled()) log.warn(errormsg + ". Unable to cop= y node for update."); + throw new DataVersioningException(errormsg); + } + } + + // make a backup copy + backup =3D entry; + entry =3D copyEntry(backup); + } + + @Override + @SuppressWarnings("unchecked") + protected void updateEntry(DataContainer dataContainer) + { + entry =3D backup; + } +} \ No newline at end of file --===============6952425969858258532==--