You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ka...@apache.org on 2010/02/10 13:42:58 UTC
svn commit: r908473 - in /db/derby/code/trunk/java/engine/org/apache/derby:
./ impl/store/ impl/store/raw/xact/
Author: kahatlen
Date: Wed Feb 10 12:42:57 2010
New Revision: 908473
URL: http://svn.apache.org/viewvc?rev=908473&view=rev
Log:
DERBY-3092: Use java.util.concurrent in TransactionTable to improve scalability
Dynamically load a Hashtable or a ConcurrentHashMap, depending on
what's available on the platform, to allow as much concurrency as
possible in the transaction table.
Added:
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentTransactionMapFactory.java (with props)
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentXactFactory.java (with props)
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionMapFactory.java (with props)
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/build.xml
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionTable.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java
db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/build.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/build.xml?rev=908473&r1=908472&r2=908473&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/build.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/build.xml Wed Feb 10 12:42:57 2010
@@ -16,7 +16,7 @@
limitations under the License.
-->
-<project default="compile_impl_store_14" basedir="../../../../../../..">
+<project default="compile_impl_store_15" basedir="../../../../../../..">
<!-- Set Properties -->
<!-- User settings -->
@@ -54,8 +54,11 @@
<include name="${derby.dir}/impl/store/**"/>
<exclude name="${derby.dir}/impl/store/raw/data/RAFContainer4.java"/>
<exclude name="${derby.dir}/impl/store/raw/data/BaseDataFileFactoryJ4.java"/>
+ <exclude name="${derby.dir}/impl/store/raw/xact/ConcurrentTransactionMapFactory.java"/>
+ <exclude name="${derby.dir}/impl/store/raw/xact/ConcurrentXactFactory.java"/>
</javac>
</target>
+
<target name="compile_impl_store_14" depends="compile_impl_store">
<javac
source="1.4"
@@ -77,5 +80,27 @@
<include name="${derby.dir}/impl/store/raw/data/BaseDataFileFactoryJ4.java"/>
</javac>
</target>
+
+ <target name="compile_impl_store_15" depends="compile_impl_store_14">
+ <javac
+ source="1.5"
+ target="1.5"
+ bootclasspath="${empty}"
+ nowarn="on"
+ debug="${debug}"
+ depend="${depend}"
+ deprecation="${deprecation}"
+ optimize="${optimize}"
+ proceed="${proceed}"
+ verbose="${verbose}"
+ srcdir="${derby.engine.src.dir}"
+ destdir="${out.dir}">
+ <classpath>
+ <pathelement path="${java15compile.classpath}"/>
+ </classpath>
+ <include name="${derby.dir}/impl/store/raw/xact/ConcurrentTransactionMapFactory.java"/>
+ <include name="${derby.dir}/impl/store/raw/xact/ConcurrentXactFactory.java"/>
+ </javac>
+ </target>
</project>
Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentTransactionMapFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentTransactionMapFactory.java?rev=908473&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentTransactionMapFactory.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentTransactionMapFactory.java Wed Feb 10 12:42:57 2010
@@ -0,0 +1,60 @@
+/*
+
+ Derby - Class org.apache.derby.impl.store.raw.xact.ConcurrentTransactionMapFactory
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+package org.apache.derby.impl.store.raw.xact;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import org.apache.derby.iapi.services.sanity.SanityManager;
+import org.apache.derby.iapi.store.raw.xact.TransactionId;
+
+/**
+ * A helper class that enables use of {@code ConcurrentHashMap} instead of
+ * {@code Hashtable} on platforms that support it. This class will be used if
+ * we are running on a Java 1.5 or higher.
+ */
+class ConcurrentTransactionMapFactory extends TransactionMapFactory {
+ @Override
+ Map newMap() {
+ Map<TransactionId, TransactionTableEntry> map =
+ new ConcurrentHashMap<TransactionId, TransactionTableEntry>();
+
+ if (SanityManager.DEBUG) {
+ // Add some extra type checks to detect bugs earlier
+ map = Collections.checkedMap(
+ map, TransactionId.class, TransactionTableEntry.class);
+ }
+
+ return map;
+ }
+
+ @Override
+ void visitEntries(Map map, TransactionTable.EntryVisitor visitor) {
+ for (Object entry : map.values()) {
+ if (!visitor.visit((TransactionTableEntry) entry)) {
+ // The visitor returned false, meaning that it's done with
+ // all of its work and we can stop the scan.
+ break;
+ }
+ }
+ }
+}
Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentTransactionMapFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentXactFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentXactFactory.java?rev=908473&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentXactFactory.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentXactFactory.java Wed Feb 10 12:42:57 2010
@@ -0,0 +1,35 @@
+/*
+
+ Derby - Class org.apache.derby.impl.store.raw.xact.ConcurrentXactFactory
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+package org.apache.derby.impl.store.raw.xact;
+
+/**
+ * A {@code TransactionFactory} similar to {@code XactFactory}, only that it
+ * provides overrides that give access to classes in the {@code
+ * java.util.concurrent} package, if supported by the runtime environment.
+ * This class is used instead of {@code XactFactory} on Java 1.5 and higher.
+ */
+public class ConcurrentXactFactory extends XactFactory {
+ @Override
+ TransactionMapFactory createMapFactory() {
+ return new ConcurrentTransactionMapFactory();
+ }
+}
Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/ConcurrentXactFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionMapFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionMapFactory.java?rev=908473&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionMapFactory.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionMapFactory.java Wed Feb 10 12:42:57 2010
@@ -0,0 +1,87 @@
+/*
+
+ Derby - Class org.apache.derby.impl.store.raw.xact.TransactionMapFactory
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to you under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+package org.apache.derby.impl.store.raw.xact;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Helper class for {@code TransactionTable} which allows it to plug in a
+ * different {@code java.util.Map} implementation for the map that contains
+ * all the {@code TransactionTableEntry} instances in the transaction table.
+ * The default implementation of this class provides support for
+ * {@code java.util.Hashtable}.
+ */
+class TransactionMapFactory {
+
+ /**
+ * <p>
+ * Create a new map instance. The map implementation must be thread-safe
+ * so that its instances can be accessed concurrently by multiple threads.
+ * That is, the map implemenation must guarantee that every method is
+ * atomic and does not fail or make the map become inconsistent just
+ * because it is accessed concurrently by another thread.
+ * </p>
+ *
+ * <p>
+ * Callers should never synchronize on the returned object in order to
+ * get consistency/atomicity guarantees across multiple accesses to the
+ * map. Instead, they should use the helper methods defined in this class,
+ * so that a mechanism appropriate for this particular map implementation
+ * is used to ensure thread-safety.
+ * </p>
+ *
+ * @return
+ */
+ Map newMap() {
+ return new Hashtable();
+ }
+
+ /**
+ * <p>
+ * Traverse the values of a map, and apply the specified visitor on each
+ * value. The traversal should be thread-safe in the sense that it should
+ * not fail because other threads access and potentially modify the map
+ * while the traversal takes place, and it must also provide all the
+ * thread-safety guarantees that are given by
+ * {@link TransactionTable#visitEntries(TransactionTable.EntryVisitor)}.
+ * </p>
+ *
+ * @param map the map that contains the
+ * @param visitor
+ * @see TransactionTable#visitEntries(TransactionTable.EntryVisitor)
+ */
+ void visitEntries(Map map, TransactionTable.EntryVisitor visitor) {
+ // Since this implementation uses a Hashtable, we need to synchronize
+ // on the map while iterating over it.
+ synchronized (map) {
+ for (Iterator it = map.values().iterator(); it.hasNext(); ) {
+ if (!visitor.visit((TransactionTableEntry) it.next())) {
+ // The visitor returned false, meaning that it's done with
+ // all of its work and we can stop the scan.
+ break;
+ }
+ }
+ }
+ }
+}
Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionMapFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionTable.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionTable.java?rev=908473&r1=908472&r2=908473&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionTable.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/TransactionTable.java Wed Feb 10 12:42:57 2010
@@ -39,7 +39,6 @@
import org.apache.derby.iapi.services.io.CompressedNumber;
import java.util.ArrayList;
-import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
@@ -98,6 +97,7 @@
* Fields
*/
+ private final TransactionMapFactory mapFactory;
private final Map trans;
private TransactionId largestUpdateXactId;
@@ -107,7 +107,8 @@
*/
public TransactionTable()
{
- trans = new Hashtable(17);
+ mapFactory = XactFactory.getMapFactory();
+ trans = mapFactory.newMap();
}
/*************************************************************
@@ -152,18 +153,30 @@
* MT - MT safe
* </p>
*
+ * <p>
+ * Entries that are added to or removed from the transaction table while
+ * it's being traversed, may or may not be visited. All the entries that
+ * are present in the map when this method is called, and have not been
+ * removed when the method returns, will have been visited exactly once
+ * (except if the {@code visit()} method returns false before all entries
+ * have been visited, in which case the traversal of the map will stop
+ * earlier).
+ * </p>
+ *
+ * <p>
+ * Note however that this method does not guarantee that a single
+ * {@code TransactionTableEntry} is not accessed concurrently by multiple
+ * threads. If the visitor accesses some of the entry's mutable state, the
+ * caller must ensure that appropriate synchronization protection is in
+ * place. For example, if accessing the update state of the entry, the
+ * caller must synchronize on "this" (the {@code TransactionTable}
+ * instance).
+ * </p>
+ *
* @param visitor the visitor to apply on each transaction table entry
*/
void visitEntries(EntryVisitor visitor) {
- synchronized (trans) {
- for (Iterator it = trans.values().iterator(); it.hasNext(); ) {
- if (!visitor.visit((TransactionTableEntry) it.next())) {
- // The visitor returned false, meaning that it's done with
- // all of its work and we can stop the scan.
- break;
- }
- }
- }
+ mapFactory.visitEntries(trans, visitor);
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java?rev=908473&r1=908472&r2=908473&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/xact/XactFactory.java Wed Feb 10 12:42:57 2010
@@ -107,14 +107,57 @@
private long backupBlockingOperations = 0;
private boolean inBackup = false;
+ /**
+ * An instance of a helper class that provides maps with different
+ * concurrency properties depending on the platform. Used by
+ * {@code TransactionTable}.
+ */
+ private static TransactionMapFactory mapFactory;
+
/*
** Constructor
*/
public XactFactory() {
super();
+ setMapFactory();
}
+ /**
+ * Create a {@code TransactionMapFactory} instance. This method can be
+ * overridden by sub-classes in order to provide a factory that produces
+ * maps that give higher concurrency, if supported by the platform.
+ *
+ * @return a {@code TransactionMapFactory} suitable for this platform
+ */
+ TransactionMapFactory createMapFactory() {
+ return new TransactionMapFactory();
+ }
+
+ /**
+ * Set the default map factory to use for this system, if it's not already
+ * set. The value will be stored in a static variable so that it will only
+ * be set by the first {@code XactFactory} that's booted.
+ */
+ private void setMapFactory() {
+ synchronized (XactFactory.class) {
+ if (mapFactory == null) {
+ mapFactory = createMapFactory();
+ }
+ }
+ }
+
+ /**
+ * Get the map factory for this platform. This can be used by {@code
+ * TransactionTable} in order to produce the sort of map that has the best
+ * concurrency properties available on this platform.
+ *
+ * @return a map factory
+ */
+ static synchronized TransactionMapFactory getMapFactory() {
+ return mapFactory;
+ }
+
/*
** Methods of ModuleControl
*/
Modified: db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/modules.properties?rev=908473&r1=908472&r2=908473&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/modules.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/modules.properties Wed Feb 10 12:42:57 2010
@@ -323,8 +323,14 @@
derby.module.rawStore.log=org.apache.derby.impl.store.raw.log.LogToFile
cloudscape.config.rawStore.log=derby
-derby.module.rawStore.transaction=org.apache.derby.impl.store.raw.xact.XactFactory
-cloudscape.config.rawStore.transaction=derby
+derby.module.rawStore.transactionJ1=org.apache.derby.impl.store.raw.xact.XactFactory
+derby.env.jdk.rawStore.transactionJ1=1
+cloudscape.config.rawStore.transactionJ1=derby
+
+derby.module.rawStore.transactionJ6=org.apache.derby.impl.store.raw.xact.ConcurrentXactFactory
+derby.env.jdk.rawStore.transactionJ6=6
+derby.env.classes.rawStore.transactionJ6=java.util.concurrent.ConcurrentHashMap
+cloudscape.config.rawStore.transactionJ6=derby
derby.module.rawStore=org.apache.derby.impl.store.raw.RawStore
cloudscape.config.rawStore=derby