From jbosscache-commits at lists.jboss.org Wed Dec 10 10:10:13 2008 Content-Type: multipart/mixed; boundary="===============0922743582196616249==" MIME-Version: 1.0 From: jbosscache-commits at lists.jboss.org To: jbosscache-commits at lists.jboss.org Subject: [jbosscache-commits] JBoss Cache SVN: r7275 - in core/branches/flat/src: main/java/org/jboss/starobrno/commands/write and 3 other directories. Date: Wed, 10 Dec 2008 10:10:12 -0500 Message-ID: --===============0922743582196616249== Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Author: manik.surtani(a)jboss.com Date: 2008-12-10 10:10:12 -0500 (Wed, 10 Dec 2008) New Revision: 7275 Modified: core/branches/flat/src/main/java/org/jboss/starobrno/Cache.java core/branches/flat/src/main/java/org/jboss/starobrno/CacheDelegate.java core/branches/flat/src/main/java/org/jboss/starobrno/commands/write/PutK= eyValueCommand.java core/branches/flat/src/main/java/org/jboss/starobrno/commands/write/Repl= aceCommand.java core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/read_commi= tted/ReadCommittedLockTest.java core/branches/flat/src/test/java/org/jboss/starobrno/profiling/ProfileTe= st.java core/branches/flat/src/test/java/org/jboss/starobrno/profiling/TreeProfi= leTest.java core/branches/flat/src/test/java/org/jboss/starobrno/profiling/testinter= nals/Generator.java Log: - Implemented putForExternalRead - Fixed a bug in replace() - Added better test for replace() - Improved profiler tests Modified: core/branches/flat/src/main/java/org/jboss/starobrno/Cache.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/Cache.java 2008-12= -10 12:51:42 UTC (rev 7274) +++ core/branches/flat/src/main/java/org/jboss/starobrno/Cache.java 2008-12= -10 15:10:12 UTC (rev 7275) @@ -37,6 +37,33 @@ */ public interface Cache extends ConcurrentMap, Lifecycle { + /** + * Under special operating behavior, associates the value with the spec= ified key. + *
    + *
  • Only goes through if the key specified does not exist; no-op ot= herwise (similar to {@link java.util.concurrent.ConcurrentMap#replace(Objec= t, Object)}) + *
  • Force asynchronous mode for replication to prevent any blocking= .
  • + *
  • invalidation does not take place.
  • + *
  • 0ms lock timeout to prevent any blocking here either. If the lo= ck is not acquired, this method is a no-op, and swallows the timeout except= ion.
  • + *
  • Ongoing transactions are suspended before this call, so failure= s here will not affect any ongoing transactions.
  • + *
  • Errors and exceptions are 'silent' - logged at a much lower lev= el than normal, and this method does not throw exceptions
  • + *
+ * This method is for caching data that has an external representation = in storage, where, concurrent modification and + * transactions are not a consideration, and failure to put the data in= the cache should be treated as a 'suboptimal outcome' + * rather than a 'failing outcome'. + *

+ * An example of when this method is useful is when data is read from, = for example, a legacy datastore, and is cached before + * returning the data to the caller. Subsequent calls would prefer to = get the data from the cache and if the data doesn't exist + * in the cache, fetch again from the legacy datastore. + *

+ * See JBCACH= E-848 for details around this feature. + *

+ * + * @param key key with which the specified value is to be associated. + * @param value value to be associated with the specified key. + * @throws IllegalStateException if {@link #getCacheStatus()} would not= return {@link org.jboss.cache.CacheStatus#STARTED}. + */ + void putForExternalRead(K key, V value); + void evict(K key); = Configuration getConfiguration(); Modified: core/branches/flat/src/main/java/org/jboss/starobrno/CacheDelegat= e.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/CacheDelegate.java= 2008-12-10 12:51:42 UTC (rev 7274) +++ core/branches/flat/src/main/java/org/jboss/starobrno/CacheDelegate.java= 2008-12-10 15:10:12 UTC (rev 7275) @@ -21,6 +21,8 @@ */ package org.jboss.starobrno; = +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.jboss.cache.CacheStatus; import org.jboss.cache.Version; import org.jboss.cache.buddyreplication.BuddyManager; @@ -79,6 +81,7 @@ private EvictionManager evictionManager; private DataContainer dataContainer; private LockManager lockManager; + private static final Log log =3D LogFactory.getLog(CacheDelegate.class); = = @Inject @@ -131,7 +134,7 @@ = public V replace(K key, V value) { - ReplaceCommand command =3D commandsFactory.buildReplaceCommand(key, = value, null); + ReplaceCommand command =3D commandsFactory.buildReplaceCommand(key, = null, value); return (V) invoker.invoke(buildCtx(), command); } = @@ -206,6 +209,40 @@ throw new UnsupportedOperationException("Go away"); } = + public void putForExternalRead(K key, V value) + { + InvocationContext ctx =3D invocationContextContainer.get(); + Transaction ongoingTransaction =3D null; + try + { + if (transactionManager !=3D null && (ongoingTransaction =3D trans= actionManager.getTransaction()) !=3D null) + { + transactionManager.suspend(); + } + + // if the node exists then this should be a no-op. + ctx.getOptionOverrides().setFailSilently(true); + ctx.getOptionOverrides().setForceAsynchronous(true); + ctx.getOptionOverrides().setLockAcquisitionTimeout(0); + replace(key, value); + } + catch (Exception e) + { + if (log.isDebugEnabled()) log.debug("Caught exception while doing= putForExternalRead()", e); + } + finally + { + try + { + if (ongoingTransaction !=3D null) transactionManager.resume(on= goingTransaction); + } + catch (Exception e) + { + log.debug("Had problems trying to resume a transaction after p= utForExternalread()", e); + } + } + } + public void evict(K key) { EvictCommand command =3D commandsFactory.buildEvictCommand(key); Modified: core/branches/flat/src/main/java/org/jboss/starobrno/commands/wri= te/PutKeyValueCommand.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/commands/write/Put= KeyValueCommand.java 2008-12-10 12:51:42 UTC (rev 7274) +++ core/branches/flat/src/main/java/org/jboss/starobrno/commands/write/Put= KeyValueCommand.java 2008-12-10 15:10:12 UTC (rev 7275) @@ -79,7 +79,7 @@ { notifier.notifyCacheEntryModified(key, true, ctx); MVCCEntry e =3D ctx.lookupEntry(key); - Object o =3D null; + Object o; if (value instanceof Delta) { // magic Modified: core/branches/flat/src/main/java/org/jboss/starobrno/commands/wri= te/ReplaceCommand.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/commands/write/Rep= laceCommand.java 2008-12-10 12:51:42 UTC (rev 7274) +++ core/branches/flat/src/main/java/org/jboss/starobrno/commands/write/Rep= laceCommand.java 2008-12-10 15:10:12 UTC (rev 7275) @@ -57,7 +57,7 @@ { MVCCEntry e =3D ctx.lookupEntry(key); if (e =3D=3D null || e.isNullEntry()) return false; - if (oldValue.equals(e.getValue())) + if (oldValue =3D=3D null || oldValue.equals(e.getValue())) { e.setValue(newValue); return true; Modified: core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/rea= d_committed/ReadCommittedLockTest.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/test/java/org/jboss/starobrno/api/mvcc/read_comm= itted/ReadCommittedLockTest.java 2008-12-10 12:51:42 UTC (rev 7274) +++ core/branches/flat/src/test/java/org/jboss/starobrno/api/mvcc/read_comm= itted/ReadCommittedLockTest.java 2008-12-10 15:10:12 UTC (rev 7275) @@ -14,7 +14,7 @@ repeatableRead =3D false; } = - public void testVisibilityOfCommittedData() throws Exception + public void testVisibilityOfCommittedDataPut() throws Exception { Cache c =3D threadLocal.get().cache; c.put("k", "v"); @@ -42,4 +42,33 @@ assert "v2".equals(c.get("k")) : "Should read committed data"; threadLocal.get().tm.commit(); } + + public void testVisibilityOfCommittedDataReplace() throws Exception + { + Cache c =3D threadLocal.get().cache; + c.put("k", "v"); + + assert "v".equals(c.get("k")); + + // start a tx and read K + threadLocal.get().tm.begin(); + assert "v".equals(c.get("k")); + assert "v".equals(c.get("k")); + Transaction reader =3D threadLocal.get().tm.suspend(); + + threadLocal.get().tm.begin(); + c.replace("k", "v2"); + Transaction writer =3D threadLocal.get().tm.suspend(); + + threadLocal.get().tm.resume(reader); + assert "v".equals(c.get("k")) : "Should not read uncommitted data"; + reader =3D threadLocal.get().tm.suspend(); + + threadLocal.get().tm.resume(writer); + threadLocal.get().tm.commit(); + + threadLocal.get().tm.resume(reader); + assert "v2".equals(c.get("k")) : "Should read committed data"; + threadLocal.get().tm.commit(); + } } Modified: core/branches/flat/src/test/java/org/jboss/starobrno/profiling/Pr= ofileTest.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/test/java/org/jboss/starobrno/profiling/ProfileT= est.java 2008-12-10 12:51:42 UTC (rev 7274) +++ core/branches/flat/src/test/java/org/jboss/starobrno/profiling/ProfileT= est.java 2008-12-10 15:10:12 UTC (rev 7275) @@ -5,16 +5,14 @@ import org.jboss.cache.lock.IsolationLevel; import org.jboss.starobrno.Cache; import org.jboss.starobrno.config.Configuration; +import org.jboss.starobrno.profiling.testinternals.Generator; +import org.jboss.starobrno.profiling.testinternals.TaskRunner; import org.jboss.starobrno.util.TestingUtil; import org.testng.annotations.Test; = import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Random; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; = /** @@ -44,7 +42,6 @@ protected static final boolean USE_SLEEP =3D false; // throttle generat= ion a bit = private List keys =3D new ArrayList(MAX_OVERALL_KEYS); - private Random r =3D new Random(); = Log log =3D LogFactory.getLog(ProfileTest.class); = @@ -54,7 +51,7 @@ Cache c =3D (Cache) cache; c.getConfiguration().setCacheMode(Configuration.CacheMode.LOCAL); c.getConfiguration().setConcurrencyLevel(2000); - c.getConfiguration().setIsolationLevel(IsolationLevel.READ_COMMITTED= ); + c.getConfiguration().setIsolationLevel(IsolationLevel.REPEATABLE_REA= D); runCompleteTest(); } = @@ -80,8 +77,13 @@ keys.clear(); for (int i =3D 0; i < MAX_OVERALL_KEYS; i++) { - Object key =3D createRandomKey(r); - while (keys.contains(key)) key =3D createRandomKey(r); + Object key; + do + { + key =3D Generator.createRandomKey(); + } + while (keys.contains(key)); + if (i % 10 =3D=3D 0) { log.warn("Generated " + i + " keys"); @@ -93,12 +95,7 @@ log.warn("Finished init() phase. " + printDuration(duration)); } = - private Object createRandomKey(Random r) - { - return Integer.toHexString(r.nextInt(Integer.MAX_VALUE)); - } = - protected void startup() { long startTime =3D System.currentTimeMillis(); @@ -111,7 +108,7 @@ private void warmup() throws InterruptedException { long startTime =3D System.currentTimeMillis(); - ExecutorService exec =3D Executors.newFixedThreadPool(NUM_THREADS); + TaskRunner exec =3D new TaskRunner(NUM_THREADS); log.warn("Starting warmup"); // creates all the Fqns since this can be expensive and we don't rea= lly want to measure this (for now) for (final Object key : keys) @@ -133,7 +130,7 @@ { public void run() { - Object key =3D keys.get(r.nextInt(MAX_OVERALL_KEYS)); + Object key =3D Generator.getRandomElement(keys); cache.get(key); cache.put(key, "Value"); cache.remove(key); @@ -141,8 +138,7 @@ }); } = - exec.shutdown(); - exec.awaitTermination(360, TimeUnit.SECONDS); + exec.stop(); = long duration =3D System.currentTimeMillis() - startTime; log.warn("Finished warmup. " + printDuration(duration)); @@ -154,7 +150,7 @@ = private void doTest() throws Exception { - ExecutorService exec =3D Executors.newFixedThreadPool(NUM_THREADS); + TaskRunner exec =3D new TaskRunner(NUM_THREADS); log.warn("Starting test"); int i; long print =3D NUM_OPERATIONS / 10; @@ -187,11 +183,7 @@ } log.warn("Finished generating runnables; awaiting executor completio= n"); // wait for executors to complete! - exec.shutdown(); - while (!exec.awaitTermination(((long) i), TimeUnit.SECONDS)) - { - Thread.sleep(1); - } + exec.stop(); = // wait up to 1 sec for each call? long elapsedTimeNanos =3D System.nanoTime() - stElapsed; @@ -229,12 +221,12 @@ = public void run() { - Object key =3D keys.get(r.nextInt(MAX_OVERALL_KEYS)); + Object key =3D Generator.getRandomElement(keys); long d =3D 0, st =3D 0; switch (mode) { case PUT: - Object value =3D getRandomString(); + Object value =3D Generator.getRandomString(); st =3D System.nanoTime(); cache.put(key, value); d =3D System.nanoTime() - st; @@ -284,18 +276,6 @@ } } = - private String getRandomString() - { - StringBuilder sb =3D new StringBuilder(); - int len =3D r.nextInt(10); - - for (int i =3D 0; i < len; i++) - { - sb.append((char) (63 + r.nextInt(26))); - } - return sb.toString(); - } - protected String printDuration(long duration) { if (duration > 2000) Modified: core/branches/flat/src/test/java/org/jboss/starobrno/profiling/Tr= eeProfileTest.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/test/java/org/jboss/starobrno/profiling/TreeProf= ileTest.java 2008-12-10 12:51:42 UTC (rev 7274) +++ core/branches/flat/src/test/java/org/jboss/starobrno/profiling/TreeProf= ileTest.java 2008-12-10 15:10:12 UTC (rev 7275) @@ -60,7 +60,7 @@ cfg.setConcurrencyLevel(2000); cfg.setLockAcquisitionTimeout(120000); cfg.setLockParentForChildInsertRemove(true); - cfg.setIsolationLevel(IsolationLevel.READ_COMMITTED); + cfg.setIsolationLevel(IsolationLevel.REPEATABLE_READ); Cache c =3D new UnitTestCacheFactory().createCache(cfg); cache =3D new TreeCacheImpl(c); } Modified: core/branches/flat/src/test/java/org/jboss/starobrno/profiling/te= stinternals/Generator.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/test/java/org/jboss/starobrno/profiling/testinte= rnals/Generator.java 2008-12-10 12:51:42 UTC (rev 7274) +++ core/branches/flat/src/test/java/org/jboss/starobrno/profiling/testinte= rnals/Generator.java 2008-12-10 15:10:12 UTC (rev 7275) @@ -33,4 +33,9 @@ for (int i =3D 0; i < depth; i++) fqnElements.add(Integer.toHexStrin= g(r.nextInt(Integer.MAX_VALUE))); return Fqn.fromList(fqnElements, true); } + + public static Object createRandomKey() + { + return Integer.toHexString(r.nextInt(Integer.MAX_VALUE)); + } } --===============0922743582196616249==--