001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.gps.device.support.parallel;
018:
019: import org.compass.core.CompassSession;
020: import org.compass.gps.CompassGpsException;
021: import org.compass.gps.device.AbstractGpsDevice;
022:
023: /**
024: * <p>A base class for gps device that can parallel the index operation.
025: *
026: * <p>When the device starts up, the {@link #doGetIndexEntities()} callback
027: * is called (should be implemented by sub classes) in order to get the
028: * {@link org.compass.gps.device.support.parallel.IndexEntity}ies. The
029: * {@link org.compass.gps.device.support.parallel.IndexEntitiesPartitioner} is
030: * then used in order to partition the index entities into several groups
031: * that can be parallel indexed. An {@link org.compass.gps.device.support.parallel.IndexEntitiesIndexer}
032: * is also obtained using the {@link #doGetIndexEntitiesIndexer()} that can
033: * index entities into the search engine and is provided by sub classes as well.
034: *
035: * <p>The {@link org.compass.gps.device.support.parallel.IndexEntitiesPartitioner}
036: * defaults to the {@link org.compass.gps.device.support.parallel.SubIndexIndexEntitiesPartitioner}
037: * that partition the index entities based on the sub index. This is the only meanigful
038: * way to partition the index entities, as it allows for the best concurrent support
039: * (locking is performed on the sub index level).
040: *
041: * <p>The {@link #index()} operation uses the {@link org.compass.gps.device.support.parallel.ParallelIndexExecutor}
042: * in order to execute the indexing process. The default implementation used is
043: * {@link org.compass.gps.device.support.parallel.ConcurrentParallelIndexExecutor}.
044: *
045: * @author kimchy
046: */
047: public abstract class AbstractParallelGpsDevice extends
048: AbstractGpsDevice {
049:
050: private ParallelIndexExecutor parallelIndexExecutor = new ConcurrentParallelIndexExecutor();
051:
052: private IndexEntitiesPartitioner indexEntitiesPartitioner = new SubIndexIndexEntitiesPartitioner();
053:
054: private IndexEntity[][] entities;
055:
056: private IndexEntitiesIndexer indexEntitiesIndexer;
057:
058: /**
059: * Starts the device. Calls {@link #doGetIndexEntities} in order to get all the
060: * indexeable entities and uses the {@link org.compass.gps.device.support.parallel.IndexEntitiesPartitioner}
061: * to partition them index groups that can be parallel indexed. Also calls
062: * {@link #doGetIndexEntitiesIndexer()} in order to obtain the index entities indexer.
063: *
064: * @throws CompassGpsException
065: */
066: public synchronized void start() throws CompassGpsException {
067: super .start();
068: entities = indexEntitiesPartitioner
069: .partition(doGetIndexEntities());
070: indexEntitiesIndexer = doGetIndexEntitiesIndexer();
071: }
072:
073: /**
074: * Index the indexable entities. Calls the {@link org.compass.gps.device.support.parallel.ParallelIndexExecutor}
075: * in order to index the different groups of indexed entities partitioned at startup.
076: *
077: * @throws CompassGpsException
078: */
079: public synchronized void index() throws CompassGpsException {
080: if (!isRunning()) {
081: throw new IllegalStateException(
082: buildMessage("must be running in order to perform the index operation"));
083: }
084: parallelIndexExecutor.performIndex(entities,
085: indexEntitiesIndexer, compassGps);
086: }
087:
088: /**
089: * Returns all the indexed entities for this device.
090: */
091: protected abstract IndexEntity[] doGetIndexEntities()
092: throws CompassGpsException;
093:
094: /**
095: * Returns an index entities indexer that knows how to index indexable entities.
096: */
097: protected abstract IndexEntitiesIndexer doGetIndexEntitiesIndexer();
098:
099: /**
100: * Overriding this method and throws an {@link IllegalStateException} as it should
101: * not be called. The {@link #index()} operation is implemented here and does not
102: * call this method.
103: */
104: protected final void doIndex(CompassSession session)
105: throws CompassGpsException {
106: throw new IllegalStateException("This should not be called");
107: }
108:
109: /**
110: * Sets the parallel index executor. Defaults to
111: * {@link org.compass.gps.device.support.parallel.ConcurrentParallelIndexExecutor}.
112: *
113: * @see #index()
114: */
115: public void setParallelIndexExecutor(
116: ParallelIndexExecutor parallelIndexExecutor) {
117: this .parallelIndexExecutor = parallelIndexExecutor;
118: }
119:
120: /**
121: * Sets the index entities partitioner. Defaults to
122: * {@link org.compass.gps.device.support.parallel.SubIndexIndexEntitiesPartitioner}.
123: *
124: * @see #start()
125: */
126: public void setIndexEntitiesPartitioner(
127: IndexEntitiesPartitioner indexEntitiesPartitioner) {
128: this.indexEntitiesPartitioner = indexEntitiesPartitioner;
129: }
130: }
|