Fix for ALF-786: WCM Cluster / Lucene: Searching in staging returns duplicate entries (when concurrently submtting)

- fixed duplication arising from indexing 0-1 and 0-2 against the index for near simultaneous snapshots 
- tracking has not been modified nor has index rebuild - the latest index info from the AVM index is definitive and complete - we do not have to do additional work as we do for DM

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19898 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Andrew Hind
2010-04-19 14:11:47 +00:00
parent 16c4b49359
commit 0d3f558e11
19 changed files with 1366 additions and 239 deletions

View File

@@ -36,7 +36,7 @@ import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
* Method interceptor for atomic indexing of AVM entries The properties can defined how stores are indexed based on type
* Method interceptor for atomic indexing of AVM entries The properties can defined how stores are indexed based on type
* (as set by Alfresco the Web site management UI) or based on the name of the store. Creates and deletes are indexed
* synchronously. Updates may be asynchronous, synchronous or ignored by the index.
*
@@ -100,14 +100,14 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
{
String store = (String) mi.getArguments()[0];
Object returnValue = mi.proceed();
if (getIndexMode(store) != IndexMode.UNINDEXED)
if (getIndexMode(store) != IndexMode.UNINDEXED)
{
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
avmIndexer.deleteIndex(store, IndexMode.SYNCHRONOUS);
}
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
avmIndexer.deleteIndex(store, IndexMode.SYNCHRONOUS);
}
}
return returnValue;
}
@@ -115,10 +115,10 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
{
String store = (String) mi.getArguments()[0];
Object returnValue = mi.proceed();
if (getIndexMode(store) != IndexMode.UNINDEXED)
{
createIndex(store);
}
if (getIndexMode(store) != IndexMode.UNINDEXED)
{
createIndex(store);
}
return returnValue;
}
else if (mi.getMethod().getName().equals("renameStore"))
@@ -127,24 +127,24 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
String to = (String) mi.getArguments()[1];
Object returnValue = mi.proceed();
int after = avmService.getLatestSnapshotID(to);
if (getIndexMode(from) != IndexMode.UNINDEXED)
if (getIndexMode(from) != IndexMode.UNINDEXED)
{
AVMLuceneIndexer avmIndexer = getIndexer(from);
if (avmIndexer != null)
{
avmIndexer.deleteIndex(from, IndexMode.SYNCHRONOUS);
}
AVMLuceneIndexer avmIndexer = getIndexer(from);
if (avmIndexer != null)
{
avmIndexer.deleteIndex(from, IndexMode.SYNCHRONOUS);
}
}
if (getIndexMode(to) != IndexMode.UNINDEXED)
if (getIndexMode(to) != IndexMode.UNINDEXED)
{
AVMLuceneIndexer avmIndexer = getIndexer(to);
if (avmIndexer != null)
{
avmIndexer.createIndex(to, IndexMode.SYNCHRONOUS);
avmIndexer.index(to, 0, after, getIndexMode(to));
}
AVMLuceneIndexer avmIndexer = getIndexer(to);
if (avmIndexer != null)
{
avmIndexer.createIndex(to, IndexMode.SYNCHRONOUS);
avmIndexer.index(to, 0, after, getIndexMode(to));
}
}
return returnValue;
}
@@ -213,74 +213,76 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
{
this.defaultMode = defaultMode;
}
/**
* Is snapshot triggered indexing enabled
*
* @return true if indexing is enabled for AVM
*/
public boolean isIndexingEnabled()
{
return enableIndexing;
}
/**
* Is snapshot triggered indexing enabled
*
* @return true if indexing is enabled for AVM
*/
public boolean isIndexingEnabled()
{
return enableIndexing;
}
/**
* @param store
* @param before
* @param after
*/
public void indexSnapshot(String store, int before, int after)
{
indexSnapshotImpl(store, before, after);
indexSnapshotImpl(store, before, after);
}
/**
* @param store
* @param after
*/
/**
* @param store
* @param after
*/
public void indexSnapshot(String store, int after)
{
indexSnapshotImpl(store, -1, after);
}
private void indexSnapshotImpl(String store, int before, int after)
{
if (getIndexMode(store) != IndexMode.UNINDEXED)
indexSnapshotImpl(store, -1, after);
}
private void indexSnapshotImpl(String store, int before, int after)
{
if (getIndexMode(store) != IndexMode.UNINDEXED)
{
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
int last = getLastIndexedSnapshot(avmIndexer, store);
if ((last == -1) && (! hasIndexBeenCreated(store)))
{
createIndex(store);
}
avmIndexer.index(store, (before != -1 ? before : last), after, getIndexMode(store));
}
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
int last = getLastIndexedSnapshot(avmIndexer, store);
if ((last == -1) && (! hasIndexBeenCreated(store)))
{
createIndex(store);
}
int from = before != -1 ? before : last;
avmIndexer.index(store, from, after, getIndexMode(store));
}
}
}
/**
* @param store
* @return - the last indexed snapshot
*/
public int getLastIndexedSnapshot(String store)
{
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
return getLastIndexedSnapshot(avmIndexer, store);
return getLastIndexedSnapshot(avmIndexer, store);
}
return -1;
}
private int getLastIndexedSnapshot(AVMLuceneIndexer avmIndexer, String store)
{
return avmIndexer.getLastIndexedSnapshot(store);
}
private int getLastIndexedSnapshot(AVMLuceneIndexer avmIndexer, String store)
{
return avmIndexer.getLastIndexedSnapshot(store);
}
/**
* Is the snapshot applied to the index? Is there an entry for any node that was added OR have all the nodes in the
* transaction been deleted as expected?
@@ -291,8 +293,8 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
*/
public boolean isSnapshotIndexed(String store, int id)
{
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
return avmIndexer.isSnapshotIndexed(store, id);
}
@@ -315,8 +317,8 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
case SYNCHRONOUS:
case ASYNCHRONOUS:
int last = avmService.getLatestSnapshotID(store);
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
avmIndexer.flushPending();
return avmIndexer.isSnapshotSearchable(store, last);
@@ -343,11 +345,11 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
case SYNCHRONOUS:
case ASYNCHRONOUS:
int last = avmService.getLatestSnapshotID(store);
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
avmIndexer.flushPending();
return getLastIndexedSnapshot(avmIndexer, store) == last;
return avmIndexer.isSnapshotIndexed(store, last);
}
return false;
default:
@@ -487,8 +489,8 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
public boolean hasIndexBeenCreated(String store)
{
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
avmIndexer.flushPending();
return avmIndexer.hasIndexBeenCreated(store);
@@ -498,8 +500,8 @@ public class AVMSnapShotTriggeredIndexingMethodInterceptor implements MethodInte
public void createIndex(String store)
{
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
AVMLuceneIndexer avmIndexer = getIndexer(store);
if (avmIndexer != null)
{
avmIndexer.createIndex(store, IndexMode.SYNCHRONOUS);
}

View File

@@ -18,8 +18,11 @@
*/
package org.alfresco.repo.search.impl.lucene;
import java.util.List;
import org.alfresco.repo.search.BackgroundIndexerAware;
import org.alfresco.repo.search.IndexMode;
import org.alfresco.service.cmr.avm.VersionDescriptor;
/**
* AVM specific indxer support
@@ -56,17 +59,6 @@ public interface AVMLuceneIndexer extends LuceneIndexer, BackgroundIndexerAware
*/
public void createIndex(String store, IndexMode mode);
/**
* Get the id of the last snapshot added to the index
* @param store
*
* @param mode
* - IndexMode.SYNCHRONOUS - the last searchable snapshop
* - IndexMode.ASYNCHRONOUS - the last pending snapshot to be indexed. It may or may not be searchable.
* @return - the snapshot id
*/
public int getLastIndexedSnapshot(String store);
/**
* Is the snapshot applied to the index?
*
@@ -99,4 +91,12 @@ public interface AVMLuceneIndexer extends LuceneIndexer, BackgroundIndexerAware
* @return
*/
public long getIndexedDocCount();
/**
* Get the last snapshot in the index - this does not mean that all snapshots before it have been indexed.
*
* @param store
* @return
*/
public int getLastIndexedSnapshot(String store);
}

View File

@@ -59,6 +59,7 @@ import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.avm.AVMException;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMService;
import org.alfresco.service.cmr.avm.VersionDescriptor;
import org.alfresco.service.cmr.avmsync.AVMDifference;
import org.alfresco.service.cmr.avmsync.AVMSyncException;
import org.alfresco.service.cmr.avmsync.AVMSyncService;
@@ -129,7 +130,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
private int startVersion = -1;
private int endVersion = -1;
private long indexedDocCount = 0;
/**
@@ -281,7 +282,12 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
}
else
{
index(difference.getDestinationPath());
if (s_logger.isDebugEnabled())
{
s_logger.debug("new: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
}
// AR-786
reindex(difference.getDestinationPath(), dstDesc.isDirectory());
if (dstDesc.isDirectory())
{
indexDirectory(dstDesc);
@@ -289,13 +295,6 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
reindexAllAncestors(difference.getDestinationPath());
}
}
// New Delete
else if (!srcDesc.isDeleted() && ((dstDesc == null) || dstDesc.isDeleted()))
{
delete(difference.getSourcePath());
delete(difference.getDestinationPath());
reindexAllAncestors(difference.getDestinationPath());
}
// Existing delete
else if (srcDesc.isDeleted())
{
@@ -311,7 +310,12 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
{
// We are back from the dead ...the node used to be deleted
// Treat as new
index(difference.getDestinationPath());
// AR-786
if (s_logger.isDebugEnabled())
{
s_logger.debug("back: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
}
reindex(difference.getDestinationPath(), dstDesc.isDirectory());
if (dstDesc.isDirectory())
{
indexDirectory(dstDesc);
@@ -319,18 +323,49 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
reindexAllAncestors(difference.getDestinationPath());
}
}
// Anything else then we reindex
// Anything else then we have a delete or reindex
else
{
if (!difference.getSourcePath().equals(difference.getDestinationPath()))
// Unknown end state ...
if(dstDesc == null)
{
// we do not know what has happened - whatever it is does not apply to this snapshot
if (s_logger.isDebugEnabled())
{
s_logger.debug("unknown: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
}
}
// Delete
else if (dstDesc.isDeleted())
{
if (s_logger.isDebugEnabled())
{
s_logger.debug("delete: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
}
delete(difference.getSourcePath());
reindexAllAncestors(difference.getSourcePath());
delete(difference.getDestinationPath());
reindexAllAncestors(difference.getDestinationPath());
}
// move
else if (!difference.getSourcePath().equals(difference.getDestinationPath()))
{
if (s_logger.isDebugEnabled())
{
s_logger.debug("move: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
}
reindex(difference.getSourcePath(), srcDesc.isDirectory());
reindex(difference.getDestinationPath(), dstDesc.isDirectory());
reindexAllAncestors(difference.getSourcePath());
reindexAllAncestors(difference.getDestinationPath());
}
// update
else
{
if (s_logger.isDebugEnabled())
{
s_logger.debug("update: ("+srcVersion+", "+dstVersion+") "+difference.getDestinationPath());
}
// If it is a directory, it is at the same path,
// so no cascade update is required for the bridge table data.
reindex(difference.getDestinationPath(), false);
@@ -382,10 +417,12 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
private void indexDirectory(AVMNodeDescriptor dir)
{
Map<String, AVMNodeDescriptor> children = avmService.getDirectoryListing(dir);
Map<String, AVMNodeDescriptor> children = avmService.getDirectoryListing(dir, false);
for (AVMNodeDescriptor child : children.values())
{
index(child.getPath());
// AR-786
reindex(child.getPath(), child.isDirectory());
reindexAllAncestors(child.getPath());
if (child.isDirectory())
{
indexDirectory(child);
@@ -542,7 +579,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
}
else
// not a root node
// not a root node
{
xdoc.add(new Field("QNAME", qNameBuffer.toString(), Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.NO));
@@ -755,7 +792,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
if (isContent)
{
// Content is always tokenised
ContentData contentData = DefaultTypeConverter.INSTANCE.convert(ContentData.class, serializableValue);
if (!index || contentData.getMimetype() == null)
{
@@ -878,7 +915,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
}
}
else
// URL not present (null reader) or no content at the URL (file missing)
// URL not present (null reader) or no content at the URL (file missing)
{
// log it
if (s_logger.isDebugEnabled())
@@ -898,20 +935,20 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
if (index)
{
switch (tokenise) {
case TRUE:
case BOTH:
default:
fieldIndex = Field.Index.TOKENIZED;
break;
case FALSE:
fieldIndex = Field.Index.UN_TOKENIZED;
break;
switch (tokenise) {
case TRUE:
case BOTH:
default:
fieldIndex = Field.Index.TOKENIZED;
break;
case FALSE:
fieldIndex = Field.Index.UN_TOKENIZED;
break;
}
} else {
fieldIndex = Field.Index.NO;
}
}
} else {
fieldIndex = Field.Index.NO;
}
if ((fieldIndex != Field.Index.NO) || (fieldStore != Field.Store.NO))
{
@@ -956,7 +993,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
{
doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO));
}
doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO));
}
@@ -1027,7 +1064,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
{
locale = I18NUtil.getLocale();
}
StringBuilder builder;
MLAnalysisMode analysisMode;
VerbatimAnalyser vba;
@@ -1063,7 +1100,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
{
doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO));
}
doc.add(new Field(attributeName, t.termText(), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO));
}
}
@@ -1132,7 +1169,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
break;
case BOTH:
doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO));
df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true);
try
{
@@ -1161,15 +1198,15 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
@Override
protected void doPrepare() throws IOException
{
AuthenticationUtil.runAs(new RunAsWork<String>()
{
AuthenticationUtil.runAs(new RunAsWork<String>()
{
public String doWork() throws Exception
{
saveDelta();
flushPending();
return null;
saveDelta();
flushPending();
return null;
}
}, AuthenticationUtil.getSystemUserName());
}, AuthenticationUtil.getSystemUserName());
}
@Override
@@ -1542,6 +1579,301 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
this.fullTextSearchIndexer = fullTextSearchIndexer;
}
public boolean isSnapshotIndexed(String store, int id)
{
if (id == 0)
{
return hasIndexBeenCreated(store);
}
else
{
return isSynchronousSnapshotPresent(store, id) || isSynchronousSnapshotPresent(store, id);
}
}
private boolean isSynchronousSnapshotPresent(String store, int id)
{
return isSynchronousSnapshotPresent(store, IndexChannel.MAIN, id) || isSynchronousSnapshotPresent(store, IndexChannel.DELTA, id) ;
}
private boolean isAsynchronousSnapshotPresent(String store, int id)
{
return isAsynchronousSnapshotPresent(store, IndexChannel.MAIN, id) || isAsynchronousSnapshotPresent(store, IndexChannel.DELTA, id) ;
}
public boolean isSnapshotSearchable(String store, int id)
{
if (id == 0)
{
return hasIndexBeenCreated(store);
}
else
{
return isSynchronousSnapshotPresent(store, id);
}
}
private boolean isSynchronousSnapshotPresent(String store, IndexChannel channel, int snapshot)
{
String prefix = SNAP_SHOT_ID + ":" + store + ":";
IndexReader reader = null;
try
{
if (channel == IndexChannel.DELTA)
{
flushPending();
reader = getDeltaReader();
}
else
{
reader = getReader();
}
TermEnum terms = null;
try
{
terms = reader.terms(new Term("ID", prefix));
if (terms.term() != null)
{
do
{
Term term = terms.term();
if (term.text().startsWith(prefix))
{
TermDocs docs = null;
try
{
docs = reader.termDocs(term);
if (docs.next())
{
String[] split = term.text().split(":");
int test = Integer.parseInt(split[3]);
if (test == snapshot)
{
return true;
}
}
}
finally
{
if (docs != null)
{
docs.close();
}
}
}
else
{
break;
}
}
while (terms.next());
}
}
finally
{
if (terms != null)
{
terms.close();
}
}
return false;
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("IO error", e);
}
finally
{
try
{
if (reader != null)
{
if (channel == IndexChannel.DELTA)
{
closeDeltaReader();
}
else
{
reader.close();
}
}
}
catch (IOException e)
{
s_logger.warn("Failed to close main reader", e);
}
}
}
private boolean isAsynchronousSnapshotPresent(String store, IndexChannel channel, int snapshot)
{
String prefix = "\u0000BG:STORE:" + store + ":";
IndexReader reader = null;
try
{
if (channel == IndexChannel.DELTA)
{
flushPending();
reader = getDeltaReader();
}
else
{
reader = getReader();
}
TermEnum terms = null;
try
{
terms = reader.terms(new Term("ID", prefix));
if (terms.term() != null)
{
do
{
Term term = terms.term();
if (term.text().startsWith(prefix))
{
TermDocs docs = null;
try
{
docs = reader.termDocs(term);
if (docs.next())
{
String[] split = term.text().split(":");
int test = Integer.parseInt(split[4]);
if (test == snapshot)
{
return true;
}
}
}
finally
{
if (docs != null)
{
docs.close();
}
}
}
else
{
break;
}
}
while (terms.next());
}
}
finally
{
if (terms != null)
{
terms.close();
}
}
return false;
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("IO error", e);
}
finally
{
try
{
if (reader != null)
{
if (channel == IndexChannel.DELTA)
{
closeDeltaReader();
}
else
{
reader.close();
}
}
}
catch (IOException e)
{
s_logger.warn("Failed to close main reader", e);
}
}
}
public boolean hasIndexBeenCreated(String store)
{
return hasIndexBeenCreatedimpl(store, IndexChannel.MAIN) || hasIndexBeenCreatedimpl(store, IndexChannel.DELTA);
}
public boolean hasIndexBeenCreatedimpl(String store, IndexChannel channel)
{
IndexReader reader = null;
try
{
if (channel == IndexChannel.DELTA)
{
flushPending();
reader = getDeltaReader();
}
else
{
reader = getReader();
}
TermDocs termDocs = null;
try
{
termDocs = reader.termDocs(new Term("ISROOT", "T"));
return termDocs.next();
}
finally
{
if (termDocs != null)
{
termDocs.close();
}
}
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("IO error", e);
}
finally
{
try
{
if (reader != null)
{
if (channel == IndexChannel.DELTA)
{
closeDeltaReader();
}
else
{
reader.close();
}
}
}
catch (IOException e)
{
s_logger.warn("Failed to close main reader", e);
}
}
}
public synchronized long getIndexedDocCount()
{
return indexedDocCount;
}
private synchronized void incrementDocCount()
{
indexedDocCount++;
}
public int getLastIndexedSnapshot(String store)
{
int last = getLastAsynchronousSnapshot(store);
@@ -1556,31 +1888,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
}
return hasIndexBeenCreated(store) ? 0 : -1;
}
public boolean isSnapshotIndexed(String store, int id)
{
if (id == 0)
{
return hasIndexBeenCreated(store);
}
else
{
return (id <= getLastAsynchronousSnapshot(store)) || (id <= getLastSynchronousSnapshot(store));
}
}
public boolean isSnapshotSearchable(String store, int id)
{
if (id == 0)
{
return hasIndexBeenCreated(store);
}
else
{
return (id <= getLastSynchronousSnapshot(store));
}
}
private int getLastSynchronousSnapshot(String store)
{
int answer = getLastSynchronousSnapshot(store, IndexChannel.DELTA);
@@ -1798,76 +2106,4 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl<String> impl
}
}
}
public boolean hasIndexBeenCreated(String store)
{
return hasIndexBeenCreatedimpl(store, IndexChannel.MAIN) || hasIndexBeenCreatedimpl(store, IndexChannel.DELTA);
}
public boolean hasIndexBeenCreatedimpl(String store, IndexChannel channel)
{
IndexReader reader = null;
try
{
if (channel == IndexChannel.DELTA)
{
flushPending();
reader = getDeltaReader();
}
else
{
reader = getReader();
}
TermDocs termDocs = null;
try
{
termDocs = reader.termDocs(new Term("ISROOT", "T"));
return termDocs.next();
}
finally
{
if (termDocs != null)
{
termDocs.close();
}
}
}
catch (IOException e)
{
throw new AlfrescoRuntimeException("IO error", e);
}
finally
{
try
{
if (reader != null)
{
if (channel == IndexChannel.DELTA)
{
closeDeltaReader();
}
else
{
reader.close();
}
}
}
catch (IOException e)
{
s_logger.warn("Failed to close main reader", e);
}
}
}
public synchronized long getIndexedDocCount()
{
return indexedDocCount;
}
private synchronized void incrementDocCount()
{
indexedDocCount++;
}
}