exo-jcr SVN: r3944 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-08 07:53:15 -0500 (Tue, 08 Feb 2011)
New Revision: 3944
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLSingleDbJDBCConnection.java
Log:
EXOJCR-1104: fix query
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLSingleDbJDBCConnection.java 2011-02-08 12:52:46 UTC (rev 3943)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLSingleDbJDBCConnection.java 2011-02-08 12:53:15 UTC (rev 3944)
@@ -75,6 +75,6 @@
+ " (select Row_Number() over (order by I.ID) as r__, I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM"
+ " from JCR_SITEM I where I.CONTAINER_NAME='?' and I.I_CLASS=1) as A where A.r__ <= ? and A.r__ > ?"
+ ") J on P.PARENT_ID = J.ID"
- + " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
+ + " where P.I_CLASS=2 and P.CONTAINER_NAME='?' and V.PROPERTY_ID=P.ID order by J.ID";
}
}
13 years, 3 months
exo-jcr SVN: r3943 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-08 07:52:46 -0500 (Tue, 08 Feb 2011)
New Revision: 3943
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleMultiDbJDBCConnection.java
Log:
EXOJCR-1104: fix query
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java 2011-02-08 12:26:22 UTC (rev 3942)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java 2011-02-08 12:52:46 UTC (rev 3943)
@@ -75,6 +75,6 @@
+ " (select Row_Number() over (order by I.ID) as r__, I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM"
+ " from JCR_SITEM I where I.CONTAINER_NAME='?' and I.I_CLASS=1) as A where A.r__ <= ? and A.r__ > ?"
+ ") J on P.PARENT_ID = J.ID"
- + " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
+ + " where P.I_CLASS=2 and P.CONTAINER_NAME='?' and V.PROPERTY_ID=P.ID order by J.ID";
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleMultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleMultiDbJDBCConnection.java 2011-02-08 12:26:22 UTC (rev 3942)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleMultiDbJDBCConnection.java 2011-02-08 12:52:46 UTC (rev 3943)
@@ -84,7 +84,7 @@
+ " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_MVALUE V, JCR_MITEM P"
+ " join ( select * from ( select A.*, ROWNUM r__ from ("
+ " select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_MITEM I "
- + " where I.I_CLASS=1 order by I.ID) A where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ + " where I.I_CLASS=1 order by I.ID) A where ROWNUM <= ?) where r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by J.ID";
}
}
13 years, 3 months
exo-jcr SVN: r3942 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc: optimisation/db and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-08 07:26:22 -0500 (Tue, 08 Feb 2011)
New Revision: 3942
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleMultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleSingleDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleSingleDbJDBCConnection.java
Log:
EXOJCR-1104: fix Oracle query
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleMultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleMultiDbJDBCConnection.java 2011-02-08 12:25:05 UTC (rev 3941)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleMultiDbJDBCConnection.java 2011-02-08 12:26:22 UTC (rev 3942)
@@ -71,7 +71,7 @@
+ " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_MVALUE V, JCR_MITEM P"
+ " join ( select * from ( select A.*, ROWNUM r__ from ("
+ " select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_MITEM I "
- + " where I.I_CLASS=1 order by I.ID) A where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ + " where I.I_CLASS=1 order by I.ID) A where ROWNUM <= ?) where r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by J.ID";
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleSingleDbJDBCConnection.java 2011-02-08 12:25:05 UTC (rev 3941)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleSingleDbJDBCConnection.java 2011-02-08 12:26:22 UTC (rev 3942)
@@ -72,7 +72,7 @@
+ " join ( select * from ( select A.*, ROWNUM r__ from ("
+ " select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_SITEM I "
+ " where I.CONTAINER_NAME=? and I.I_CLASS=1 order by I.ID"
- + " ) A where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ + " ) A where ROWNUM <= ?) where r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleSingleDbJDBCConnection.java 2011-02-08 12:25:05 UTC (rev 3941)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleSingleDbJDBCConnection.java 2011-02-08 12:26:22 UTC (rev 3942)
@@ -86,7 +86,7 @@
+ " join ( select * from ( select A.*, ROWNUM r__ from ("
+ " select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_SITEM I "
+ " where I.CONTAINER_NAME=? and I.I_CLASS=1 order by I.ID"
- + " ) A where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ + " ) A where ROWNUM <= ?) where r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
}
}
13 years, 3 months
exo-jcr SVN: r3941 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache.
by do-not-reply@jboss.org
Author: nzamosenchuk
Date: 2011-02-08 07:25:05 -0500 (Tue, 08 Feb 2011)
New Revision: 3941
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/ParentNodeEvictionActionPolicy.java
Log:
EXOJCR-1185 : applying the patch, that replaces getChildrenNamesDirect with hasChildrenDirect
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/ParentNodeEvictionActionPolicy.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/ParentNodeEvictionActionPolicy.java 2011-02-08 10:17:33 UTC (rev 3940)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/dataflow/persistent/jbosscache/ParentNodeEvictionActionPolicy.java 2011-02-08 12:25:05 UTC (rev 3941)
@@ -24,8 +24,6 @@
import org.jboss.cache.NodeSPI;
import org.jboss.cache.eviction.EvictionActionPolicy;
-import java.util.Set;
-
/**
* This class is used to prevent the memory leak described here http://community.jboss.org/thread/147084
* and corresponding to the JIRA https://jira.jboss.org/jira/browse/JBCACHE-1567
@@ -53,14 +51,18 @@
try
{
if (log.isTraceEnabled())
+ {
log.trace("Evicting Fqn " + fqn);
+ }
cache.evict(fqn);
result = true;
}
catch (Exception e)
{
if (log.isDebugEnabled())
+ {
log.debug("Unable to evict " + fqn, e);
+ }
result = false;
}
if (fqn.size() != 4)
@@ -76,26 +78,26 @@
// The expected data structure is of type ${ws-id}/$CHILD_NODES/${node-id}/${sub-node-name} or
// ${ws-id}/$CHILD_PROPS/${node-id}/${sub-property-name}
- // We use the method getChildrenNamesDirect to avoid going through
+ // We use the method hasChildrenDirect to avoid going through
// the intercepter chain (EXOJCR-460)
NodeSPI node = ((CacheSPI)cache).peek(parentFqn, false);
// Check if not null, possibly this node was concurrently removed
- if (node != null)
+ if (node != null && !node.hasChildrenDirect())
{
- Set<Object> names = node.getChildrenNamesDirect();
- if (names.isEmpty() || (names.size() == 1 && names.contains(fqn.get(3))))
+ if (log.isTraceEnabled())
{
- if (log.isTraceEnabled())
- log.trace("Evicting Fqn " + fqn);
- cache.evict(parentFqn);
+ log.trace("Evicting Fqn " + fqn);
}
+ cache.evict(parentFqn);
}
}
}
catch (Exception e)
{
if (log.isDebugEnabled())
+ {
log.debug("Unable to evict " + fqn, e);
+ }
}
return result;
}
13 years, 3 months
exo-jcr SVN: r3940 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc: db and 2 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-08 05:17:33 -0500 (Tue, 08 Feb 2011)
New Revision: 3940
Added:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLConnectionFactory.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLMultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLSingleDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLConnectionFactory.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLMultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleMultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleSingleDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleMultiDbJDBCConnection.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleSingleDbJDBCConnection.java
Log:
EXOJCR-1104: add MSSQL support, fix Oracle query
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-02-08 08:30:07 UTC (rev 3939)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/JDBCWorkspaceDataContainer.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -45,6 +45,7 @@
import org.exoplatform.services.jcr.impl.storage.jdbc.db.DefaultOracleConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.GenericConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.HSQLDBConnectionFactory;
+import org.exoplatform.services.jcr.impl.storage.jdbc.db.MSSQLConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.MySQLConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.OracleConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.db.WorkspaceStorageConnectionFactory;
@@ -749,7 +750,27 @@
}
else if (dbDialect == DBConstants.DB_DIALECT_MSSQL)
{
- this.connFactory = defaultConnectionFactory();
+ if (dbSourceName != null)
+ {
+ DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+ if (ds != null)
+ {
+ this.connFactory =
+ new MSSQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
+ }
+ else
+ {
+ throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ }
+ }
+ else
+ {
+ this.connFactory =
+ new MSSQLConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
+ valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mssql.sql";
dbInitilizer = defaultDBInitializer(sqlPath);
}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLConnectionFactory.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLConnectionFactory.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLConnectionFactory.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.jcr.impl.storage.jdbc.db;
+
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.sql.SQLException;
+
+import javax.jcr.RepositoryException;
+import javax.sql.DataSource;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 8 02 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: MSSQLConnectionFactory.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class MSSQLConnectionFactory extends GenericConnectionFactory
+{
+
+ /**
+ * MSSQLConnectionFactory constructor.
+ *
+ * @param dataSource
+ * - DataSource
+ * @param dbDriver
+ * - JDBC Driver
+ * @param dbUrl
+ * - JDBC URL
+ * @param dbUserName
+ * - database username
+ * @param dbPassword
+ * - database user password
+ * @param containerName
+ * - Container name (see configuration)
+ * @param multiDb
+ * - multidatabase state flag
+ * @param valueStorageProvider
+ * - external Value Storages provider
+ * @param maxBufferSize
+ * - Maximum buffer size (see configuration)
+ * @param swapDirectory
+ * - Swap directory (see configuration)
+ * @param swapCleaner
+ * - Swap cleaner (internal FileCleaner).
+ * @throws RepositoryException
+ * if error eccurs
+ */
+ public MSSQLConnectionFactory(String dbDriver, String dbUrl, String dbUserName, String dbPassword,
+ String containerName, boolean multiDb, ValueStoragePluginProvider valueStorageProvider, int maxBufferSize,
+ File swapDirectory, FileCleaner swapCleaner) throws RepositoryException
+ {
+ super(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
+ }
+
+ /**
+ * MSSQLConnectionFactory constructor.
+ *
+ * @param dataSource
+ * - DataSource
+ * @param containerName
+ * - Container name (see configuration)
+ * @param multiDb
+ * - multidatabase state flag
+ * @param valueStorageProvider
+ * - external Value Storages provider
+ * @param maxBufferSize
+ * - Maximum buffer size (see configuration)
+ * @param swapDirectory
+ * - Swap directory (see configuration)
+ * @param swapCleaner
+ * - Swap cleaner (internal FileCleaner).
+ */
+ public MSSQLConnectionFactory(DataSource dbDataSource, String containerName, boolean multiDb,
+ ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+ {
+ super(dbDataSource, containerName, multiDb, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException
+ {
+ try
+ {
+ if (multiDb)
+ {
+ return new MSSQLMultiDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
+ valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
+ return new MSSQLSingleDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
+ valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLMultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLMultiDbJDBCConnection.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLMultiDbJDBCConnection.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.db;
+
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 19 mars 2010
+ */
+public class MSSQLMultiDbJDBCConnection extends MultiDbJDBCConnection
+{
+ /**
+ * MSSQL Multidatabase JDBC Connection constructor.
+ *
+ * @param dbConnection
+ * JDBC connection, shoudl be opened before
+ * @param readOnly
+ * boolean if true the dbConnection was marked as READ-ONLY.
+ * @param containerName
+ * Workspace Storage Container name (see configuration)
+ * @param valueStorageProvider
+ * External Value Storages provider
+ * @param maxBufferSize
+ * Maximum buffer size (see configuration)
+ * @param swapDirectory
+ * Swap directory File (see configuration)
+ * @param swapCleaner
+ * Swap cleaner (internal FileCleaner).
+ * @throws SQLException
+ *
+ * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+ */
+ public MSSQLMultiDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+ ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+ throws SQLException
+ {
+ super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void prepareQueries() throws SQLException
+ {
+ super.prepareQueries();
+ FIND_NODES_AND_PROPERTIES =
+ "select J.*, P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED,"
+ + " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM P"
+ + " join (select A.* from"
+ + " (select Row_Number() over (order by I.ID) as r__, I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM"
+ + " from JCR_SITEM I where I.I_CLASS=1) as A where A.r__ <= ? and A.r__ > ?) J on P.PARENT_ID = J.ID"
+ + " where P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by J.ID";
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLSingleDbJDBCConnection.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/MSSQLSingleDbJDBCConnection.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.db;
+
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 8 02 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: MSSQLSingleDbJDBCConnection.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class MSSQLSingleDbJDBCConnection extends SingleDbJDBCConnection
+{
+ /**
+ * MSSQL Singledatabase JDBC Connection constructor.
+ *
+ * @param dbConnection
+ * JDBC connection, should be opened before
+ * @param readOnly
+ * boolean if true the dbConnection was marked as READ-ONLY.
+ * @param containerName
+ * Workspace Storage Container name (see configuration)
+ * @param valueStorageProvider
+ * External Value Storages provider
+ * @param maxBufferSize
+ * Maximum buffer size (see configuration)
+ * @param swapDirectory
+ * Swap directory File (see configuration)
+ * @param swapCleaner
+ * Swap cleaner (internal FileCleaner).
+ * @throws SQLException
+ *
+ * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+ */
+ public MSSQLSingleDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+ ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+ throws SQLException
+ {
+ super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void prepareQueries() throws SQLException
+ {
+ super.prepareQueries();
+ FIND_NODES_AND_PROPERTIES =
+ "select J.*, P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED,"
+ + " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM P"
+ + " join (select A.* from"
+ + " (select Row_Number() over (order by I.ID) as r__, I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM"
+ + " from JCR_SITEM I where I.CONTAINER_NAME='?' and I.I_CLASS=1) as A where A.r__ <= ? and A.r__ > ?"
+ + ") J on P.PARENT_ID = J.ID"
+ + " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleMultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleMultiDbJDBCConnection.java 2011-02-08 08:30:07 UTC (rev 3939)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleMultiDbJDBCConnection.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -69,10 +69,9 @@
FIND_NODES_AND_PROPERTIES =
"select J.*, P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED,"
+ " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_MVALUE V, JCR_MITEM P"
- + " join ( select * ( select a.*, ROWNUM r__ from ("
+ + " join ( select * from ( select A.*, ROWNUM r__ from ("
+ " select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_MITEM I "
- + " where I.I_CLASS=1 order by I.ID"
- + " ) a where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ + " where I.I_CLASS=1 order by I.ID) A where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by J.ID";
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleSingleDbJDBCConnection.java 2011-02-08 08:30:07 UTC (rev 3939)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/db/OracleSingleDbJDBCConnection.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -69,10 +69,10 @@
FIND_NODES_AND_PROPERTIES =
"select J.*, P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED,"
+ " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM P"
- + " join ( select * ( select a.*, ROWNUM r__ from ("
+ + " join ( select * from ( select A.*, ROWNUM r__ from ("
+ " select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_SITEM I "
+ " where I.CONTAINER_NAME=? and I.I_CLASS=1 order by I.ID"
- + " ) a where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ + " ) A where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java 2011-02-08 08:30:07 UTC (rev 3939)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/CQJDBCWorkspaceDataContainer.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -31,6 +31,7 @@
import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.DefaultOracleConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.GenericCQConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.HSQLDBConnectionFactory;
+import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.MSSQLConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.MySQLConnectionFactory;
import org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db.OracleConnectionFactory;
import org.exoplatform.services.jcr.impl.util.io.FileCleanerHolder;
@@ -85,6 +86,7 @@
* @throws IOException
* on I/O error
*/
+ @Override
protected void initDatabase() throws NamingException, RepositoryException, IOException
{
@@ -185,7 +187,27 @@
}
else if (dbDialect == DBConstants.DB_DIALECT_MSSQL)
{
- this.connFactory = defaultConnectionFactory();
+ if (dbSourceName != null)
+ {
+ DataSource ds = (DataSource)new InitialContext().lookup(dbSourceName);
+ if (ds != null)
+ {
+ this.connFactory =
+ new MSSQLConnectionFactory(ds, containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
+ }
+ else
+ {
+ throw new RepositoryException("Datasource '" + dbSourceName + "' is not bound in this context.");
+ }
+ }
+ else
+ {
+ this.connFactory =
+ new MSSQLConnectionFactory(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb,
+ valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
sqlPath = "/conf/storage/jcr-" + (multiDb ? "m" : "s") + "jdbc.mssql.sql";
dbInitilizer = defaultDBInitializer(sqlPath);
}
@@ -268,6 +290,7 @@
* @throws RepositoryException
* on Storage error
*/
+ @Override
protected GenericConnectionFactory defaultConnectionFactory() throws NamingException, RepositoryException
{
// by default
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLConnectionFactory.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLConnectionFactory.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLConnectionFactory.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * 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.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db;
+
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.sql.SQLException;
+
+import javax.jcr.RepositoryException;
+import javax.sql.DataSource;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 8 02 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: MSSQLConnectionFactory.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class MSSQLConnectionFactory extends GenericCQConnectionFactory
+{
+
+ /**
+ * MSSQLConnectionFactory constructor.
+ *
+ * @param dataSource
+ * - DataSource
+ * @param dbDriver
+ * - JDBC Driver
+ * @param dbUrl
+ * - JDBC URL
+ * @param dbUserName
+ * - database username
+ * @param dbPassword
+ * - database user password
+ * @param containerName
+ * - Container name (see configuration)
+ * @param multiDb
+ * - multidatabase state flag
+ * @param valueStorageProvider
+ * - external Value Storages provider
+ * @param maxBufferSize
+ * - Maximum buffer size (see configuration)
+ * @param swapDirectory
+ * - Swap directory (see configuration)
+ * @param swapCleaner
+ * - Swap cleaner (internal FileCleaner).
+ * @throws RepositoryException
+ * if error eccurs
+ */
+ public MSSQLConnectionFactory(String dbDriver, String dbUrl, String dbUserName, String dbPassword,
+ String containerName, boolean multiDb, ValueStoragePluginProvider valueStorageProvider, int maxBufferSize,
+ File swapDirectory, FileCleaner swapCleaner) throws RepositoryException
+ {
+ super(dbDriver, dbUrl, dbUserName, dbPassword, containerName, multiDb, valueStorageProvider, maxBufferSize,
+ swapDirectory, swapCleaner);
+ }
+
+ /**
+ * MSSQLConnectionFactory constructor.
+ *
+ * @param dataSource
+ * - DataSource
+ * @param containerName
+ * - Container name (see configuration)
+ * @param multiDb
+ * - multidatabase state flag
+ * @param valueStorageProvider
+ * - external Value Storages provider
+ * @param maxBufferSize
+ * - Maximum buffer size (see configuration)
+ * @param swapDirectory
+ * - Swap directory (see configuration)
+ * @param swapCleaner
+ * - Swap cleaner (internal FileCleaner).
+ */
+ public MSSQLConnectionFactory(DataSource dbDataSource, String containerName, boolean multiDb,
+ ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+ {
+ super(dbDataSource, containerName, multiDb, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException
+ {
+ try
+ {
+ if (multiDb)
+ {
+ return new MSSQLMultiDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
+ valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
+ return new MSSQLSingleDbJDBCConnection(getJdbcConnection(readOnly), readOnly, containerName,
+ valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+
+ }
+ catch (SQLException e)
+ {
+ throw new RepositoryException(e);
+ }
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLMultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLMultiDbJDBCConnection.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLMultiDbJDBCConnection.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db;
+
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 19 mars 2010
+ */
+public class MSSQLMultiDbJDBCConnection extends MultiDbJDBCConnection
+{
+ /**
+ * MSSQL Multidatabase JDBC Connection constructor.
+ *
+ * @param dbConnection
+ * JDBC connection, shoudl be opened before
+ * @param readOnly
+ * boolean if true the dbConnection was marked as READ-ONLY.
+ * @param containerName
+ * Workspace Storage Container name (see configuration)
+ * @param valueStorageProvider
+ * External Value Storages provider
+ * @param maxBufferSize
+ * Maximum buffer size (see configuration)
+ * @param swapDirectory
+ * Swap directory File (see configuration)
+ * @param swapCleaner
+ * Swap cleaner (internal FileCleaner).
+ * @throws SQLException
+ *
+ * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+ */
+ public MSSQLMultiDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+ ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+ throws SQLException
+ {
+ super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ FIND_NODES_AND_PROPERTIES =
+ "select J.*, P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED,"
+ + " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM P"
+ + " join (select A.* from"
+ + " (select Row_Number() over (order by I.ID) as r__, I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM"
+ + " from JCR_SITEM I where I.I_CLASS=1) as A where A.r__ <= ? and A.r__ > ?) J on P.PARENT_ID = J.ID"
+ + " where P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by J.ID";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void prepareQueries() throws SQLException
+ {
+ super.prepareQueries();
+ }
+}
Added: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java (rev 0)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/MSSQLSingleDbJDBCConnection.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2003-2010 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.storage.jdbc.optimisation.db;
+
+import org.exoplatform.services.jcr.impl.util.io.FileCleaner;
+import org.exoplatform.services.jcr.storage.value.ValueStoragePluginProvider;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * Date: 8 02 2011
+ *
+ * @author <a href="mailto:anatoliy.bazko@exoplatform.com.ua">Anatoliy Bazko</a>
+ * @version $Id: MSSQLSingleDbJDBCConnection.java 34360 2010-11-11 11:11:11Z tolusha $
+ */
+public class MSSQLSingleDbJDBCConnection extends SingleDbJDBCConnection
+{
+ /**
+ * MSSQL Singledatabase JDBC Connection constructor.
+ *
+ * @param dbConnection
+ * JDBC connection, should be opened before
+ * @param readOnly
+ * boolean if true the dbConnection was marked as READ-ONLY.
+ * @param containerName
+ * Workspace Storage Container name (see configuration)
+ * @param valueStorageProvider
+ * External Value Storages provider
+ * @param maxBufferSize
+ * Maximum buffer size (see configuration)
+ * @param swapDirectory
+ * Swap directory File (see configuration)
+ * @param swapCleaner
+ * Swap cleaner (internal FileCleaner).
+ * @throws SQLException
+ *
+ * @see org.exoplatform.services.jcr.impl.util.io.FileCleaner
+ */
+ public MSSQLSingleDbJDBCConnection(Connection dbConnection, boolean readOnly, String containerName,
+ ValueStoragePluginProvider valueStorageProvider, int maxBufferSize, File swapDirectory, FileCleaner swapCleaner)
+ throws SQLException
+ {
+ super(dbConnection, readOnly, containerName, valueStorageProvider, maxBufferSize, swapDirectory, swapCleaner);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void prepareQueries() throws SQLException
+ {
+ super.prepareQueries();
+ FIND_NODES_AND_PROPERTIES =
+ "select J.*, P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED,"
+ + " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM P"
+ + " join (select A.* from"
+ + " (select Row_Number() over (order by I.ID) as r__, I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM"
+ + " from JCR_SITEM I where I.CONTAINER_NAME='?' and I.I_CLASS=1) as A where A.r__ <= ? and A.r__ > ?"
+ + ") J on P.PARENT_ID = J.ID"
+ + " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
+ }
+}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleMultiDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleMultiDbJDBCConnection.java 2011-02-08 08:30:07 UTC (rev 3939)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleMultiDbJDBCConnection.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -82,10 +82,9 @@
FIND_NODES_AND_PROPERTIES =
"select J.*, P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED,"
+ " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_MVALUE V, JCR_MITEM P"
- + " join ( select * ( select a.*, ROWNUM r__ from ("
+ + " join ( select * from ( select A.*, ROWNUM r__ from ("
+ " select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_MITEM I "
- + " where I.I_CLASS=1 order by I.ID"
- + " ) a where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ + " where I.I_CLASS=1 order by I.ID) A where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and V.PROPERTY_ID=P.ID order by J.ID";
}
}
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleSingleDbJDBCConnection.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleSingleDbJDBCConnection.java 2011-02-08 08:30:07 UTC (rev 3939)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/optimisation/db/OracleSingleDbJDBCConnection.java 2011-02-08 10:17:33 UTC (rev 3940)
@@ -83,10 +83,10 @@
FIND_NODES_AND_PROPERTIES =
"select J.*, P.ID AS P_ID, P.NAME AS P_NAME, P.VERSION AS P_VERSION, P.P_TYPE, P.P_MULTIVALUED,"
+ " V.DATA, V.ORDER_NUM, V.STORAGE_DESC from JCR_SVALUE V, JCR_SITEM P"
- + " join ( select * ( select a.*, ROWNUM r__ from ("
+ + " join ( select * from ( select A.*, ROWNUM r__ from ("
+ " select I.ID, I.PARENT_ID, I.NAME, I.VERSION, I.I_INDEX, I.N_ORDER_NUM from JCR_SITEM I "
+ " where I.CONTAINER_NAME=? and I.I_CLASS=1 order by I.ID"
- + " ) a where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ + " ) A where ROWNUM <= ?)) where r__ > ?) J on P.PARENT_ID = J.ID"
+ " where P.I_CLASS=2 and P.CONTAINER_NAME=? and V.PROPERTY_ID=P.ID order by J.ID";
}
}
13 years, 3 months
exo-jcr SVN: r3939 - in jcr/branches/1.12.x/patch/1.12.8-GA: JCR-1572 and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-08 03:30:07 -0500 (Tue, 08 Feb 2011)
New Revision: 3939
Added:
jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1572/
jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1572/JCR-1572.patch
Log:
JCR-1572: patch proposed
Added: jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1572/JCR-1572.patch
===================================================================
--- jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1572/JCR-1572.patch (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1572/JCR-1572.patch 2011-02-08 08:30:07 UTC (rev 3939)
@@ -0,0 +1,462 @@
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java (revision 3789)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java (working copy)
+@@ -43,9 +43,16 @@
+ import java.util.Iterator;
+ import java.util.List;
+ import java.util.Map;
++import java.util.Queue;
+ import java.util.Set;
+ import java.util.Timer;
+ import java.util.TimerTask;
++import java.util.concurrent.Callable;
++import java.util.concurrent.CountDownLatch;
++import java.util.concurrent.LinkedBlockingQueue;
++import java.util.concurrent.atomic.AtomicInteger;
++import java.util.concurrent.atomic.AtomicLong;
++import java.util.concurrent.atomic.AtomicReference;
+
+ import javax.jcr.ItemNotFoundException;
+ import javax.jcr.RepositoryException;
+@@ -214,6 +221,11 @@
+ private boolean reindexing = false;
+
+ /**
++ * Flag indicating whether the index is stopped.
++ */
++ private volatile boolean stopped;
++
++ /**
+ * The index format version of this multi index.
+ */
+ private final IndexFormatVersion version;
+@@ -314,6 +326,14 @@
+ setReadWrite();
+ }
+ this.indexNames.setMultiIndex(this);
++ // Add a hook that will stop the threads if they are still running
++ Runtime.getRuntime().addShutdownHook(new Thread()
++ {
++ public void run()
++ {
++ stopped = true;
++ }
++ });
+ }
+
+ /**
+@@ -374,11 +394,10 @@
+ reindexing = true;
+ try
+ {
+- long count = 0;
+ // traverse and index workspace
+ executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
+ // NodeData rootState = (NodeData) stateMgr.getItemData(rootId);
+- count = createIndex(indexingTree.getIndexingRoot(), stateMgr, count);
++ long count = createIndex(indexingTree.getIndexingRoot(), stateMgr);
+ executeAndLog(new Commit(getTransactionId()));
+ log.info("Created initial index for {} nodes", new Long(count));
+ releaseMultiReader();
+@@ -951,6 +970,7 @@
+ }
+ }
+ }
++ this.stopped = true;
+ }
+
+ /**
+@@ -1297,44 +1317,118 @@
+ * @throws RepositoryException
+ * if any other error occurs
+ */
+- private long createIndex(NodeData node, ItemDataConsumer stateMgr, long count) throws IOException,
++ private long createIndex(NodeData node, ItemDataConsumer stateMgr) throws IOException,
+ RepositoryException
+ {
++ MultithreadedIndexing indexing = new MultithreadedIndexing(node, stateMgr);
++ return indexing.launch(false);
++ }
++
++ /**
++ * Recursively creates an index starting with the NodeState
++ * <code>node</code>.
++ *
++ * @pamam tasks
++ * the queue of existing indexing tasks
++ * @param node
++ * the current NodeState.
++ * @param stateMgr
++ * the shared item state manager.
++ * @param count
++ * the number of nodes already indexed.
++ * @throws IOException
++ * if an error occurs while writing to the index.
++ * @throws ItemStateException
++ * if an node state cannot be found.
++ * @throws RepositoryException
++ * if any other error occurs
++ * @throws InterruptedException
++ * if the task has been interrupted
++ */
++ private void createIndex(final Queue<Callable<Void>> tasks, final NodeData node, final ItemDataConsumer stateMgr, final AtomicLong count) throws IOException,
++ RepositoryException, InterruptedException
++ {
++ if (stopped)
++ {
++ throw new InterruptedException();
++ }
+ // NodeId id = node.getNodeId();
+
+ if (indexingTree.isExcluded(node))
+ {
+- return count;
++ return;
+ }
+- executeAndLog(new AddNode(getTransactionId(), node.getIdentifier()));
+- if (++count % 100 == 0)
++ executeAndLog(new AddNode(getTransactionId(), node.getIdentifier(), true));
++ if (count.incrementAndGet() % 1000 == 0)
+ {
+-
+- log.info("indexing... {} ({})", node.getQPath().getAsString(), new Long(count));
++ log.info("indexing... {} ({})", node.getQPath().getAsString(), new Long(count.get()));
+ }
+- if (count % 10 == 0)
++ synchronized (this)
+ {
+- checkIndexingQueue(true);
++ if (count.get() % 10 == 0)
++ {
++ checkIndexingQueue(true);
++ }
++ checkVolatileCommit();
+ }
+- checkVolatileCommit();
+ List<NodeData> children = stateMgr.getChildNodesData(node);
+- for (NodeData nodeData : children)
++ for (final NodeData nodeData : children)
+ {
+-
+- NodeData childState = (NodeData)stateMgr.getItemData(nodeData.getIdentifier());
+- if (childState == null)
++ Callable<Void> task = new Callable<Void>()
+ {
+- handler.getOnWorkspaceInconsistencyHandler().handleMissingChildNode(
+- new ItemNotFoundException("Child not found "), handler, nodeData.getQPath(), node, nodeData);
+- }
++ public Void call() throws Exception
++ {
++ createIndex(tasks, node, stateMgr, count, nodeData);
++ return null;
++ }
+
+- if (nodeData != null)
++ };
++ if (!tasks.offer(task))
+ {
+- count = createIndex(nodeData, stateMgr, count);
++ // All threads have tasks to do so we do it ourself
++ createIndex(tasks, node, stateMgr, count, nodeData);
+ }
+ }
++ }
++
++ /**
++ * Recursively creates an index starting with the NodeState
++ * <code>node</code>.
++ *
++ * @pamam tasks
++ * the queue of existing indexing tasks
++ * @param node
++ * the current NodeState.
++ * @param stateMgr
++ * the shared item state manager.
++ * @param count
++ * the number of nodes already indexed.
++ * @param nodeData
++ * the node data to index.
++ * @throws IOException
++ * if an error occurs while writing to the index.
++ * @throws ItemStateException
++ * if an node state cannot be found.
++ * @throws RepositoryException
++ * if any other error occurs
++ * @throws InterruptedException
++ * if the task has been interrupted
++ */
++ private void createIndex(final Queue<Callable<Void>> tasks, final NodeData node,
++ final ItemDataConsumer stateMgr, final AtomicLong count, final NodeData nodeData)
++ throws RepositoryException, IOException, InterruptedException
++ {
++ NodeData childState = (NodeData)stateMgr.getItemData(nodeData.getIdentifier());
++ if (childState == null)
++ {
++ handler.getOnWorkspaceInconsistencyHandler().handleMissingChildNode(
++ new ItemNotFoundException("Child not found "), handler, nodeData.getQPath(), node, nodeData);
++ }
+
+- return count;
++ if (nodeData != null)
++ {
++ createIndex(tasks, nodeData, stateMgr, count);
++ }
+ }
+
+ /**
+@@ -1850,6 +1944,8 @@
+ */
+ private Document doc;
+
++ private boolean synch;
++
+ /**
+ * Creates a new AddNode action.
+ *
+@@ -1860,8 +1956,22 @@
+ */
+ AddNode(long transactionId, String uuid)
+ {
++ this(transactionId, uuid, false);
++ }
++
++ /**
++ * Creates a new AddNode action.
++ *
++ * @param transactionId
++ * the id of the transaction that executes this action.
++ * @param uuid
++ * the uuid of the node to add.
++ */
++ AddNode(long transactionId, String uuid, boolean synch)
++ {
+ super(transactionId, Action.TYPE_ADD_NODE);
+ this.uuid = uuid;
++ this.synch = synch;
+ }
+
+ /**
+@@ -1921,7 +2031,17 @@
+ }
+ if (doc != null)
+ {
+- index.volatileIndex.addDocuments(new Document[]{doc});
++ if (synch)
++ {
++ synchronized (index)
++ {
++ index.volatileIndex.addDocuments(new Document[]{doc});
++ }
++ }
++ else
++ {
++ index.volatileIndex.addDocuments(new Document[]{doc});
++ }
+ }
+ }
+
+@@ -2559,4 +2679,203 @@
+ }
+ }
+ }
++
++ /**
++ * This class is used to index a node and its descendants nodes with several threads
++ */
++ private class MultithreadedIndexing
++ {
++ /**
++ * This instance of {@link AtomicReference} will contain the exception meet if any exception has occurred
++ */
++ private final AtomicReference<Exception> exception = new AtomicReference<Exception>();
++
++ /**
++ * The total amount of threads used for the indexing
++ */
++ private final int nThreads = Runtime.getRuntime().availableProcessors();
++
++ /**
++ * The {@link CountDownLatch} used to notify that the indexing is over
++ */
++ private final CountDownLatch endSignal = new CountDownLatch(nThreads);
++
++ /**
++ * The total amount of threads currently working
++ */
++ private final AtomicInteger runningThreads = new AtomicInteger();
++
++ /**
++ * The total amount of nodes already indexed
++ */
++ private final AtomicLong count = new AtomicLong();
++
++ /**
++ * The list of indexing tasks left to do
++ */
++ private final Queue<Callable<Void>> tasks = new LinkedBlockingQueue<Callable<Void>>(nThreads)
++ {
++ private static final long serialVersionUID = 1L;
++
++ @Override
++ public Callable<Void> poll()
++ {
++ Callable<Void> task;
++ synchronized (runningThreads)
++ {
++ if ((task = super.poll()) != null)
++ {
++ runningThreads.incrementAndGet();
++ }
++ }
++ return task;
++ }
++
++ @Override
++ public boolean offer(Callable<Void> o)
++ {
++ if (super.offer(o))
++ {
++ synchronized (runningThreads)
++ {
++ runningThreads.notifyAll();
++ }
++ return true;
++ }
++ return false;
++ }
++ };
++
++ /**
++ * The task that all the indexing threads have to execute
++ */
++ private final Runnable indexingTask = new Runnable()
++ {
++ public void run()
++ {
++ while (exception.get() == null)
++ {
++ Callable<Void> task;
++ while (exception.get() == null && (task = tasks.poll()) != null)
++ {
++ try
++ {
++ task.call();
++ }
++ catch (InterruptedException e)
++ {
++ Thread.currentThread().interrupt();
++ }
++ catch (Exception e)
++ {
++ exception.set(e);
++ }
++ finally
++ {
++ synchronized (runningThreads)
++ {
++ runningThreads.decrementAndGet();
++ runningThreads.notifyAll();
++ }
++ }
++ }
++ synchronized (runningThreads)
++ {
++ if (exception.get() == null && (runningThreads.get() > 0))
++ {
++ try
++ {
++ runningThreads.wait();
++ }
++ catch (InterruptedException e)
++ {
++ Thread.currentThread().interrupt();
++ }
++ }
++ else
++ {
++ break;
++ }
++ }
++ }
++ endSignal.countDown();
++ }
++ };
++
++ /**
++ * Default constructor
++ * @param node
++ * the current NodeState.
++ * @param stateMgr
++ * the shared item state manager.
++ */
++ public MultithreadedIndexing(final NodeData node, final ItemDataConsumer stateMgr)
++ {
++ tasks.offer(new Callable<Void>()
++ {
++ public Void call() throws Exception
++ {
++ createIndex(tasks, node, stateMgr, count);
++ return null;
++ }
++ });
++ }
++
++ /**
++ * Launches the indexing
++ * @param asynchronous indicates whether or not the current thread needs to wait until the
++ * end of the indexing
++ * @return the total amount of nodes that have been indexed. <code>-1</code> in case of an
++ * asynchronous indexing
++ * @throws IOException
++ * if an error occurs while writing to the index.
++ * @throws ItemStateException
++ * if an node state cannot be found.
++ * @throws RepositoryException
++ * if any other error occurs
++ */
++ public long launch(boolean asynchronous) throws IOException, RepositoryException
++ {
++ startThreads();
++ if (!asynchronous)
++ {
++ try
++ {
++ endSignal.await();
++ if (exception.get() != null)
++ {
++ if (exception.get() instanceof IOException)
++ {
++ throw (IOException)exception.get();
++ }
++ else if (exception.get() instanceof RepositoryException)
++ {
++ throw (RepositoryException)exception.get();
++ }
++ else
++ {
++ throw new RuntimeException("Error while indexing", exception.get());
++ }
++ }
++ return count.get();
++ }
++ catch (InterruptedException e)
++ {
++ Thread.currentThread().interrupt();
++ }
++ }
++ return -1L;
++ }
++
++ /**
++ * Starts all the indexing threads
++ */
++ private void startThreads()
++ {
++ for (int i=0; i < nThreads; i++)
++ {
++ (new Thread(indexingTask, "Indexing Thread #" + (i + 1))).start();
++ }
++ }
++ }
+ }
\ No newline at end of file
13 years, 3 months
exo-jcr SVN: r3938 - in jcr/branches/1.12.x/patch: 1.12.8-GA and 1 other directories.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-08 03:28:50 -0500 (Tue, 08 Feb 2011)
New Revision: 3938
Added:
jcr/branches/1.12.x/patch/1.12.8-GA/
jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1577/
jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1577/JCR-1577.patch
Log:
JCR-1577: patch proposed
Added: jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1577/JCR-1577.patch
===================================================================
--- jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1577/JCR-1577.patch (rev 0)
+++ jcr/branches/1.12.x/patch/1.12.8-GA/JCR-1577/JCR-1577.patch 2011-02-08 08:28:50 UTC (rev 3938)
@@ -0,0 +1,13 @@
+Index: exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/DefaultChangesFilter.java
+===================================================================
+--- exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/DefaultChangesFilter.java (revision 3814)
++++ exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/DefaultChangesFilter.java (working copy)
+@@ -117,7 +117,7 @@
+ log.error("Error indexing changes " + e, e);
+ try
+ {
+- parentHandler.logErrorChanges(removedNodes, addedNodes);
++ parentHandler.logErrorChanges(parentRemovedNodes, parentAddedNodes);
+ }
+ catch (IOException ioe)
+ {
13 years, 3 months
exo-jcr SVN: r3937 - in jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl: storage/jdbc/indexing and 1 other directory.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-07 16:21:49 -0500 (Mon, 07 Feb 2011)
New Revision: 3937
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java
Log:
EXOJCR-1104: RDBMS reindexing is multithreaded
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-07 18:54:11 UTC (rev 3936)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-07 21:21:49 UTC (rev 3937)
@@ -435,10 +435,10 @@
// NodeData rootState = (NodeData) stateMgr.getItemData(rootId);
// check if we have deal with JDBC indexing mechanism
Indexable indexableComponent = (Indexable)handler.getContext().getContainer().getComponent(Indexable.class);
- long count = createIndex(indexingTree.getIndexingRoot(), stateMgr);
- // long count =
- // indexableComponent == null ? createIndex(indexingTree.getIndexingRoot(), stateMgr) : createIndex(
- // indexableComponent, indexingTree.getIndexingRoot());
+ long count =
+ indexableComponent == null ? createIndex(indexingTree.getIndexingRoot(), stateMgr) : createIndex(
+ indexableComponent.getNodeDataIndexingIterator(handler.getReindexingPageSize()),
+ indexingTree.getIndexingRoot());
executeAndLog(new Commit(getTransactionId()));
log.info("Created initial index for {} nodes", new Long(count));
@@ -1533,60 +1533,118 @@
}
/**
- * Creates an index.
- * <code>node</code>.
+ * Create index.
*
- * @param indexableComponent
- * the component which responsible for quick indexing
+ * @param iterator
+ * the NodeDataIndexing iterator
* @param rootNode
- * the current NodeState.
- * @param path
- * the path of the current node.
+ * the root node of the index
+ * @return the total amount of indexed nodes
+ * @throws IOException
+ * if an error occurs while writing to the index.
+ * @throws RepositoryException
+ * if any other error occurs
+ */
+ private long createIndex(NodeDataIndexingIterator iterator, NodeData rootNode) throws IOException,
+ RepositoryException
+ {
+ MultithreadedIndexing indexing = new MultithreadedIndexing(iterator, rootNode);
+ return indexing.launch(false);
+ }
+
+ /**
+ * Create index.
+ *
+ * @param iterator
+ * the NodeDataIndexing iterator
+ * @param rootNode
+ * the root node of the index
* @param count
* the number of nodes already indexed.
- * @return the number of nodes indexed so far.
* @throws IOException
* if an error occurs while writing to the index.
- * @throws ItemStateException
- * if an node state cannot be found.
* @throws RepositoryException
* if any other error occurs
+ * @throws InterruptedException
+ * if the task has been interrupted
*/
- private long createIndex(Indexable indexableComponent, NodeData rootNode, long count) throws IOException,
- RepositoryException
+ private void createIndex(final NodeDataIndexingIterator iterator, NodeData rootNode, final AtomicLong count)
+ throws RepositoryException, InterruptedException, IOException
{
- NodeDataIndexingIterator iterator =
- indexableComponent.getNodeDataIndexingIterator(handler.getReindexingPageSize());
-
- while (iterator.hasNext())
+ for (NodeDataIndexing node : iterator.next())
{
- for (NodeDataIndexing node : iterator.next())
+ if (stopped)
{
- if (indexingTree.isExcluded(node))
- {
- continue;
- }
+ throw new InterruptedException();
+ }
- if (!node.getQPath().isDescendantOf(rootNode.getQPath()) && !node.getQPath().equals(rootNode.getQPath()))
- {
- continue;
- }
+ if (indexingTree.isExcluded(node))
+ {
+ continue;
+ }
- executeAndLog(new AddNode(getTransactionId(), node, true));
+ if (!node.getQPath().isDescendantOf(rootNode.getQPath()) && !node.getQPath().equals(rootNode.getQPath()))
+ {
+ continue;
+ }
- if (++count % 100 == 0)
+ executeAndLog(new AddNode(getTransactionId(), node, true));
+ if (count.incrementAndGet() % 1000 == 0)
+ {
+ log.info("indexing... {} ({})", node.getQPath().getAsString(), new Long(count.get()));
+ }
+
+ synchronized (this)
+ {
+ if (count.get() % 10 == 0)
{
- log.info("indexing... {} ({})", node.getQPath().getAsString(), new Long(count));
- }
- if (count % 10 == 0)
- {
checkIndexingQueue(true);
}
checkVolatileCommit();
}
}
+ }
- return count;
+ /**
+ * Creates an index.
+ *
+ * @param tasks
+ * the queue of existing indexing tasks
+ * @param rootNode
+ * the root node of the index
+ * @param iterator
+ * the NodeDataIndexing iterator
+ * @param count
+ * the number of nodes already indexed.
+ * @throws IOException
+ * if an error occurs while writing to the index.
+ * @throws ItemStateException
+ * if an node state cannot be found.
+ * @throws RepositoryException
+ * if any other error occurs
+ * @throws InterruptedException
+ * if thread was interrupted
+ */
+ private void createIndex(final Queue<Callable<Void>> tasks, final NodeDataIndexingIterator iterator,
+ final NodeData rootNode, final AtomicLong count) throws IOException, RepositoryException, InterruptedException
+ {
+ while (iterator.hasNext())
+ {
+ Callable<Void> task = new Callable<Void>()
+ {
+ public Void call() throws Exception
+ {
+ createIndex(iterator, rootNode, count);
+ return null;
+ }
+ };
+
+ if (!tasks.offer(task))
+ {
+ // All threads have tasks to do so we do it ourself
+ createIndex(iterator, rootNode, count);
+ }
+ }
}
/**
@@ -3005,7 +3063,8 @@
};
/**
- * Default constructor
+ * MultithreadedIndexing constructor.
+ *
* @param node
* the current NodeState.
* @param stateMgr
@@ -3024,6 +3083,26 @@
}
/**
+ * MultithreadedIndexing constructor.
+ *
+ * @param node
+ * the current NodeState.
+ * @param iterator
+ * NodeDataIndexingIterator
+ */
+ public MultithreadedIndexing(final NodeDataIndexingIterator iterator, final NodeData rootNode)
+ {
+ tasks.offer(new Callable<Void>()
+ {
+ public Void call() throws Exception
+ {
+ createIndex(tasks, iterator, rootNode, count);
+ return null;
+ }
+ });
+ }
+
+ /**
* Launches the indexing
* @param asynchronous indicates whether or not the current thread needs to wait until the
* end of the indexing
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java 2011-02-07 18:54:11 UTC (rev 3936)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/storage/jdbc/indexing/JdbcNodeDataIndexingIterator.java 2011-02-07 21:21:49 UTC (rev 3937)
@@ -25,7 +25,10 @@
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
+import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.jcr.RepositoryException;
@@ -55,17 +58,17 @@
/**
* The current offset in database.
*/
- private int offset = 0;
+ private AtomicInteger offset = new AtomicInteger(0);
/**
- * Logger.
+ * Indicates if not all records have been read from database.
*/
- protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.JdbcIndexingDataIterator");
+ private AtomicBoolean hasNext = new AtomicBoolean(true);
/**
- * The list of nodes to return in next() method.
+ * Logger.
*/
- private List<NodeDataIndexing> current;
+ protected static final Log LOG = ExoLogger.getLogger("exo.jcr.component.core.JdbcIndexingDataIterator");
/**
* Constructor JdbcIndexingDataIterator.
@@ -75,41 +78,24 @@
{
this.connFactory = connFactory;
this.pageSize = pageSize;
- this.current = readNext();
}
/**
* {@inheritDoc}
*/
- public boolean hasNext()
- {
- return this.current.size() != 0;
- }
-
- /**
- * {@inheritDoc}
- */
public List<NodeDataIndexing> next() throws RepositoryException
{
- List<NodeDataIndexing> next = this.current;
- this.current = readNext();
+ if (!hasNext())
+ {
+ // avoid unnecessary request to database
+ return new ArrayList<NodeDataIndexing>();
+ }
- return next;
- }
-
- /**
- * Read nodes from database.
- *
- * @return List<NodeDataIndexing>
- * @throws RepositoryException
- */
- private List<NodeDataIndexing> readNext() throws RepositoryException
- {
JDBCStorageConnection conn = (JDBCStorageConnection)connFactory.openConnection();
try
{
- List<NodeDataIndexing> result = conn.getNodesAndProperties(offset, pageSize);
- offset += pageSize;
+ List<NodeDataIndexing> result = conn.getNodesAndProperties(offset.getAndAdd(pageSize), pageSize);
+ hasNext.compareAndSet(true, result.size() == pageSize);
return result;
}
@@ -118,5 +104,13 @@
conn.close();
}
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean hasNext()
+ {
+ return hasNext.get();
+ }
}
13 years, 3 months
exo-jcr SVN: r3936 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-07 13:54:11 -0500 (Mon, 07 Feb 2011)
New Revision: 3936
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
Log:
EXOJCR-1184: Improve the re-indexing mechanism to take advantage of multi-cores: wrap addShutDownHook in privileged block
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-07 17:56:22 UTC (rev 3935)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-07 18:54:11 UTC (rev 3936)
@@ -345,13 +345,21 @@
setReadWrite();
}
this.indexNames.setMultiIndex(this);
+
// Add a hook that will stop the threads if they are still running
- Runtime.getRuntime().addShutdownHook(new Thread()
+ SecurityHelper.doPrivilegedAction(new PrivilegedAction<Object>()
{
- @Override
- public void run()
+ public Void run()
{
- stopped = true;
+ Runtime.getRuntime().addShutdownHook(new Thread()
+ {
+ @Override
+ public void run()
+ {
+ stopped = true;
+ }
+ });
+ return null;
}
});
}
@@ -425,15 +433,13 @@
executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
// NodeData rootState = (NodeData) stateMgr.getItemData(rootId);
-
// check if we have deal with JDBC indexing mechanism
Indexable indexableComponent = (Indexable)handler.getContext().getContainer().getComponent(Indexable.class);
+ long count = createIndex(indexingTree.getIndexingRoot(), stateMgr);
// long count =
// indexableComponent == null ? createIndex(indexingTree.getIndexingRoot(), stateMgr) : createIndex(
// indexableComponent, indexingTree.getIndexingRoot());
- long count = createIndex(indexingTree.getIndexingRoot(), stateMgr);
-
executeAndLog(new Commit(getTransactionId()));
log.info("Created initial index for {} nodes", new Long(count));
releaseMultiReader();
@@ -1527,7 +1533,7 @@
}
/**
- * Recursively creates an index starting with the NodeState
+ * Creates an index.
* <code>node</code>.
*
* @param indexableComponent
@@ -1566,7 +1572,7 @@
continue;
}
- executeAndLog(new AddNode(getTransactionId(), node));
+ executeAndLog(new AddNode(getTransactionId(), node, true));
if (++count % 100 == 0)
{
@@ -2103,6 +2109,9 @@
*/
private Document doc;
+ /**
+ * Indicates if need to execute command in synchronize mode.
+ */
private boolean synch;
/**
@@ -2127,9 +2136,11 @@
* Creates a new AddNode action.
*
* @param transactionId
- * the id of the transaction that executes this action.
+ * the id of the transaction that executes this action
* @param uuid
- * the uuid of the node to add.
+ * the uuid of the node to add
+ * @param synch
+ * indicates if need to execute command in synchronize mode
*/
AddNode(long transactionId, String uuid, boolean synch)
{
@@ -2145,10 +2156,12 @@
* the id of the transaction that executes this action.
* @param uuid
* the uuid of the node to add.
+ * @param synch
+ * indicates if need to execute command in synchronize mode
*/
- AddNode(long transactionId, NodeDataIndexing node)
+ AddNode(long transactionId, NodeDataIndexing node, boolean synch)
{
- this(transactionId, node.getIdentifier());
+ this(transactionId, node.getIdentifier(), synch);
this.node = node;
}
@@ -3014,7 +3027,8 @@
* Launches the indexing
* @param asynchronous indicates whether or not the current thread needs to wait until the
* end of the indexing
- * @return the total amount of nodes that have been indexed. <code>-1</code> in case of an
+
+ * @return the total amount of nodes that have been indexed. <code>-1</code> in case of an
* asynchronous indexing
* @throws IOException
* if an error occurs while writing to the index.
13 years, 3 months
exo-jcr SVN: r3935 - jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene.
by do-not-reply@jboss.org
Author: tolusha
Date: 2011-02-07 12:56:22 -0500 (Mon, 07 Feb 2011)
New Revision: 3935
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
Log:
EXOJCR-1184: Improve the re-indexing mechanism to take advantage of multi-cores
Modified: jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
--- jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-07 16:24:25 UTC (rev 3934)
+++ jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2011-02-07 17:56:22 UTC (rev 3935)
@@ -49,9 +49,16 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Queue;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
import javax.jcr.ItemNotFoundException;
import javax.jcr.RepositoryException;
@@ -220,6 +227,11 @@
private boolean reindexing = false;
/**
+ * Flag indicating whether the index is stopped.
+ */
+ private volatile boolean stopped;
+
+ /**
* The index format version of this multi index.
*/
private final IndexFormatVersion version;
@@ -333,6 +345,15 @@
setReadWrite();
}
this.indexNames.setMultiIndex(this);
+ // Add a hook that will stop the threads if they are still running
+ Runtime.getRuntime().addShutdownHook(new Thread()
+ {
+ @Override
+ public void run()
+ {
+ stopped = true;
+ }
+ });
}
/**
@@ -400,7 +421,6 @@
reindexing = true;
try
{
- long count = 0;
// traverse and index workspace
executeAndLog(new Start(Action.INTERNAL_TRANSACTION));
@@ -408,14 +428,12 @@
// check if we have deal with JDBC indexing mechanism
Indexable indexableComponent = (Indexable)handler.getContext().getContainer().getComponent(Indexable.class);
- if (indexableComponent == null)
- {
- count = createIndex(indexingTree.getIndexingRoot(), stateMgr, count);
- }
- else
- {
- count = createIndex(indexableComponent, indexingTree.getIndexingRoot(), count);
- }
+ // long count =
+ // indexableComponent == null ? createIndex(indexingTree.getIndexingRoot(), stateMgr) : createIndex(
+ // indexableComponent, indexingTree.getIndexingRoot());
+
+ long count = createIndex(indexingTree.getIndexingRoot(), stateMgr);
+
executeAndLog(new Commit(getTransactionId()));
log.info("Created initial index for {} nodes", new Long(count));
releaseMultiReader();
@@ -1016,6 +1034,7 @@
}
}
}
+ this.stopped = true;
}
/**
@@ -1393,65 +1412,118 @@
}
}
+ private long createIndex(NodeData node, ItemDataConsumer stateMgr) throws IOException, RepositoryException
+ {
+ MultithreadedIndexing indexing = new MultithreadedIndexing(node, stateMgr);
+ return indexing.launch(false);
+ }
+
/**
* Recursively creates an index starting with the NodeState
* <code>node</code>.
*
+ * @param tasks
+ * the queue of existing indexing tasks
* @param node
* the current NodeState.
- * @param path
- * the path of the current node.
* @param stateMgr
- * the shared item state manager.
+ * the shared item state manager.
* @param count
* the number of nodes already indexed.
- * @return the number of nodes indexed so far.
* @throws IOException
* if an error occurs while writing to the index.
* @throws ItemStateException
* if an node state cannot be found.
* @throws RepositoryException
* if any other error occurs
+ * @throws InterruptedException
+ * if the task has been interrupted
*/
- private long createIndex(NodeData node, ItemDataConsumer stateMgr, long count) throws IOException,
- RepositoryException
+ private void createIndex(final Queue<Callable<Void>> tasks, final NodeData node, final ItemDataConsumer stateMgr,
+ final AtomicLong count) throws IOException, RepositoryException, InterruptedException
{
- // NodeId id = node.getNodeId();
+ if (stopped)
+ {
+ throw new InterruptedException();
+ }
if (indexingTree.isExcluded(node))
{
- return count;
+ return;
}
- executeAndLog(new AddNode(getTransactionId(), node.getIdentifier()));
- if (++count % 100 == 0)
+ executeAndLog(new AddNode(getTransactionId(), node.getIdentifier(), true));
+ if (count.incrementAndGet() % 1000 == 0)
{
+ log.info("indexing... {} ({})", node.getQPath().getAsString(), new Long(count.get()));
+ }
- log.info("indexing... {} ({})", node.getQPath().getAsString(), new Long(count));
- }
- if (count % 10 == 0)
+ synchronized (this)
{
- checkIndexingQueue(true);
+ if (count.get() % 10 == 0)
+ {
+ checkIndexingQueue(true);
+ }
+ checkVolatileCommit();
}
- checkVolatileCommit();
+
List<NodeData> children = stateMgr.getChildNodesData(node);
- for (NodeData nodeData : children)
+ for (final NodeData nodeData : children)
{
- NodeData childState = (NodeData)stateMgr.getItemData(nodeData.getIdentifier());
- if (childState == null)
+ Callable<Void> task = new Callable<Void>()
{
- handler.getOnWorkspaceInconsistencyHandler().handleMissingChildNode(
- new ItemNotFoundException("Child not found "), handler, nodeData.getQPath(), node, nodeData);
- }
-
- if (nodeData != null)
+ public Void call() throws Exception
+ {
+ createIndex(tasks, node, stateMgr, count, nodeData);
+ return null;
+ }
+ };
+ if (!tasks.offer(task))
{
- count = createIndex(nodeData, stateMgr, count);
+ // All threads have tasks to do so we do it ourself
+ createIndex(tasks, node, stateMgr, count, nodeData);
}
}
+ }
- return count;
+ /**
+ * Recursively creates an index starting with the NodeState
+ * <code>node</code>.
+ *
+ * @param tasks
+ * the queue of existing indexing tasks
+ * @param node
+ * the current NodeState.
+ * @param stateMgr
+ * the shared item state manager.
+ * @param count
+ * the number of nodes already indexed.
+ * @param nodeData
+ * the node data to index.
+ * @throws IOException
+ * if an error occurs while writing to the index.
+ * @throws ItemStateException
+ * if an node state cannot be found.
+ * @throws RepositoryException
+ * if any other error occurs
+ * @throws InterruptedException
+ * if the task has been interrupted
+ */
+ private void createIndex(final Queue<Callable<Void>> tasks, final NodeData node, final ItemDataConsumer stateMgr,
+ final AtomicLong count, final NodeData nodeData) throws RepositoryException, IOException, InterruptedException
+ {
+ NodeData childState = (NodeData)stateMgr.getItemData(nodeData.getIdentifier());
+ if (childState == null)
+ {
+ handler.getOnWorkspaceInconsistencyHandler().handleMissingChildNode(
+ new ItemNotFoundException("Child not found "), handler, nodeData.getQPath(), node, nodeData);
+ }
+
+ if (nodeData != null)
+ {
+ createIndex(tasks, nodeData, stateMgr, count);
+ }
}
/**
@@ -1474,8 +1546,8 @@
* @throws RepositoryException
* if any other error occurs
*/
- private long createIndex(Indexable indexableComponent, NodeData rootNode, long count)
- throws IOException, RepositoryException
+ private long createIndex(Indexable indexableComponent, NodeData rootNode, long count) throws IOException,
+ RepositoryException
{
NodeDataIndexingIterator iterator =
indexableComponent.getNodeDataIndexingIterator(handler.getReindexingPageSize());
@@ -2017,8 +2089,8 @@
/**
* The maximum length of a AddNode String.
*/
- private static final int ENTRY_LENGTH =
- Long.toString(Long.MAX_VALUE).length() + Action.ADD_NODE.length() + Constants.UUID_FORMATTED_LENGTH + 2;
+ private static final int ENTRY_LENGTH = Long.toString(Long.MAX_VALUE).length() + Action.ADD_NODE.length()
+ + Constants.UUID_FORMATTED_LENGTH + 2;
/**
* The uuid of the node to add.
@@ -2031,6 +2103,8 @@
*/
private Document doc;
+ private boolean synch;
+
/**
* The node to add.
*/
@@ -2046,8 +2120,22 @@
*/
AddNode(long transactionId, String uuid)
{
+ this(transactionId, uuid, false);
+ }
+
+ /**
+ * Creates a new AddNode action.
+ *
+ * @param transactionId
+ * the id of the transaction that executes this action.
+ * @param uuid
+ * the uuid of the node to add.
+ */
+ AddNode(long transactionId, String uuid, boolean synch)
+ {
super(transactionId, Action.TYPE_ADD_NODE);
this.uuid = uuid;
+ this.synch = synch;
}
/**
@@ -2126,9 +2214,20 @@
log.debug(e.getMessage());
}
}
+
if (doc != null)
{
- index.volatileIndex.addDocuments(new Document[]{doc});
+ if (synch)
+ {
+ synchronized (index)
+ {
+ index.volatileIndex.addDocuments(new Document[]{doc});
+ }
+ }
+ else
+ {
+ index.volatileIndex.addDocuments(new Document[]{doc});
+ }
}
}
@@ -2385,8 +2484,8 @@
/**
* The maximum length of a DeleteNode String.
*/
- private static final int ENTRY_LENGTH =
- Long.toString(Long.MAX_VALUE).length() + Action.DELETE_NODE.length() + Constants.UUID_FORMATTED_LENGTH + 2;
+ private static final int ENTRY_LENGTH = Long.toString(Long.MAX_VALUE).length() + Action.DELETE_NODE.length()
+ + Constants.UUID_FORMATTED_LENGTH + 2;
/**
* The uuid of the node to remove.
@@ -2631,7 +2730,7 @@
{
// try to stop merger in safe way
merger.dispose();
-
+
flushTask.cancel();
FLUSH_TIMER.purge();
this.redoLog = null;
@@ -2769,4 +2868,203 @@
}
}
}
+
+ /**
+ * This class is used to index a node and its descendants nodes with several threads
+ */
+ private class MultithreadedIndexing
+ {
+ /**
+ * This instance of {@link AtomicReference} will contain the exception meet if any exception has occurred
+ */
+ private final AtomicReference<Exception> exception = new AtomicReference<Exception>();
+
+ /**
+ * The total amount of threads used for the indexing
+ */
+ private final int nThreads = Runtime.getRuntime().availableProcessors();
+
+ /**
+ * The {@link CountDownLatch} used to notify that the indexing is over
+ */
+ private final CountDownLatch endSignal = new CountDownLatch(nThreads);
+
+ /**
+ * The total amount of threads currently working
+ */
+ private final AtomicInteger runningThreads = new AtomicInteger();
+
+ /**
+ * The total amount of nodes already indexed
+ */
+ private final AtomicLong count = new AtomicLong();
+
+ /**
+ * The list of indexing tasks left to do
+ */
+ private final Queue<Callable<Void>> tasks = new LinkedBlockingQueue<Callable<Void>>(nThreads)
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Callable<Void> poll()
+ {
+ Callable<Void> task;
+ synchronized (runningThreads)
+ {
+ if ((task = super.poll()) != null)
+ {
+ runningThreads.incrementAndGet();
+ }
+ }
+ return task;
+ }
+
+ @Override
+ public boolean offer(Callable<Void> o)
+ {
+ if (super.offer(o))
+ {
+ synchronized (runningThreads)
+ {
+ runningThreads.notifyAll();
+ }
+ return true;
+ }
+ return false;
+ }
+ };
+
+ /**
+ * The task that all the indexing threads have to execute
+ */
+ private final Runnable indexingTask = new Runnable()
+ {
+ public void run()
+ {
+ while (exception.get() == null)
+ {
+ Callable<Void> task;
+ while (exception.get() == null && (task = tasks.poll()) != null)
+ {
+ try
+ {
+ task.call();
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ catch (Exception e)
+ {
+ exception.set(e);
+ }
+ finally
+ {
+ synchronized (runningThreads)
+ {
+ runningThreads.decrementAndGet();
+ runningThreads.notifyAll();
+ }
+ }
+ }
+ synchronized (runningThreads)
+ {
+ if (exception.get() == null && (runningThreads.get() > 0))
+ {
+ try
+ {
+ runningThreads.wait();
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ endSignal.countDown();
+ }
+ };
+
+ /**
+ * Default constructor
+ * @param node
+ * the current NodeState.
+ * @param stateMgr
+ * the shared item state manager.
+ */
+ public MultithreadedIndexing(final NodeData node, final ItemDataConsumer stateMgr)
+ {
+ tasks.offer(new Callable<Void>()
+ {
+ public Void call() throws Exception
+ {
+ createIndex(tasks, node, stateMgr, count);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Launches the indexing
+ * @param asynchronous indicates whether or not the current thread needs to wait until the
+ * end of the indexing
+ * @return the total amount of nodes that have been indexed. <code>-1</code> in case of an
+ * asynchronous indexing
+ * @throws IOException
+ * if an error occurs while writing to the index.
+ * @throws ItemStateException
+ * if an node state cannot be found.
+ * @throws RepositoryException
+ * if any other error occurs
+ */
+ public long launch(boolean asynchronous) throws IOException, RepositoryException
+ {
+ startThreads();
+ if (!asynchronous)
+ {
+ try
+ {
+ endSignal.await();
+ if (exception.get() != null)
+ {
+ if (exception.get() instanceof IOException)
+ {
+ throw (IOException)exception.get();
+ }
+ else if (exception.get() instanceof RepositoryException)
+ {
+ throw (RepositoryException)exception.get();
+ }
+ else
+ {
+ throw new RuntimeException("Error while indexing", exception.get());
+ }
+ }
+ return count.get();
+ }
+ catch (InterruptedException e)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ return -1L;
+ }
+
+ /**
+ * Starts all the indexing threads
+ */
+ private void startThreads()
+ {
+ for (int i = 0; i < nThreads; i++)
+ {
+ (new Thread(indexingTask, "Indexing Thread #" + (i + 1))).start();
+ }
+ }
+ }
}
13 years, 3 months