diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/EntityPropertyTypeDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/EntityPropertyTypeDAO.java index afaf16b741608a2446b6be8ae505fa23e2bda137..ec60ba102b137e5fe587ff9a0bddf0f103eb98c0 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/EntityPropertyTypeDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/EntityPropertyTypeDAO.java @@ -36,8 +36,8 @@ import org.springframework.orm.hibernate3.HibernateTemplate; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityPropertyTypeDAO; -import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.EntitiesToUpdate; import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IFullTextIndexUpdateScheduler; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IndexUpdateOperation; import ch.systemsx.cisd.openbis.generic.shared.dto.ColumnNames; import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyPE; @@ -445,7 +445,7 @@ final class EntityPropertyTypeDAO extends AbstractDAO implements IEntityProperty private void scheduleFullTextIndexUpdate(List<Long> entityIds) { - fullTextIndexUpdateScheduler.scheduleUpdate(new EntitiesToUpdate( + fullTextIndexUpdateScheduler.scheduleUpdate(IndexUpdateOperation.reindex( getIndexedEntityClass(entityKind), entityIds)); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/IndexCreationUtil.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/IndexCreationUtil.java index 380a6e84c299ad2d4be1ec5055490ecfc2a63a65..e8b0b782bf046a1d608d95064c5dbb615a752a6a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/IndexCreationUtil.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/IndexCreationUtil.java @@ -35,11 +35,11 @@ import ch.systemsx.cisd.common.logging.LogInitializer; import ch.systemsx.cisd.common.process.ProcessExecutionHelper; import ch.systemsx.cisd.common.utilities.Template; import ch.systemsx.cisd.dbmigration.postgresql.DumpPreparator; -import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.EntitiesToUpdate; import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.FullTextIndexerRunnable; import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.HibernateSearchContext; import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IFullTextIndexUpdater; import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IndexMode; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search.IndexUpdateOperation; /** * Utility methods around database indexing with <i>Hibernate</i>. @@ -110,7 +110,7 @@ public final class IndexCreationUtil { } - public void scheduleUpdate(EntitiesToUpdate entities) + public void scheduleUpdate(IndexUpdateOperation entities) { } }; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/DefaultFullTextIndexer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/DefaultFullTextIndexer.java index 7364db575789c7c2ab2e0fbbbb6c219b4841d56f..ab0b9ed4389f1b0385f187a27379b9e0214bc697 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/DefaultFullTextIndexer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/DefaultFullTextIndexer.java @@ -95,7 +95,10 @@ final class DefaultFullTextIndexer implements IFullTextIndexer final long maxId = ids.get(nextIndex); final List<T> results = listEntitiesWithRestrictedId(fullTextSession, clazz, minId, maxId); - index = indexEntities(fullTextSession, results, clazz, index); + indexEntities(fullTextSession, results, clazz); + index = nextIndex; + operationLog.info(String.format("%d %ss have been indexed...", index, clazz + .getSimpleName())); } fullTextSession.getSearchFactory().optimize(clazz); operationLog.info(String.format("'%s' index complete. %d entities have been indexed.", @@ -119,7 +122,10 @@ final class DefaultFullTextIndexer implements IFullTextIndexer final int nextIndex = getNextIndex(index, maxIndex); List<Long> subList = ids.subList(index, nextIndex); final List<T> results = listEntitiesWithRestrictedId(fullTextSession, clazz, subList); - index = indexEntities(fullTextSession, results, clazz, index); + indexEntities(fullTextSession, results, clazz); + index = nextIndex; + operationLog.info(String.format("%d %ss have been reindexed...", index, clazz + .getSimpleName())); } fullTextSession.getSearchFactory().optimize(clazz); transaction.commit(); @@ -127,6 +133,24 @@ final class DefaultFullTextIndexer implements IFullTextIndexer clazz.getSimpleName(), index)); } + public <T> void removeFromIndex(final Session hibernateSession, final Class<T> clazz, + final List<Long> ids) throws DataAccessException + { + operationLog.info(String.format("Removing %s %ss...", ids.size(), clazz.getSimpleName())); + final FullTextSession fullTextSession = getFullTextSession(hibernateSession); + + // removing from index doesn't require a lot of resources - don't need to use batches + final Transaction transaction = fullTextSession.beginTransaction(); + for (Long id : ids) + { + fullTextSession.purge(clazz, id); + } + fullTextSession.getSearchFactory().optimize(clazz); + transaction.commit(); + operationLog.info(String.format("'%s' index is updated. %d entities have been removed.", + clazz.getSimpleName(), ids.size())); + } + private int getNextIndex(int index, int maxIndex) { return Math.min(index + batchSize, maxIndex); @@ -140,20 +164,15 @@ final class DefaultFullTextIndexer implements IFullTextIndexer return fullTextSession; } - private static final <T> int indexEntities(final FullTextSession fullTextSession, - final List<T> entities, final Class<T> clazz, final int oldCounter) + private static final <T> void indexEntities(final FullTextSession fullTextSession, + final List<T> entities, final Class<T> clazz) { - int counter = oldCounter; for (T entity : entities) { indexEntity(fullTextSession, entity); - counter++; } - operationLog.info(String.format("%d %ss have been indexed...", counter, clazz - .getSimpleName())); fullTextSession.flushToIndexes(); fullTextSession.clear(); - return counter; } private static final <T> List<Long> getAllIds(final FullTextSession fullTextSession, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/FullTextIndexUpdater.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/FullTextIndexUpdater.java index 942088118d04b22b412821c09354833d0091696f..0459642e7ec882009e0e9e696156d602b9a2a860 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/FullTextIndexUpdater.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/FullTextIndexUpdater.java @@ -49,7 +49,7 @@ public final class FullTextIndexUpdater extends HibernateDaoSupport implements private final IFullTextIndexer fullTextIndexer; - private final IExtendedBlockingQueue<EntitiesToUpdate> updaterQueue; + private final IExtendedBlockingQueue<IndexUpdateOperation> updaterQueue; public FullTextIndexUpdater(final SessionFactory sessionFactory, final HibernateSearchContext context) @@ -62,7 +62,8 @@ public final class FullTextIndexUpdater extends HibernateDaoSupport implements File queueFile = getUpdaterQueueFile(context); operationLog.debug(String.format("Updater queue file: %s.", queueFile)); updaterQueue = - ExtendedBlockingQueueFactory.<EntitiesToUpdate> createPersistRecordBased(queueFile); + ExtendedBlockingQueueFactory + .<IndexUpdateOperation> createPersistRecordBased(queueFile); } private static File getUpdaterQueueFile(HibernateSearchContext context) @@ -89,13 +90,13 @@ public final class FullTextIndexUpdater extends HibernateDaoSupport implements } } - public void scheduleUpdate(EntitiesToUpdate entities) + public void scheduleUpdate(IndexUpdateOperation operation) { if (operationLog.isDebugEnabled()) { - operationLog.debug("Scheduling update: " + entities); + operationLog.debug("Scheduling update: " + operation); } - updaterQueue.add(entities); + updaterQueue.add(operation); } /** @@ -118,10 +119,10 @@ public final class FullTextIndexUpdater extends HibernateDaoSupport implements { while (true) { - final EntitiesToUpdate entities = updaterQueue.peekWait(); + final IndexUpdateOperation operation = updaterQueue.peekWait(); if (operationLog.isInfoEnabled()) { - operationLog.info("Updating " + entities); + operationLog.info("Update: " + operation); } final StopWatch stopWatch = new StopWatch(); stopWatch.start(); @@ -129,12 +130,20 @@ public final class FullTextIndexUpdater extends HibernateDaoSupport implements try { session = getSession(); - fullTextIndexer.doFullTextIndexUpdate(getSession(), entities.getClazz(), - entities.getIds()); + switch (operation.getOperationKind()) + { + case REINDEX: + fullTextIndexer.doFullTextIndexUpdate(getSession(), operation + .getClazz(), operation.getIds()); + break; + case REMOVE: + fullTextIndexer.removeFromIndex(getSession(), operation.getClazz(), + operation.getIds()); + } stopWatch.stop(); } catch (RuntimeException e) { - notificationLog.error("Error updating " + entities + ".", e); + notificationLog.error("Error: " + operation + ".", e); } finally { if (session != null) @@ -144,8 +153,9 @@ public final class FullTextIndexUpdater extends HibernateDaoSupport implements } if (operationLog.isInfoEnabled()) { - operationLog.info("Updating " + entities.getIds().size() + " " - + entities.getClazz().getSimpleName() + "s took " + stopWatch); + operationLog.info(operation.getOperationKind() + " of " + + operation.getIds().size() + " " + + operation.getClazz().getSimpleName() + "s took " + stopWatch); } updaterQueue.take(); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/FullTextIndexerRunnable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/FullTextIndexerRunnable.java index fde10920c49f6b460f12f43a3069c90a569d4584..ccbe01e8b208771dc11e6662af4a8934a654213b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/FullTextIndexerRunnable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/FullTextIndexerRunnable.java @@ -86,6 +86,12 @@ public final class FullTextIndexerRunnable extends HibernateDaoSupport implement } final Set<Class<?>> indexedEntities = indexedEntityFinder.getIndexedEntities(); + // Use code below for debugging if not all entities need to be indexed. + // + // final Set<Class<?>> indexedEntities = new HashSet<Class<?>>(); + // indexedEntities.add(ExternalDataPE.class); + // indexedEntities.add(ExperimentPE.class); + if (indexedEntities.size() == 0) { operationLog.info(String.format("No entity annotated with '%s' has been found.", diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IFullTextIndexUpdateScheduler.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IFullTextIndexUpdateScheduler.java index 6bdb6b2583e180458ab0136036f0f6db570f6113..81ca1bb53ae82b89d2740b0979acb58785e3e1d4 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IFullTextIndexUpdateScheduler.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IFullTextIndexUpdateScheduler.java @@ -26,7 +26,7 @@ package ch.systemsx.cisd.openbis.generic.server.dataaccess.db.search; public interface IFullTextIndexUpdateScheduler { /** - * Schedules update of index for specified entities. + * Schedules specified operation. */ - void scheduleUpdate(EntitiesToUpdate entities); + void scheduleUpdate(IndexUpdateOperation operation); } \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IFullTextIndexer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IFullTextIndexer.java index 6758664ce985bdecafd270f886f243fec957ce94..a0e484f72aac02e60387b8d61c87f3f3bbc6fd92 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IFullTextIndexer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IFullTextIndexer.java @@ -43,4 +43,11 @@ public interface IFullTextIndexer */ public <T> void doFullTextIndexUpdate(final Session hibernateSession, final Class<T> clazz, final List<Long> ids) throws DataAccessException; + + /** + * Removes entities of given <var>clazz</var> with given <var>ids</var> from the + * <i>full-text</i> index using given <i>Hibernate</i> session. + */ + public <T> void removeFromIndex(final Session hibernateSession, final Class<T> clazz, + final List<Long> ids) throws DataAccessException; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/EntitiesToUpdate.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IndexUpdateOperation.java similarity index 52% rename from openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/EntitiesToUpdate.java rename to openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IndexUpdateOperation.java index dffb3451fe12190c17f1135ab24743b6c819baa5..d2f52663004b001aa19bf15ac0bc9bc868bd2324 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/EntitiesToUpdate.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/search/IndexUpdateOperation.java @@ -22,20 +22,45 @@ import java.util.List; import ch.systemsx.cisd.common.collections.CollectionUtils; /** + * Encapsulates operation kind and data for an update operation to be performed on an index. + * * @author Piotr Buczek */ -public class EntitiesToUpdate implements Serializable +public class IndexUpdateOperation implements Serializable { + public enum IndexUpdateOperationKind + { + /** update indexed entity */ + REINDEX, + + /** remove from index */ + REMOVE + } + private static final long serialVersionUID = 1L; private final Class<?> clazz; private final List<Long> ids; - public EntitiesToUpdate(Class<?> clazz, List<Long> ids) + private final IndexUpdateOperationKind operationKind; + + public static IndexUpdateOperation remove(Class<?> clazz, List<Long> ids) + { + return new IndexUpdateOperation(IndexUpdateOperationKind.REMOVE, clazz, ids); + } + + public static IndexUpdateOperation reindex(Class<?> clazz, List<Long> ids) + { + return new IndexUpdateOperation(IndexUpdateOperationKind.REINDEX, clazz, ids); + } + + private IndexUpdateOperation(IndexUpdateOperationKind operationKind, Class<?> clazz, + List<Long> ids) { this.clazz = clazz; this.ids = ids; + this.operationKind = operationKind; } public Class<?> getClazz() @@ -48,10 +73,15 @@ public class EntitiesToUpdate implements Serializable return ids; } + public IndexUpdateOperationKind getOperationKind() + { + return operationKind; + } + @Override public String toString() { - return clazz.getName() + ": " + CollectionUtils.abbreviate(ids, 10); + return operationKind + " " + clazz.getName() + ": " + CollectionUtils.abbreviate(ids, 10); } }