JBoss Cache SVN: r6806 - in core/trunk/src: main/java/org/jboss/cache/loader/s3 and 1 other directories.
by jbosscache-commits@lists.jboss.org
Author: genman
Date: 2008-09-26 17:38:03 -0400 (Fri, 26 Sep 2008)
New Revision: 6806
Modified:
core/trunk/src/main/java/org/jboss/cache/loader/bdbje/BdbjeCacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/s3/S3CacheLoader.java
core/trunk/src/test/java/org/jboss/cache/loader/BdbjeCacheLoaderTest.java
Log:
JBCACHE-1368 - Optimize BDB & S3
Modified: core/trunk/src/main/java/org/jboss/cache/loader/bdbje/BdbjeCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/bdbje/BdbjeCacheLoader.java 2008-09-26 17:44:22 UTC (rev 6805)
+++ core/trunk/src/main/java/org/jboss/cache/loader/bdbje/BdbjeCacheLoader.java 2008-09-26 21:38:03 UTC (rev 6806)
@@ -552,9 +552,10 @@
private void doPut(Transaction txn, Fqn name, Map values)
throws Exception
{
-
// JBCACHE-769 -- make a defensive copy
- values = (values == null ? null : new HashMap(values));
+ if (values != null && !(values instanceof HashMap)) {
+ values = new HashMap(values);
+ }
/* To update-or-insert, try putNoOverwrite first, then a RMW cycle. */
DatabaseEntry dataEntry = makeDataEntry(values);
@@ -562,25 +563,11 @@
Cursor cursor = cacheDb.openCursor(txn, null);
try
{
- OperationStatus status = cursor.putNoOverwrite(keyEntry, dataEntry);
+ OperationStatus status = cursor.put(keyEntry, dataEntry);
if (status == OperationStatus.SUCCESS)
{
createParentNodes(cursor, name);
}
- else
- {
- DatabaseEntry foundData = new DatabaseEntry();
- status = cursor.getSearchKey(keyEntry, foundData, LockMode.RMW);
- if (status == OperationStatus.SUCCESS)
- {
- Map map = makeDataObject(foundData);
- if (values != null)
- {
- map.putAll(values);
- }
- cursor.putCurrent(makeDataEntry(map));
- }
- }
}
finally
{
Modified: core/trunk/src/main/java/org/jboss/cache/loader/s3/S3CacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/s3/S3CacheLoader.java 2008-09-26 17:44:22 UTC (rev 6805)
+++ core/trunk/src/main/java/org/jboss/cache/loader/s3/S3CacheLoader.java 2008-09-26 21:38:03 UTC (rev 6806)
@@ -320,7 +320,7 @@
*/
public Object put(Fqn name, Object key, Object value) throws Exception
{
- Map map = mayGet(name);
+ Map map = get(name);
Object oldValue;
if (map != null)
{
@@ -389,17 +389,6 @@
}
/**
- * Returns null if optimized; else fetches.
- */
- private Map mayGet(Fqn name) throws Exception
- {
- if (config.getOptimize())
- return null;
- else
- return get(name);
- }
-
- /**
* Removes a key from an FQN.
* Not very fast.
*/
@@ -425,14 +414,9 @@
*/
public void put(Fqn name, Map<Object, Object> values) throws Exception
{
- Map map = mayGet(name);
if (values == null)
values = Collections.emptyMap();
- if (map != null)
- map.putAll(values);
- else
- map = new HashMap(values);
- put0(name, map);
+ put0(name, values);
}
/**
Modified: core/trunk/src/test/java/org/jboss/cache/loader/BdbjeCacheLoaderTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/BdbjeCacheLoaderTest.java 2008-09-26 17:44:22 UTC (rev 6805)
+++ core/trunk/src/test/java/org/jboss/cache/loader/BdbjeCacheLoaderTest.java 2008-09-26 21:38:03 UTC (rev 6806)
@@ -14,6 +14,8 @@
@Test(groups = "functional")
public class BdbjeCacheLoaderTest extends CacheLoaderTestsBase
{
+
+ @Override
protected void configureCache() throws Exception
{
String tmpDir = System.getProperty("java.io.tmpdir", "/tmp");
16 years, 2 months
JBoss Cache SVN: r6805 - in core/trunk/src: test/java/org/jboss/cache/loader and 3 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-09-26 13:44:22 -0400 (Fri, 26 Sep 2008)
New Revision: 6805
Modified:
core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java
core/trunk/src/test/java/org/jboss/cache/loader/UnnecessaryLoadingTest.java
core/trunk/src/test/java/org/jboss/cache/mgmt/CacheLoaderTest.java
core/trunk/src/test/java/org/jboss/cache/mgmt/PassivationTest.java
core/trunk/src/test/java/org/jboss/cache/passivation/PassivationTestsBase.java
core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferTestBase.java
Log:
Fixed broken tests
Modified: core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java 2008-09-26 11:52:18 UTC (rev 6804)
+++ core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java 2008-09-26 17:44:22 UTC (rev 6805)
@@ -429,6 +429,7 @@
}
con = cf.getConnection();
+
ps = con.prepareStatement(config.getSelectNodeSql());
ps.setString(1, name.toString());
@@ -480,8 +481,6 @@
*/
protected void insertNode(Fqn name, Map dataMap, boolean rowMayExist)
{
- if (dataMap != null && !(dataMap instanceof HashMap))
- throw new RuntimeException("Cannot persist map of type " + dataMap.getClass());
Connection con = null;
PreparedStatement ps = null;
try
@@ -569,8 +568,6 @@
*/
protected void updateNode(Fqn name, Map<Object, Object> node)
{
- if (node != null && !(node instanceof HashMap))
- throw new RuntimeException("Cannot persist map of type " + node.getClass());
Connection con = null;
PreparedStatement ps = null;
try
Modified: core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java 2008-09-26 11:52:18 UTC (rev 6804)
+++ core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java 2008-09-26 17:44:22 UTC (rev 6805)
@@ -460,6 +460,8 @@
protected void storeAttributes(Fqn fqn, Map attrs) throws Exception
{
+ if (attrs != null && !(attrs instanceof HashMap))
+ throw new RuntimeException("Unsupporte dmap type " + attrs.getClass());
regionAwareMarshall(fqn, attrs);
}
@@ -467,6 +469,9 @@
protected void doMarshall(Fqn fqn, Object toMarshall) throws Exception
{
Map attrs = (Map) toMarshall;
+
+ if (attrs != null && !(attrs instanceof HashMap)) throw new RuntimeException("Map is " + attrs.getClass());
+
File f = getDirectory(fqn, true);
File child = new File(f, DATA);
if (!child.exists())
Modified: core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java 2008-09-26 11:52:18 UTC (rev 6804)
+++ core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java 2008-09-26 17:44:22 UTC (rev 6805)
@@ -28,7 +28,6 @@
import org.jboss.cache.config.CacheLoaderConfig;
import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
import org.jboss.cache.marshall.NodeData;
-import org.jboss.cache.util.Immutables;
import java.io.InputStream;
import java.io.ObjectInputStream;
@@ -122,17 +121,9 @@
}
//creation sequence important - we need to overwrite old values
- try
- {
- Object oldVal = existing.put(key, value);
- updateNode(name, existing);
- return oldVal;
- }
- catch (UnsupportedOperationException uoe)
- {
- log.error("Caught UOE - map is " + existing.getClass());
- throw uoe;
- }
+ Object oldVal = existing.put(key, value);
+ updateNode(name, existing);
+ return oldVal;
}
finally
{
@@ -194,7 +185,7 @@
fqn = nd.getFqn();
}
- Map attributes = nd.getAttributes() == null ? null : Immutables.immutableMapCopy(nd.getAttributes());
+ Map attributes = nd.getAttributes() == null ? null : new HashMap(nd.getAttributes());
populatePreparedStatementForInsert(fqn, attributes, ps);
if (!config.isBatchEnabled())
{
Modified: core/trunk/src/test/java/org/jboss/cache/loader/UnnecessaryLoadingTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/UnnecessaryLoadingTest.java 2008-09-26 11:52:18 UTC (rev 6804)
+++ core/trunk/src/test/java/org/jboss/cache/loader/UnnecessaryLoadingTest.java 2008-09-26 17:44:22 UTC (rev 6805)
@@ -5,6 +5,7 @@
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Node;
+import org.jboss.cache.NodeSPI;
import org.jboss.cache.config.CacheLoaderConfig;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
import static org.testng.AssertJUnit.*;
@@ -91,7 +92,8 @@
protected void assertDataNotLoaded(Fqn f)
{
- assertFalse("Data should not be loaded for node " + f, cache.peek(f, false).isDataLoaded());
+ NodeSPI n = cache.peek(f, true);
+ assertFalse("Data should not be loaded for node " + f, n != null && n.isDataLoaded());
}
@@ -186,14 +188,14 @@
replay(mockCacheLoader);
cache.put(child, m);
- assertDataNotLoaded(child);
+ assertDataLoaded(child);
// should load child data
// mockCacheLoader.expects(once()).method("get").with(eq(child));
cache.get(child, "foo");
- assertDataNotLoaded(child);
+ assertDataLoaded(child);
cache.get(child, "foo");
- assertDataNotLoaded(child);
+ assertDataLoaded(child);
cache.get(child, "foo2"); // does not exist, will trigger a load
assertDataLoaded(child);
@@ -324,8 +326,10 @@
expect(mockCacheLoader.get(eq(parent))).andReturn(null);
expect(mockCacheLoader.put(eq(parent), eq(k), eq(v))).andReturn(null);
- mockCacheLoader.put(eq(parent), eq(m));
- expect(mockCacheLoader.get(eq(parent))).andReturn(Collections.singletonMap((Object) k, (Object) v));
+ Map<Object, Object> toExpect = new HashMap<Object, Object>(m);
+ toExpect.put(k, v);
+ mockCacheLoader.put(eq(parent), eq(toExpect));
+ expect(mockCacheLoader.get(eq(parent))).andReturn(toExpect);
replay(mockCacheLoader);
cache.put(parent, k, v);
assertDataLoaded(parent);
@@ -333,15 +337,17 @@
// now evict
cache.evict(parent, false);
+ assertDataNotLoaded(parent);
+
// should not load
cache.put(parent, m);
- assertDataNotLoaded(parent);
+ assertDataLoaded(parent);
// now a get for an existing key should not trigger a load!
assertEquals("v2", cache.get(parent, "k2"));
- assertDataNotLoaded(parent);
+ assertDataLoaded(parent);
// but going a get for a nonexistent key should!
assertEquals(v, cache.get(parent, k));
Modified: core/trunk/src/test/java/org/jboss/cache/mgmt/CacheLoaderTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/mgmt/CacheLoaderTest.java 2008-09-26 11:52:18 UTC (rev 6804)
+++ core/trunk/src/test/java/org/jboss/cache/mgmt/CacheLoaderTest.java 2008-09-26 17:44:22 UTC (rev 6805)
@@ -30,7 +30,7 @@
assertNotNull("CacheStoreInterceptor not found.", store);
// verify cache loader statistics for entries loaded into cache
- int miss = 0;
+ int miss = 5;
int load = 0;
int stores = 5;
assertEquals("CacheLoaderLoads count error: ", load, loader.getCacheLoaderLoads());
@@ -91,6 +91,7 @@
// add a new node - this should cause a store
stores++;
+ miss++;
cache.put(POLAND, new HashMap<String, Object>());
assertEquals("CacheLoaderLoads count error: ", load, loader.getCacheLoaderLoads());
assertEquals("CacheLoaderMisses count error: ", miss, loader.getCacheLoaderMisses());
Modified: core/trunk/src/test/java/org/jboss/cache/mgmt/PassivationTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/mgmt/PassivationTest.java 2008-09-26 11:52:18 UTC (rev 6804)
+++ core/trunk/src/test/java/org/jboss/cache/mgmt/PassivationTest.java 2008-09-26 17:44:22 UTC (rev 6805)
@@ -35,7 +35,7 @@
assertNotNull("PassivationInterceptor not found.", pass);
System.out.println("count of misses " + act.getCacheLoaderMisses());
- int miss = 0;
+ int miss = 5;
int activations = 0;
// was 5 in 1.3 (one per attribute)
// now just Europe/Albania and Europe/Hungary were loaded
@@ -109,6 +109,7 @@
cache.put(POLAND, new HashMap<String, Object>());
cache.put(POLAND, CAPITAL, "Warsaw");
cache.put(POLAND, CURRENCY, "Zloty");
+ miss++;
assertEquals("CacheLoaderLoads count error: ", 1, act.getCacheLoaderLoads());
assertEquals("CacheLoaderMisses count error: ", miss, act.getCacheLoaderMisses());
assertEquals("Activations count error: ", activations, act.getActivations());
Modified: core/trunk/src/test/java/org/jboss/cache/passivation/PassivationTestsBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/passivation/PassivationTestsBase.java 2008-09-26 11:52:18 UTC (rev 6804)
+++ core/trunk/src/test/java/org/jboss/cache/passivation/PassivationTestsBase.java 2008-09-26 17:44:22 UTC (rev 6805)
@@ -1319,7 +1319,16 @@
List<Modification> list = new ArrayList<Modification>();
+ Map<String, String> map = new HashMap<String, String>();
+ map.put("five", "six");
+ map.put("seven", "eight");
Modification mod = new Modification();
+ mod.setType(Modification.ModificationType.PUT_DATA);
+ mod.setFqn(FQN);
+ mod.setData(map);
+ list.add(mod);
+
+ mod = new Modification();
mod.setType(Modification.ModificationType.PUT_KEY_VALUE);
mod.setFqn(FQN);
mod.setKey("one");
@@ -1333,15 +1342,6 @@
mod.setValue("four");
list.add(mod);
- Map<String, String> map = new HashMap<String, String>();
- map.put("five", "six");
- map.put("seven", "eight");
- mod = new Modification();
- mod.setType(Modification.ModificationType.PUT_DATA);
- mod.setFqn(FQN);
- mod.setData(map);
- list.add(mod);
-
return list;
}
Modified: core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferTestBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferTestBase.java 2008-09-26 11:52:18 UTC (rev 6804)
+++ core/trunk/src/test/java/org/jboss/cache/statetransfer/StateTransferTestBase.java 2008-09-26 17:44:22 UTC (rev 6805)
@@ -27,6 +27,7 @@
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Region;
+import org.jboss.cache.config.CacheLoaderConfig;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
@@ -241,8 +242,9 @@
+ prop.getProperty("cache.jdbc.node.type") + "\n" + "cache.jdbc.sql-concat="
+ prop.getProperty("cache.jdbc.sql-concat");
- c.setCacheLoaderConfig(getSingleCacheLoaderConfig("", "org.jboss.cache.loader.JDBCCacheLoader",
- props, false, true, false));
+ CacheLoaderConfig clc = getSingleCacheLoaderConfig("", "org.jboss.cache.loader.JDBCCacheLoader", props, false, true, false);
+ clc.getFirstCacheLoaderConfig().setPurgeOnStartup(true);
+ c.setCacheLoaderConfig(clc);
}
else
{
16 years, 2 months
JBoss Cache SVN: r6804 - core/trunk/src/test/java/org/jboss/cache/factories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-09-26 07:52:18 -0400 (Fri, 26 Sep 2008)
New Revision: 6804
Modified:
core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainFactoryTest.java
Log:
Updated test to deal with changes made in JBCACHE-1368 (Optimize the CacheLoader.putAll() method so reads are not necessary)
Modified: core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainFactoryTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainFactoryTest.java 2008-09-26 11:50:32 UTC (rev 6803)
+++ core/trunk/src/test/java/org/jboss/cache/factories/InterceptorChainFactoryTest.java 2008-09-26 11:52:18 UTC (rev 6804)
@@ -6,11 +6,11 @@
import org.jboss.cache.config.BuddyReplicationConfig;
import org.jboss.cache.config.CacheLoaderConfig;
import org.jboss.cache.config.CacheLoaderConfig.IndividualCacheLoaderConfig;
+import org.jboss.cache.config.Configuration;
import static org.jboss.cache.config.Configuration.CacheMode.*;
import static org.jboss.cache.config.Configuration.NodeLockingScheme.MVCC;
import static org.jboss.cache.config.Configuration.NodeLockingScheme.OPTIMISTIC;
import org.jboss.cache.config.EvictionConfig;
-import org.jboss.cache.config.Configuration;
import org.jboss.cache.interceptors.*;
import org.jboss.cache.interceptors.base.CommandInterceptor;
import org.jboss.cache.loader.DummyInMemoryCacheLoader;
@@ -37,7 +37,7 @@
configuration.setCacheMode(LOCAL);
configuration.setNodeLockingScheme(Configuration.NodeLockingScheme.PESSIMISTIC);
configuration.setUseLazyDeserialization(false);
- cache = (CacheSPI) new DefaultCacheFactory<Object, Object>().createCache(configuration,false);
+ cache = (CacheSPI) new DefaultCacheFactory<Object, Object>().createCache(configuration, false);
}
@AfterMethod(alwaysRun = true)
@@ -170,7 +170,7 @@
assertEquals(ReplicationInterceptor.class, interceptors.next().getClass());
assertEquals(PessimisticLockInterceptor.class, interceptors.next().getClass());
assertEquals(LegacyCacheLoaderInterceptor.class, interceptors.next().getClass());
- assertEquals(CacheStoreInterceptor.class, interceptors.next().getClass());
+ assertEquals(LegacyCacheStoreInterceptor.class, interceptors.next().getClass());
assertEquals(CallInterceptor.class, interceptors.next().getClass());
assertInterceptorLinkage(list);
@@ -230,7 +230,7 @@
assertEquals(ReplicationInterceptor.class, interceptors.next().getClass());
assertEquals(PessimisticLockInterceptor.class, interceptors.next().getClass());
assertEquals(LegacyCacheLoaderInterceptor.class, interceptors.next().getClass());
- assertEquals(CacheStoreInterceptor.class, interceptors.next().getClass());
+ assertEquals(LegacyCacheStoreInterceptor.class, interceptors.next().getClass());
assertEquals(CallInterceptor.class, interceptors.next().getClass());
assertInterceptorLinkage(list);
@@ -355,7 +355,7 @@
assertEquals(OptimisticTxInterceptor.class, interceptors.next().getClass());
assertEquals(NotificationInterceptor.class, interceptors.next().getClass());
assertEquals(LegacyCacheLoaderInterceptor.class, interceptors.next().getClass());
- assertEquals(CacheStoreInterceptor.class, interceptors.next().getClass());
+ assertEquals(LegacyCacheStoreInterceptor.class, interceptors.next().getClass());
assertEquals(OptimisticLockingInterceptor.class, interceptors.next().getClass());
assertEquals(OptimisticValidatorInterceptor.class, interceptors.next().getClass());
assertEquals(OptimisticCreateIfNotExistsInterceptor.class, interceptors.next().getClass());
16 years, 3 months
JBoss Cache SVN: r6803 - in core/trunk/src: main/java/org/jboss/cache/interceptors and 4 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-09-26 07:50:32 -0400 (Fri, 26 Sep 2008)
New Revision: 6803
Added:
core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheStoreInterceptor.java
core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoaderPessimisticTest.java
Removed:
core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/UpgradableLock.java
Modified:
core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheLoaderInterceptor.java
core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java
core/trunk/src/main/java/org/jboss/cache/loader/CacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java
core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderOld.java
core/trunk/src/main/java/org/jboss/cache/lock/StripedLock.java
core/trunk/src/test/java/org/jboss/cache/loader/AsyncFileCacheLoaderTest.java
core/trunk/src/test/java/org/jboss/cache/loader/CacheLoaderTestsBase.java
core/trunk/src/test/java/org/jboss/cache/loader/CacheLoaderWithReplicationTest.java
core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoader.java
Log:
1) Better impl for JBCACHE-1410: JDBCCacheLoader may attempt to create a node entry in the DB twice
2) JBCACHE-1368: Optimize the CacheLoader.putAll() method so reads are not necessary
3) JBCACHE-1414: inefficient exists() in JDBCCacheLoader
Modified: core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -145,8 +145,14 @@
else
{
if (configuration.getNodeLockingScheme() != NodeLockingScheme.MVCC)
+ {
interceptorChain.appendIntereceptor(createInterceptor(LegacyCacheLoaderInterceptor.class));
- interceptorChain.appendIntereceptor(createInterceptor(CacheStoreInterceptor.class));
+ interceptorChain.appendIntereceptor(createInterceptor(LegacyCacheStoreInterceptor.class));
+ }
+ else
+ {
+ interceptorChain.appendIntereceptor(createInterceptor(CacheStoreInterceptor.class));
+ }
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheLoaderInterceptor.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -116,7 +116,7 @@
{
if (command.getFqn() != null)
{
- loadIfNeeded(ctx, command.getFqn(), null, false, true, false, false, false, false, false);
+ loadIfNeeded(ctx, command.getFqn(), null, true, true, false, false, false, false, true);
}
return invokeNextInterceptor(ctx, command);
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/CacheStoreInterceptor.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -77,7 +77,7 @@
private HashMap txStores = new HashMap();
private Map<GlobalTransaction, Set<Fqn>> preparingTxs = new ConcurrentHashMap<GlobalTransaction, Set<Fqn>>();
private long cacheStores = 0;
- private CacheLoader loader;
+ CacheLoader loader;
private CacheLoaderManager loaderManager;
private boolean optimistic;
private boolean statsEnabled;
@@ -281,12 +281,17 @@
return returnValue;
}
- loader.put(command.getFqn(), command.getData());
+ storeStateForPutDataMap(command.getFqn(), ctx);
if (getStatisticsEnabled()) cacheStores++;
return returnValue;
}
+ protected void storeStateForPutDataMap(Fqn f, InvocationContext ctx) throws Exception
+ {
+ loader.put(f, ctx.lookUpNode(f).getDelegationTarget().getData());
+ }
+
@Override
protected Object handlePutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable
{
@@ -328,7 +333,7 @@
NodeSPI n = ctx.lookUpNode(f);
if (n != null && !n.isDeleted())
{
- Map internalState = n.getInternalState(true);
+ Map internalState = n.getInternalState(false);
loader.put(f, internalState);
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheLoaderInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheLoaderInterceptor.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheLoaderInterceptor.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -119,7 +119,7 @@
{
if (command.getFqn() != null)
{
- loadIfNeeded(ctx, command.getFqn(), null, false, true, false, ctx.getTransactionContext(), false, false, false);
+ loadIfNeeded(ctx, command.getFqn(), null, true, true, false, ctx.getTransactionContext(), false, false, false);
}
return invokeNextInterceptor(ctx, command);
}
Added: core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheStoreInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheStoreInterceptor.java (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyCacheStoreInterceptor.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -0,0 +1,37 @@
+/*
+ * 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.cache.interceptors;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.InvocationContext;
+import org.jboss.cache.annotations.Compat;
+
+@Compat
+@Deprecated
+public class LegacyCacheStoreInterceptor extends CacheStoreInterceptor
+{
+ @Override
+ protected void storeStateForPutDataMap(Fqn f, InvocationContext ctx) throws Exception
+ {
+ loader.put(f, ctx.lookUpNode(f).getDataDirect());
+ }
+}
Modified: core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -69,7 +69,10 @@
protected ConnectionFactory cf;
protected String driverName;
private AdjListJDBCCacheLoaderConfig config;
- protected StripedLock lock = new StripedLock();
+ protected StripedLock lock = new StripedLock(128);
+ // dummy, used for serializing empty maps. One should NOT use Collections.emptyMap() here since if an emptyMap is
+ // serialized, upon deserialization it cannot be added to.
+ private static final Map<Object, Object> EMPTY_HASHMAP = new HashMap<Object, Object>(0, 1);
public void setConfig(CacheLoaderConfig.IndividualCacheLoaderConfig base)
{
@@ -265,8 +268,46 @@
safeClose(st);
cf.close(con);
}
+
+ createDummyTableIfNeeded();
}
+ private void createDummyTableIfNeeded() throws Exception
+ {
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try
+ {
+ conn = cf.getConnection();
+ ps = conn.prepareStatement(config.getDummyTableRemovalDDL());
+ ps.execute();
+ }
+ catch (Exception e)
+ {
+ // ignore - it just means we didn't need to drop any database tables.
+ }
+ finally
+ {
+ safeClose(ps);
+ cf.close(conn);
+ }
+
+ try
+ {
+ conn = cf.getConnection();
+ ps = conn.prepareStatement(config.getDummyTableCreationDDL());
+ ps.execute();
+ safeClose(ps);
+ ps = conn.prepareStatement(config.getDummyTablePopulationSql());
+ ps.execute();
+ }
+ finally
+ {
+ safeClose(ps);
+ cf.close(conn);
+ }
+ }
+
@Override
public void stop()
{
@@ -309,14 +350,23 @@
public boolean exists(Fqn name) throws Exception
{
lock.acquireLock(name, false);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
try
{
- final Map node = loadNode(name);
- return node != null;// && node != NULL_NODE_IN_ROW;
+ conn = cf.getConnection();
+ ps = conn.prepareStatement(config.getExistsSql());
+ ps.setString(1, name.toString());
+ rs = ps.executeQuery();
+ return rs.next();
}
finally
{
lock.releaseLock(name);
+ safeClose(rs);
+ safeClose(ps);
+ cf.close(conn);
}
}
@@ -424,11 +474,14 @@
/**
* Inserts a node into the database
*
- * @param name the fqn
- * @param dataMap the node
+ * @param name the fqn
+ * @param dataMap the node
+ * @param rowMayExist if true, then this method will not be strict in testing for 1 row being inserted, since 0 may be inserted if the row already exists.
*/
- protected void insertNode(Fqn name, Map dataMap)
+ protected void insertNode(Fqn name, Map dataMap, boolean rowMayExist)
{
+ if (dataMap != null && !(dataMap instanceof HashMap))
+ throw new RuntimeException("Cannot persist map of type " + dataMap.getClass());
Connection con = null;
PreparedStatement ps = null;
try
@@ -444,7 +497,7 @@
populatePreparedStatementForInsert(name, dataMap, ps);
int rows = ps.executeUpdate();
- if (rows != 1)
+ if (!rowMayExist && rows != 1)
{
throw new IllegalStateException("Expected one insert row but got " + rows);
}
@@ -471,7 +524,8 @@
protected void populatePreparedStatementForInsert(Fqn name, Map dataMap, PreparedStatement ps)
throws Exception
{
- ps.setString(1, name.toString());
+ String fqnString = name.toString();
+ ps.setString(1, fqnString);
if (dataMap != null)
{
@@ -501,6 +555,9 @@
{
ps.setString(3, name.getAncestor(name.size() - 1).toString());
}
+
+ // and a repeat - the 4th param is the same as the 1st one.
+ ps.setString(4, fqnString);
}
@@ -512,6 +569,8 @@
*/
protected void updateNode(Fqn name, Map<Object, Object> node)
{
+ if (node != null && !(node instanceof HashMap))
+ throw new RuntimeException("Cannot persist map of type " + node.getClass());
Connection con = null;
PreparedStatement ps = null;
try
@@ -524,7 +583,7 @@
con = cf.getConnection();
ps = con.prepareStatement(config.getUpdateNodeSql());
- if (node == null) node = Collections.emptyMap();
+ if (node == null) node = EMPTY_HASHMAP;
ByteBuffer byteBuffer = marshall(node);
ps.setBinaryStream(1, byteBuffer.getStream(), byteBuffer.getLength());
Modified: core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -67,6 +67,7 @@
private String selectNodeSql;
private String updateNodeSql;
private String updateTableSql;
+ private String existsSql;
private String connectionFactoryClass;
private String primaryKey = PRIMARY_KEY_DEFAULT;
private String fqnType = FQN_TYPE_DEFAULT;
@@ -188,6 +189,21 @@
return insertNodeSql;
}
+ public String getExistsSql()
+ {
+ if (existsSql == null)
+ {
+ setExistsSql(constructExistsSql());
+ }
+ return existsSql;
+ }
+
+ public void setExistsSql(String existsSql)
+ {
+ testImmutability("existsSql");
+ this.existsSql = existsSql;
+ }
+
public void setInsertNodeSql(String insertNodeSql)
{
testImmutability("insertNodeSql");
@@ -577,16 +593,51 @@
return "select " + fqnColumn + " from " + table + " where " + parentColumn + "=?";
}
+ private String constructExistsSql()
+ {
+ return "select '1' from " + table + " where " + fqnColumn + "=?";
+ }
+
private String constructInsertNodeSql()
{
- return "insert into " +
- table +
- " (" +
- fqnColumn +
- ", " +
- nodeColumn +
- ", " +
- parentColumn +
- ") values (?, ?, ?)";
+ // This SQL string takes in 4 params - fqn, node (serialized data), parent, and fqn AGAIN.
+ // the benefit of this is is that it will run without failing even if the row already exists, so you don't need
+ // to check if the row exists before running this query. Returns '1' if the row was inserted, '0' otherwise,
+ // but does NOT fail on primary key conflict.
+
+ // the 'dummy' table, table_D, *must* exist though, and could contain just a single dummy constant row.
+
+ return "INSERT INTO "
+ + table
+ + " ("
+ + fqnColumn
+ + ", "
+ + nodeColumn
+ + ", "
+ + parentColumn
+ + ") SELECT ?, ?, ? FROM "
+ + table
+ + "_D WHERE NOT EXISTS (SELECT "
+ + fqnColumn
+ + " FROM "
+ + table
+ + " WHERE "
+ + fqnColumn
+ + " = ?)";
}
+
+ public String getDummyTableCreationDDL()
+ {
+ return "create table " + table + "_D (i CHAR)";
+ }
+
+ public String getDummyTableRemovalDDL()
+ {
+ return "drop table " + table + "_D";
+ }
+
+ public String getDummyTablePopulationSql()
+ {
+ return "insert into " + table + "_D values ('x')";
+ }
}
\ No newline at end of file
Modified: core/trunk/src/main/java/org/jboss/cache/loader/CacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/CacheLoader.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/loader/CacheLoader.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -142,6 +142,11 @@
* insertion.
* This is the same behavior as {@link Map#putAll}.
* If the node does not exist, all parent nodes from the root down are created automatically
+ * <p/>
+ * <b>Note</b> since <i>3.0</i>, as an optimization, this method will require a definitive attribute map and
+ * not just a subset. This will allow cache loader implementations to overwrite rather than merge, if that is
+ * deemed more efficient. This will not break backward compatibility since performing a merge will not cause
+ * any loss of data even though it is an unnecessary step.
*
* @param name The fully qualified name of the node
* @param attributes A Map of attributes. Can be null
Modified: core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/loader/FileCacheLoader.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -257,7 +257,7 @@
public void put(Fqn fqn, Map attributes) throws Exception
{
- put(fqn, attributes, false);
+ put(fqn, attributes, true);
}
Modified: core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -98,10 +98,46 @@
*/
public Object put(Fqn name, Object key, Object value) throws Exception
{
- Map<Object, Object> m = new HashMap<Object, Object>(1);
- m.put(key, value);
- Map existing = _put(name, m);
- return existing == null ? null : existing.get(key);
+ lock.acquireLock(name, true);
+ try
+ {
+ Map<Object, Object> existing = loadNode(name);
+
+ if (existing == null)
+ {
+ // do not use a singleton map here since this is serialized and stored in the DB.
+ Map<Object, Object> m = new HashMap<Object, Object>(1);
+ m.put(key, value);
+ addNewSubtree(name, m);
+ return null;
+ }
+
+ if (existing == NULL_NODE_IN_ROW)
+ {
+ // do not use a singleton map here since this is serialized and stored in the DB.
+ Map<Object, Object> m = new HashMap<Object, Object>(1);
+ m.put(key, value);
+ updateNode(name, m);
+ return null;
+ }
+
+ //creation sequence important - we need to overwrite old values
+ try
+ {
+ Object oldVal = existing.put(key, value);
+ updateNode(name, existing);
+ return oldVal;
+ }
+ catch (UnsupportedOperationException uoe)
+ {
+ log.error("Caught UOE - map is " + existing.getClass());
+ throw uoe;
+ }
+ }
+ finally
+ {
+ lock.releaseLock(name);
+ }
}
/**
@@ -110,7 +146,24 @@
*/
public void put(Fqn name, Map attributes) throws Exception
{
- _put(name, attributes);
+ lock.acquireLock(name, true);
+ Map toStore = attributes;
+ if (toStore != null && !(toStore instanceof HashMap)) toStore = new HashMap(attributes);
+ try
+ {
+ if (!exists(name))
+ {
+ addNewSubtree(name, toStore);
+ }
+ else
+ {
+ updateNode(name, toStore);
+ }
+ }
+ finally
+ {
+ lock.releaseLock(name);
+ }
}
@Override
@@ -291,56 +344,18 @@
return result;
}
- private Map _put(Fqn name, Map attributes) throws Exception
- {
- lock.acquireLock(name, true);
- try
- {
- Map result = null;
- Map treeNode = loadNode(name);
- if (treeNode == null)
- {
- addNewSubtree(name, attributes);
- }
- else if (treeNode == NULL_NODE_IN_ROW)
- {
- updateNode(name, attributes);
- }
- else
- {//the node exists and the attribute map is NOT null
- Map<Object, Object> newAttributes = new HashMap<Object, Object>(treeNode);
- newAttributes.putAll(attributes);//creation sequnce important - we need to overwrite old values
- updateNode(name, newAttributes);
- result = treeNode;
- }
- return result;
- }
- finally
- {
- lock.releaseLock(name);
- }
- }
-
private void addNewSubtree(Fqn name, Map attributes) throws Exception
{
Fqn currentNode = name;
do
{
- try
+ if (currentNode.equals(name))
{
- lock.acquireLock(currentNode, true);
- if (currentNode.equals(name))
- {
- insertNode(currentNode, attributes);
- }
- else
- {
- if (loadNode(currentNode) == null) insertNode(currentNode, null);
- }
+ insertNode(currentNode, attributes, false);
}
- finally
+ else
{
- lock.releaseLock(currentNode);
+ insertNode(currentNode, null, true);
}
if (currentNode.isRoot()) break;
currentNode = currentNode.getParent();
Modified: core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderOld.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderOld.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderOld.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -149,11 +149,11 @@
final Fqn parent = name.getAncestor(i);
if (!exists(parent))
{
- insertNode(parent, null);
+ insertNode(parent, null, false);
}
}
}
- insertNode(name, node);
+ insertNode(name, node, false);
}
return oldValue;
@@ -331,11 +331,11 @@
final Fqn parent = name.getAncestor(i);
if (!exists(parent))
{
- insertNode(parent, null);
+ insertNode(parent, null, false);
}
}
}
- insertNode(name, attrs);
+ insertNode(name, attrs, false);
}
}
Modified: core/trunk/src/main/java/org/jboss/cache/lock/StripedLock.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/lock/StripedLock.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/lock/StripedLock.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -23,9 +23,9 @@
import net.jcip.annotations.ThreadSafe;
import org.jboss.cache.Fqn;
-import org.jboss.cache.util.concurrent.locks.UpgradableLock;
import java.util.List;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* A simple implementation of lock striping, using Fqns as the keys to lock on, primarily used to help make
@@ -48,7 +48,7 @@
private final int lockSegmentMask;
private final int lockSegmentShift;
- final UpgradableLock[] sharedLocks;
+ final ReentrantReadWriteLock[] sharedLocks;
/**
* This constructor just calls {@link #StripedLock(int)} with a default concurrency value of 20.
@@ -75,9 +75,9 @@
lockSegmentShift = 32 - tempLockSegShift;
lockSegmentMask = numLocks - 1;
- sharedLocks = new UpgradableLock[numLocks];
+ sharedLocks = new ReentrantReadWriteLock[numLocks];
- for (int i = 0; i < numLocks; i++) sharedLocks[i] = new UpgradableLock();
+ for (int i = 0; i < numLocks; i++) sharedLocks[i] = new ReentrantReadWriteLock();
}
/**
@@ -88,11 +88,11 @@
*/
public void acquireLock(Fqn fqn, boolean exclusive)
{
- UpgradableLock lock = getLock(fqn);
+ ReentrantReadWriteLock lock = getLock(fqn);
if (exclusive)
{
- lock.acquireWriteLockWithUpgrade();
+ lock.writeLock().lock();
}
else
{
@@ -107,11 +107,18 @@
*/
public void releaseLock(Fqn fqn)
{
- UpgradableLock lock = getLock(fqn);
- lock.unlock();
+ ReentrantReadWriteLock lock = getLock(fqn);
+ if (lock.isWriteLockedByCurrentThread())
+ {
+ lock.writeLock().unlock();
+ }
+ else
+ {
+ lock.readLock().unlock();
+ }
}
- final UpgradableLock getLock(Object o)
+ final ReentrantReadWriteLock getLock(Object o)
{
return sharedLocks[hashToIndex(o)];
}
Deleted: core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/UpgradableLock.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/UpgradableLock.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/main/java/org/jboss/cache/util/concurrent/locks/UpgradableLock.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -1,88 +0,0 @@
-/*
- * 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.cache.util.concurrent.locks;
-
-import org.jboss.cache.util.concurrent.ConcurrentHashSet;
-
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-/**
- * A {@link java.util.concurrent.locks.ReentrantReadWriteLock} with support for acquiring write locks when the current
- * thread already has a read lock. Also supports releasing such write locks and re-acquiring read locks in the process.
- */
-public class UpgradableLock extends ReentrantReadWriteLock
-{
- private final Set<Thread> upgraders = new ConcurrentHashSet<Thread>();
-
- /**
- * Attempts to upgrade a read lock to a write lock. If no read locks are held, a write lock is simply attempted.
- */
- public void acquireWriteLockWithUpgrade()
- {
- boolean upgradeNeeded = true;
- try
- {
- readLock().unlock();
- }
- catch (IllegalMonitorStateException imse)
- {
- // read lock was never held; no upgrading needed.
- upgradeNeeded = false;
- }
-
- if (upgradeNeeded) upgraders.add(Thread.currentThread());
-
- writeLock().lock();
- }
-
- /**
- * Unlocks any locks held by the current thread. If a write lock is held, it is released. If a read lock is held
- * it is released. This method supports reentrant locks so unlocking repeatedly may release >1 write lock. It
- * also supports upgraded locks, i.e., read locks that were upgraded to write locks.
- */
- public void unlock()
- {
- if (isWriteLockedByCurrentThread())
- {
- writeLock().unlock();
- Thread current;
- if (!isWriteLockedByCurrentThread() && upgraders.contains((current = Thread.currentThread())))
- {
- // re-acquire the RL.
- readLock().lock();
- upgraders.remove(current);
- }
- }
- else
- {
- try
- {
- readLock().unlock();
- }
- catch (IllegalMonitorStateException imse)
- {
- // perhaps the RL was already released earlier?
- }
- }
- }
-}
Modified: core/trunk/src/test/java/org/jboss/cache/loader/AsyncFileCacheLoaderTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/AsyncFileCacheLoaderTest.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/test/java/org/jboss/cache/loader/AsyncFileCacheLoaderTest.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -88,9 +88,10 @@
map.put("c", "d");
// Three kinds of puts!
Modification mod = new Modification(Modification.ModificationType.PUT_KEY_VALUE, fqn, "e", "f");
+ loader.put(fqn, map);
loader.put(fqn, "a", "b");
- loader.put(fqn, map);
loader.put(Collections.singletonList(mod));
+ System.out.println(loader.get(fqn));
assertEquals("put right away", 3, loader.get(fqn).size());
loader.remove(fqn);
}
Modified: core/trunk/src/test/java/org/jboss/cache/loader/CacheLoaderTestsBase.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/CacheLoaderTestsBase.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/test/java/org/jboss/cache/loader/CacheLoaderTestsBase.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -19,6 +19,7 @@
import static org.testng.AssertJUnit.*;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
@@ -41,7 +42,7 @@
* @author Bela Ban
* @version $Id$
*/
-//@Test(groups = {"functional"})
+@Test(groups = {"functional"})
abstract public class CacheLoaderTestsBase extends AbstractCacheLoaderTestBase
{
private static final Log log = LogFactory.getLog(CacheLoaderTestsBase.class);
@@ -1646,6 +1647,9 @@
list.add(mod);
Map<Object, Object> map = new HashMap<Object, Object>();
+ // any call to putAll() will result in all the cached data being written
+ map.put("one", "two");
+ map.put("three", "four");
map.put("five", "six");
map.put("seven", "eight");
mod = new Modification();
@@ -1950,7 +1954,58 @@
assertEquals(value, loader.get(fqn).get(key));
}
+ public void testPutAllAfterEvict() throws Exception
+ {
+ Fqn fqn = Fqn.fromString("/a/b");
+ Map<String, String> original = new HashMap<String, String>();
+ Map<String, String> toAdd = new HashMap<String, String>();
+ Map<String, String> all = new HashMap<String, String>();
+ original.put("1", "One");
+ original.put("2", "Two");
+ toAdd.put("3", "Three");
+ toAdd.put("4", "Four");
+
+ all.putAll(original);
+ all.putAll(toAdd);
+
+ cache.put(fqn, original);
+ assert loader.get(fqn).equals(original);
+ cache.evict(fqn);
+ assert loader.get(fqn).equals(original);
+ cache.put(fqn, toAdd);
+ assert loader.get(fqn).equals(all);
+ cache.evict(fqn);
+ assert loader.get(fqn).equals(all);
+ }
+
+ public void testPutAllAfterEvictWithChild() throws Exception
+ {
+ Fqn fqn = Fqn.fromString("/a/b");
+ Map<String, String> original = new HashMap<String, String>();
+ Map<String, String> toAdd = new HashMap<String, String>();
+ Map<String, String> all = new HashMap<String, String>();
+
+ original.put("1", "One");
+ original.put("2", "Two");
+ toAdd.put("3", "Three");
+ toAdd.put("4", "Four");
+
+ all.putAll(original);
+ all.putAll(toAdd);
+
+ cache.put(fqn, original);
+ cache.put(Fqn.fromRelativeElements(fqn, "c"), "x", "y"); // put stuff in a child so that evicting fqn will only clear its data map.
+ assert loader.get(fqn).equals(original);
+ cache.evict(fqn);
+ assert loader.get(fqn).equals(original);
+ cache.put(fqn, toAdd);
+ assert loader.get(fqn).equals(all);
+ cache.evict(fqn);
+ assert loader.get(fqn).equals(all);
+ }
+
+
/**
* Test load/store state.
*/
Modified: core/trunk/src/test/java/org/jboss/cache/loader/CacheLoaderWithReplicationTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/CacheLoaderWithReplicationTest.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/test/java/org/jboss/cache/loader/CacheLoaderWithReplicationTest.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -14,6 +14,7 @@
import org.jboss.cache.commands.tx.PrepareCommand;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.jboss.cache.transaction.DummyTransactionManagerLookup;
import org.jboss.cache.util.TestingUtil;
import org.jboss.cache.util.internals.ReplicationListener;
import static org.testng.AssertJUnit.assertEquals;
@@ -43,12 +44,12 @@
public void setUp() throws Exception
{
cache1 = new DefaultCacheFactory<Object, Object>().createCache(false);
- cache1.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig("", "org.jboss.cache.loader.DummyInMemoryCacheLoader", null, false, true, false));
- cache1.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
+ cache1.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig("", DummyInMemoryCacheLoader.class.getName(), "debug=true", false, true, false));
+ cache1.getConfiguration().setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
cache2 = new DefaultCacheFactory<Object, Object>().createCache(false);
- cache2.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig("", "org.jboss.cache.loader.DummyInMemoryCacheLoader", null, false, true, false));
- cache2.getConfiguration().setTransactionManagerLookupClass("org.jboss.cache.transaction.DummyTransactionManagerLookup");
+ cache2.getConfiguration().setCacheLoaderConfig(getSingleCacheLoaderConfig("", DummyInMemoryCacheLoader.class.getName(), "debug=true", false, true, false));
+ cache2.getConfiguration().setTransactionManagerLookupClass(DummyTransactionManagerLookup.class.getName());
loader1 = loader2 = null;
mgr1 = mgr2 = null;
@@ -252,6 +253,10 @@
assertEquals("value", cache1.get(fqn, key));
assertEquals("value", cache2.get(fqn, key));
+
+ System.out.println(loader1.get(fqn));
+ System.out.println(loader2.get(fqn));
+
assertEquals("value", loader1.get(fqn).get(key));
assertEquals("value", loader2.get(fqn).get(key));
Modified: core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoader.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoader.java 2008-09-26 11:28:53 UTC (rev 6802)
+++ core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoader.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -181,6 +181,7 @@
{
n = new DummyNode(name);
}
+ n.data.clear(); // emulate cache loaders overwriting any internal data map with new data map passed in.
if (attributes != null) n.data.putAll(injectNULLs(attributes));
getNodesMap().put(name, n);
// we need to make sure parents get put in as well.
Copied: core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoaderPessimisticTest.java (from rev 6786, core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoaderTest.java)
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoaderPessimisticTest.java (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/loader/DummyInMemoryCacheLoaderPessimisticTest.java 2008-09-26 11:50:32 UTC (rev 6803)
@@ -0,0 +1,22 @@
+package org.jboss.cache.loader;
+
+import org.jboss.cache.config.CacheLoaderConfig;
+import org.jboss.cache.config.Configuration.NodeLockingScheme;
+import org.testng.annotations.Test;
+
+/**
+ * Odd that we need a test for a test class, but if we intend to use the {@link DummyInMemoryCacheLoader} as a cache
+ * loader stub then we need to make sure it behaves as a valid cache loader.
+ */
+@Test(groups = {"functional"})
+public class DummyInMemoryCacheLoaderPessimisticTest extends CacheLoaderTestsBase
+{
+ protected void configureCache() throws Exception
+ {
+ // use the shared variation of the DIMCL so that state is persisted in a static variable in memory rather than an
+ // instance one.
+ CacheLoaderConfig clc = getSingleCacheLoaderConfig("", DummySharedInMemoryCacheLoader.class.getName(), "debug=true", false, true, false);
+ cache.getConfiguration().setCacheLoaderConfig(clc);
+ cache.getConfiguration().setNodeLockingScheme(NodeLockingScheme.PESSIMISTIC);
+ }
+}
\ No newline at end of file
16 years, 3 months
JBoss Cache SVN: r6802 - in core/branches/2.2.X/src/main/java/org/jboss/cache: lock and 1 other directories.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-09-26 07:28:53 -0400 (Fri, 26 Sep 2008)
New Revision: 6802
Removed:
core/branches/2.2.X/src/main/java/org/jboss/cache/util/concurrent/locks/
Modified:
core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java
core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java
core/branches/2.2.X/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java
core/branches/2.2.X/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderOld.java
core/branches/2.2.X/src/main/java/org/jboss/cache/lock/StripedLock.java
Log:
Better impl for JBCACHE-1410: JDBCCacheLoader may attempt to create a node entry in the DB twice
Modified: core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java
===================================================================
--- core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java 2008-09-26 11:20:35 UTC (rev 6801)
+++ core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java 2008-09-26 11:28:53 UTC (rev 6802)
@@ -243,8 +243,46 @@
safeClose(st);
cf.close(con);
}
+
+ createDummyTableIfNeeded();
}
+ private void createDummyTableIfNeeded() throws Exception
+ {
+ Connection conn = null;
+ PreparedStatement ps = null;
+ try
+ {
+ conn = cf.getConnection();
+ ps = conn.prepareStatement(config.getDummyTableRemovalDDL());
+ ps.execute();
+ }
+ catch (Exception e)
+ {
+ // ignore - it just means we didn't need to drop any database tables.
+ }
+ finally
+ {
+ safeClose(ps);
+ cf.close(conn);
+ }
+
+ try
+ {
+ conn = cf.getConnection();
+ ps = conn.prepareStatement(config.getDummyTableCreationDDL());
+ ps.execute();
+ safeClose(ps);
+ ps = conn.prepareStatement(config.getDummyTablePopulationSql());
+ ps.execute();
+ }
+ finally
+ {
+ safeClose(ps);
+ cf.close(conn);
+ }
+ }
+
@Override
public void stop()
{
@@ -411,10 +449,11 @@
/**
* Inserts a node into the database
*
- * @param name the fqn
- * @param node the node
+ * @param name the fqn
+ * @param node the node
+ * @param rowMayExist if true, then this method will not be strict in testing for 1 row being inserted, since 0 may be inserted if the row already exists.
*/
- protected void insertNode(Fqn name, Map node)
+ protected void insertNode(Fqn name, Map node, boolean rowMayExist)
{
Connection con = null;
PreparedStatement ps = null;
@@ -428,8 +467,12 @@
con = cf.getConnection();
ps = con.prepareStatement(config.getInsertNodeSql());
- ps.setString(1, name.toString());
+ String fqnString = name.toString();
+ // the Fqn needs to be in the 1st and 4th places.
+ ps.setString(1, fqnString);
+ ps.setString(4, fqnString);
+
if (node != null)
{
// ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -465,7 +508,7 @@
}
int rows = ps.executeUpdate();
- if (rows != 1)
+ if (!rowMayExist && rows != 1)
{
throw new IllegalStateException("Expected one insert row but got " + rows);
}
Modified: core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java
===================================================================
--- core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java 2008-09-26 11:20:35 UTC (rev 6801)
+++ core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java 2008-09-26 11:28:53 UTC (rev 6802)
@@ -579,14 +579,44 @@
private String constructInsertNodeSql()
{
- return "insert into " +
- table +
- " (" +
- fqnColumn +
- ", " +
- nodeColumn +
- ", " +
- parentColumn +
- ") values (?, ?, ?)";
+ // This SQL string takes in 4 params - fqn, node (serialized data), parent, and fqn AGAIN.
+ // the benefit of this is is that it will run without failing even if the row already exists, so you don't need
+ // to check if the row exists before running this query. Returns '1' if the row was inserted, '0' otherwise,
+ // but does NOT fail on primary key conflict.
+
+ // the 'dummy' table, table_D, *must* exist though, and could contain just a single dummy constant row.
+
+ return "INSERT INTO "
+ + table
+ + " ("
+ + fqnColumn
+ + ", "
+ + nodeColumn
+ + ", "
+ + parentColumn
+ + ") SELECT ?, ?, ? FROM "
+ + table
+ + "_D WHERE NOT EXISTS (SELECT "
+ + fqnColumn
+ + " FROM "
+ + table
+ + " WHERE "
+ + fqnColumn
+ + " = ?)";
}
+
+ public String getDummyTableCreationDDL()
+ {
+ return "create table " + table + "_D (i CHAR)";
+ }
+
+ public String getDummyTableRemovalDDL()
+ {
+ return "drop table " + table + "_D";
+ }
+
+ public String getDummyTablePopulationSql()
+ {
+ return "insert into " + table + "_D values ('x')";
+ }
}
\ No newline at end of file
Modified: core/branches/2.2.X/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java
===================================================================
--- core/branches/2.2.X/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java 2008-09-26 11:20:35 UTC (rev 6801)
+++ core/branches/2.2.X/src/main/java/org/jboss/cache/loader/JDBCCacheLoader.java 2008-09-26 11:28:53 UTC (rev 6802)
@@ -240,21 +240,13 @@
Fqn currentNode = name;
do
{
- try
+ if (currentNode.equals(name))
{
- lock.acquireLock(currentNode, true);
- if (currentNode.equals(name))
- {
- insertNode(currentNode, attributes);
- }
- else
- {
- if (loadNode(currentNode) == null) insertNode(currentNode, null);
- }
+ insertNode(currentNode, attributes, false);
}
- finally
+ else
{
- lock.releaseLock(currentNode);
+ insertNode(currentNode, null, true);
}
if (currentNode.isRoot()) break;
currentNode = currentNode.getParent();
Modified: core/branches/2.2.X/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderOld.java
===================================================================
--- core/branches/2.2.X/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderOld.java 2008-09-26 11:20:35 UTC (rev 6801)
+++ core/branches/2.2.X/src/main/java/org/jboss/cache/loader/JDBCCacheLoaderOld.java 2008-09-26 11:28:53 UTC (rev 6802)
@@ -135,11 +135,11 @@
final Fqn parent = name.getAncestor(i);
if (!exists(parent))
{
- insertNode(parent, null);
+ insertNode(parent, null, false);
}
}
}
- insertNode(name, node);
+ insertNode(name, node, false);
}
return oldValue;
@@ -317,11 +317,11 @@
final Fqn parent = name.getAncestor(i);
if (!exists(parent))
{
- insertNode(parent, null);
+ insertNode(parent, null, false);
}
}
}
- insertNode(name, attrs);
+ insertNode(name, attrs, false);
}
}
}
Modified: core/branches/2.2.X/src/main/java/org/jboss/cache/lock/StripedLock.java
===================================================================
--- core/branches/2.2.X/src/main/java/org/jboss/cache/lock/StripedLock.java 2008-09-26 11:20:35 UTC (rev 6801)
+++ core/branches/2.2.X/src/main/java/org/jboss/cache/lock/StripedLock.java 2008-09-26 11:28:53 UTC (rev 6802)
@@ -23,9 +23,9 @@
import net.jcip.annotations.ThreadSafe;
import org.jboss.cache.Fqn;
-import org.jboss.cache.util.concurrent.locks.UpgradableLock;
import java.util.List;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* A simple implementation of lock striping, using Fqns as the keys to lock on, primarily used to help make
@@ -48,7 +48,7 @@
private final int lockSegmentMask;
private final int lockSegmentShift;
- final UpgradableLock[] sharedLocks;
+ final ReentrantReadWriteLock[] sharedLocks;
/**
* This constructor just calls {@link #StripedLock(int)} with a default concurrency value of 20.
@@ -75,9 +75,9 @@
lockSegmentShift = 32 - tempLockSegShift;
lockSegmentMask = numLocks - 1;
- sharedLocks = new UpgradableLock[numLocks];
+ sharedLocks = new ReentrantReadWriteLock[numLocks];
- for (int i = 0; i < numLocks; i++) sharedLocks[i] = new UpgradableLock();
+ for (int i = 0; i < numLocks; i++) sharedLocks[i] = new ReentrantReadWriteLock();
}
/**
@@ -88,11 +88,11 @@
*/
public void acquireLock(Fqn fqn, boolean exclusive)
{
- UpgradableLock lock = getLock(fqn);
+ ReentrantReadWriteLock lock = getLock(fqn);
if (exclusive)
{
- lock.acquireWriteLockWithUpgrade();
+ lock.writeLock().lock();
}
else
{
@@ -107,11 +107,18 @@
*/
public void releaseLock(Fqn fqn)
{
- UpgradableLock lock = getLock(fqn);
- lock.unlock();
+ ReentrantReadWriteLock lock = getLock(fqn);
+ if (lock.isWriteLockedByCurrentThread())
+ {
+ lock.writeLock().unlock();
+ }
+ else
+ {
+ lock.readLock().unlock();
+ }
}
- final UpgradableLock getLock(Object o)
+ final ReentrantReadWriteLock getLock(Object o)
{
return sharedLocks[hashToIndex(o)];
}
16 years, 3 months
JBoss Cache SVN: r6801 - core/branches/2.2.X/src/main/java/org/jboss/cache/loader.
by jbosscache-commits@lists.jboss.org
Author: manik.surtani(a)jboss.com
Date: 2008-09-26 07:20:35 -0400 (Fri, 26 Sep 2008)
New Revision: 6801
Modified:
core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java
core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java
Log:
JBCACHE-1414: inefficient exists() in JDBCCacheLoader
Modified: core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java
===================================================================
--- core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java 2008-09-25 17:24:21 UTC (rev 6800)
+++ core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoader.java 2008-09-26 11:20:35 UTC (rev 6801)
@@ -287,14 +287,23 @@
public boolean exists(Fqn name) throws Exception
{
lock.acquireLock(name, false);
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
try
{
- final Map node = loadNode(name);
- return node != null;// && node != NULL_NODE_IN_ROW;
+ conn = cf.getConnection();
+ ps = conn.prepareStatement(config.getExistsSql());
+ ps.setString(1, name.toString());
+ rs = ps.executeQuery();
+ return rs.next();
}
finally
{
lock.releaseLock(name);
+ safeClose(rs);
+ safeClose(ps);
+ cf.close(conn);
}
}
Modified: core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java
===================================================================
--- core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java 2008-09-25 17:24:21 UTC (rev 6800)
+++ core/branches/2.2.X/src/main/java/org/jboss/cache/loader/AdjListJDBCCacheLoaderConfig.java 2008-09-26 11:20:35 UTC (rev 6801)
@@ -18,7 +18,7 @@
* The serialVersionUID
*/
private static final long serialVersionUID = -8371846151643130281L;
-
+
private static final boolean CREATE_TABLE_DEFAULT = true;
private static final boolean DROP_TABLE_DEFAULT = false;
private static final String PARENT_COLUMN_DEFAULT = "parent";
@@ -27,8 +27,8 @@
private static final String FQN_TYPE_DEFAULT = "varchar(255)";
private static final String FQN_COLUMN_DEFAULT = "fqn";
private static final String PRIMARY_KEY_DEFAULT = "jbosscache_pk";
- private static final String TABLE_DEFAULT = "jbosscache";
-
+ private static final String TABLE_DEFAULT = "jbosscache";
+
private boolean createTable = CREATE_TABLE_DEFAULT;
private String createTableDDL;
private String datasourceName;
@@ -46,6 +46,7 @@
private String selectNodeSql;
private String updateNodeSql;
private String updateTableSql;
+ private String existsSql;
private String connectionFactoryClass;
private String primaryKey = PRIMARY_KEY_DEFAULT;
private String fqnType = FQN_TYPE_DEFAULT;
@@ -167,6 +168,21 @@
return insertNodeSql;
}
+ public String getExistsSql()
+ {
+ if (existsSql == null)
+ {
+ setExistsSql(constructExistsSql());
+ }
+ return existsSql;
+ }
+
+ public void setExistsSql(String existsSql)
+ {
+ testImmutability("existsSql");
+ this.existsSql = existsSql;
+ }
+
public void setInsertNodeSql(String insertNodeSql)
{
testImmutability("insertNodeSql");
@@ -313,7 +329,7 @@
testImmutability("connectionFactoryClass");
this.connectionFactoryClass = connectionFactoryClass;
}
-
+
public String getPrimaryKey()
{
return primaryKey;
@@ -556,6 +572,11 @@
return "select " + fqnColumn + " from " + table + " where " + parentColumn + "=?";
}
+ private String constructExistsSql()
+ {
+ return "select '1' from " + table + " where " + fqnColumn + "=?";
+ }
+
private String constructInsertNodeSql()
{
return "insert into " +
@@ -567,5 +588,5 @@
", " +
parentColumn +
") values (?, ?, ?)";
- }
+ }
}
\ No newline at end of file
16 years, 3 months
JBoss Cache SVN: r6800 - searchable/tags.
by jbosscache-commits@lists.jboss.org
Author: navssurtani
Date: 2008-09-25 13:24:21 -0400 (Thu, 25 Sep 2008)
New Revision: 6800
Added:
searchable/tags/1.0.0.CR1/
Log:
CR1
Copied: searchable/tags/1.0.0.CR1 (from rev 6799, searchable/trunk)
16 years, 3 months