/******************************************************************************* * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * MetaMatrix, Inc - repackaging and updates for use as a metadata store *******************************************************************************/ package org.teiid.internal.core.index; import java.io.IOException; import org.teiid.core.index.IEntryResult; import org.teiid.core.index.IIndex; import org.teiid.core.index.IQueryResult; import org.teiid.metadata.VDBResource; /** * An Index is used to create an index on the disk, and to make queries. It uses a set of * indexers and a mergeFactory. The index fills an inMemoryIndex up * to it reaches a certain size, and then merges it with a main index on the disk. * <br> <br> * The changes are only taken into account by the queries after a merge. */ public class Index implements IIndex { /** * Maximum size of the index in memory. */ public static final int MAX_FOOTPRINT= 10000000; private VDBResource indexFile; /* * Caching the index input object so we can keep it open for multiple pass querying rather than * opening/closing and wasting CPU for file IO */ private BlocksIndexInput cachedInput; protected boolean doCache = false; private String resourceFileName; /** * String representation of this index. */ public String toString; public Index(VDBResource f) throws IOException { indexFile = f; initialize(); } /** * @see IIndex#getNumDocuments */ public int getNumDocuments() throws IOException { BlocksIndexInput input = getBlocksIndexInput(); try { input.open(); return input.getNumFiles(); } finally { if( !doCache ) { input.close(); } } } /** * @see IIndex#getNumWords */ public int getNumWords() throws IOException { BlocksIndexInput input = getBlocksIndexInput(); try { input.open(); return input.getNumWords(); } finally { if( !doCache ) { input.close(); } } } /** * Initialises the indexGenerator. */ public void initialize() throws IOException { // check whether existing index file can be read BlocksIndexInput mainIndexInput= getBlocksIndexInput(); try { mainIndexInput.open(); } catch(IOException e) { BlocksIndexInput input = mainIndexInput; try { input.setOpen(true); input.close(); } finally { input.setOpen(false); } //System.out.println(" Index.initialize(): Deleting Index file = " + indexFile.getName()); mainIndexInput = null; throw e; } if( !doCache ) { mainIndexInput.close(); } } /** * @see IIndex#query */ public IQueryResult[] query(String word) throws IOException { BlocksIndexInput input= getBlocksIndexInput(); try { return input.query(word); } finally { if( !doCache ) { input.close(); } } } public IEntryResult[] queryEntries(char[] prefix) throws IOException { BlocksIndexInput input= getBlocksIndexInput(); try { return input.queryEntriesPrefixedBy(prefix); } finally { if( !doCache ) { input.close(); } } } /** * @see IIndex#queryInDocumentNames */ public IQueryResult[] queryInDocumentNames(String word) throws IOException { BlocksIndexInput input= getBlocksIndexInput(); try { return input.queryInDocumentNames(word); } finally { if( !doCache ) { input.close(); } } } /** * @see IIndex#queryPrefix */ public IQueryResult[] queryPrefix(char[] prefix) throws IOException { BlocksIndexInput input= getBlocksIndexInput(); try { return input.queryFilesReferringToPrefix(prefix); } finally { if( !doCache ) { input.close(); } } } /** * Overloaded the method in Index to allow a user to specify if the * query should be case sensitive. */ public IEntryResult[] queryEntriesMatching(char[] prefix, boolean isCaseSensitive) throws IOException { BlocksIndexInput input= getBlocksIndexInput(); try { return input.queryEntriesMatching(prefix,isCaseSensitive); } finally { if( !doCache ) { input.close(); } } } /** * Overloaded the method in Index to allow a user to specify if the * query should be case sensitive. */ public IEntryResult[] queryEntries(char[] prefix, boolean isCaseSensitive) throws IOException { BlocksIndexInput input = getBlocksIndexInput(); try { return input.queryEntriesPrefixedBy(prefix,isCaseSensitive); } finally { if( !doCache ) { input.close(); } } } protected BlocksIndexInput getBlocksIndexInput() { if( doCache ) { if( getCachedInput() == null ) { boolean wasLoaded = false; try { if( getCachedInput() == null ) { setCachedInput( new BlocksIndexInput(indexFile) ); getCachedInput().open(); wasLoaded = true; } } catch ( IOException theException ) { } finally { if( wasLoaded && getCachedInput() != null ) { return getCachedInput(); } setCachedInput(null); } } else { return getCachedInput(); } } return new BlocksIndexInput(indexFile); } public void close() { if( getCachedInput() != null ) { try { getCachedInput().close(); } catch (IOException theException) { } finally { setCachedInput(null); } } } public String toString() { String str = this.toString; if (str == null) str = super.toString(); str += "(length: "+ indexFile.getSize() +")"; //$NON-NLS-1$ //$NON-NLS-2$ return str; } public void setDoCache(boolean theDoCache) { this.doCache = theDoCache; } public BlocksIndexInput getCachedInput() { return this.cachedInput; } public void setCachedInput(BlocksIndexInput theCachedInput) { this.cachedInput = theCachedInput; } public String getResourceFileName() { return this.resourceFileName; } }