/*******************************************************************************
* 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 Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* MetaMatrix, Inc - repackaging and updates for use as a metadata store
*******************************************************************************/
package org.teiid.designer.core.index;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* This index stores the document names in an <code>ArrayList</code>, and the words in an <code>HashtableOfObjects</code>.
*
* @since 8.0
*/
public class InMemoryIndex {
/**
* hashtable of WordEntrys = words+numbers of the files they appear in.
*/
protected List<WordEntry> words;
/**
* List of IndexedFiles = file name + a unique number.
*/
protected IndexedFileHashedArray files;
/**
* Size of the index.
*/
protected long footprint;
private WordEntry[] sortedWordEntries;
private IndexedFile[] sortedFiles;
public InMemoryIndex() {
init();
}
public IndexedFile addDocument( IDocument document ) {
IndexedFile indexedFile = this.files.add(document);
this.footprint += indexedFile.footprint() + 4;
this.sortedFiles = null;
return indexedFile;
}
/**
* Looks if the word already exists in the index and add the fileNum to this word. If the word does not exist, it adds it in
* the index.
*/
protected void addRef( char[] word,
int fileNum ) {
// Assuming that our indexes are already unique we shouldn't
// worry about whether or not one exists already in the list
// So let's change this a little and improve performance.
// WordEntry entry= (WordEntry) this.words.get(word);
// if (entry == null) {
// entry= new WordEntry(word);
// entry.addRef(fileNum);
// this.words.add(entry);
// this.sortedWordEntries= null;
// this.footprint += entry.footprint();
// } else {
// this.footprint += entry.addRef(fileNum);
// }
// return;
// NEW CODE BELOW
WordEntry entry = new WordEntry(word);
entry.addRef(fileNum);
this.words.add(entry);
this.sortedWordEntries = null;
this.footprint += entry.footprint();
}
public void addRef( IndexedFile indexedFile,
char[] word ) {
addRef(word, indexedFile.getFileNumber());
}
/**
* Returns the footprint of the index.
*/
public long getFootprint() {
return this.footprint;
}
/**
* Returns the indexed file with the given path, or null if such file does not exist.
*/
public IndexedFile getIndexedFile( String path ) {
return files.get(path);
}
/**
* @see IIndex#getNumDocuments()
*/
public int getNumFiles() {
return files.size();
}
/**
* @see IIndex#getNumWords()
*/
public int getNumWords() {
return words.size();
}
/**
* Returns the words contained in the hashtable of words, sorted by alphabetical order.
*/
protected IndexedFile[] getSortedFiles() {
if (this.sortedFiles == null) {
IndexedFile[] indexedFiles = files.asArray();
Arrays.sort(indexedFiles);
this.sortedFiles = indexedFiles;
}
return this.sortedFiles;
}
/**
* Returns the word entries contained in the hashtable of words, sorted by alphabetical order.
*/
protected WordEntry[] getSortedWordEntries() {
if (this.sortedWordEntries == null) {
WordEntry[] words = this.words.toArray(new WordEntry[this.words.size()]);
Arrays.sort(words);
this.sortedWordEntries = words;
}
return this.sortedWordEntries;
}
/**
* Initialises the fields of the index
*/
public void init() {
words = new ArrayList<WordEntry>(256);
files = new IndexedFileHashedArray(101);
footprint = 0;
sortedWordEntries = null;
sortedFiles = null;
}
/**
* Saves the index in the given file. Structure of the saved Index : - IndexedFiles in sorted order. + example:
* "c:/com/Test.java 1" "c:/com/UI.java 2" - References with the words in sorted order + example: "classDecl/Test 1"
* "classDecl/UI 2" "ref/String 1 2"
*/
public void save( File file ) throws IOException {
BlocksIndexOutput output = new BlocksIndexOutput(file);
save(output);
}
/**
* Saves the index in the given IndexOutput. Structure of the saved Index : - IndexedFiles in sorted order. + example:
* "c:/com/Test.java 1" "c:/com/UI.java 2" - References with the words in sorted order + example: "classDecl/Test 1"
* "classDecl/UI 2" "ref/String 1 2"
*/
protected void save( IndexOutput output ) throws IOException {
boolean ok = false;
try {
output.open();
IndexedFile[] indexedFiles = files.asArray();
for (int i = 0, length = indexedFiles.length; i < length; ++i)
output.addFile(indexedFiles[i]); // written out in order BUT not alphabetical
getSortedWordEntries(); // init the slot
for (int i = 0, numWords = sortedWordEntries.length; i < numWords; ++i)
output.addWord(sortedWordEntries[i]);
output.flush();
output.close();
ok = true;
} finally {
if (!ok && output != null) output.close();
}
}
}