blob: 70c31e4e0086139e994b9ddd53924c54c1fc2ac0 [file] [log] [blame]
/*******************************************************************************
* 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
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.impl;
import java.io.File;
import java.io.IOException;
import org.eclipse.cdt.internal.core.index.IDocument;
/**
* This index stores the document names in an <code>ObjectVector</code>, and the words in
* an <code>HashtableOfObjects</code>.
*/
public class InMemoryIndex {
/**
* hashtable of IncludeEntrys = includeFiles+numbers of the files they appear in.
*/
protected IncludeEntryHashedArray includes;
/**
* hashtable of WordEntrys = words+numbers of the files they appear in.
*/
protected WordEntryHashedArray words;
/**
* List of IndexedFiles = file name + a unique number.
*/
protected IndexedFileHashedArray files;
/**
* Size of the index.
*/
protected long footprint;
private IncludeEntry[] sortedIncludeEntries;
private WordEntry[] sortedWordEntries;
private IndexedFile[] sortedFiles;
private int lastId;
public InMemoryIndex() {
includes= new IncludeEntryHashedArray(501);
init();
}
public IndexedFile addDocument(IDocument document) {
IndexedFile indexedFile= this.files.add(document);
this.footprint += indexedFile.footprint() + 4;
this.sortedFiles = null;
return indexedFile;
}
public void addIncludeRef(IndexedFile indexedFile, char[] include) {
addIncludeRef(include, indexedFile.getFileNumber());
}
public void addIncludeRef(IndexedFile indexedFile, String include) {
addIncludeRef(include.toCharArray(), indexedFile.getFileNumber());
}
/**
* Adds the references of the include to the tree (reference = number of the file the include belongs to).
*/
protected void addIncludeRef(char[] include, int[] references) {
int size= references.length;
int i= 0;
while (i < size) {
if (references[i] != 0)
addIncludeRef(include, references[i]);
i++;
}
}
/**
* Looks if the include already exists to the tree and adds the fileNum to this include.
* If the include does not exist, it adds it to the tree.
*/
protected void addIncludeRef(char[] include, int fileNum) {
IncludeEntry entry= (IncludeEntry) this.includes.get(include);
if (entry == null) {
entry= new IncludeEntry(include, ++lastId);
entry.addRef(fileNum);
this.includes.add(entry);
this.sortedIncludeEntries= null;
//TODO: BOG FIGURE OUT FOOTPRINT
//this.footprint += entry.getClass(); //footprint();
//
} else {
this.footprint += entry.addRef(fileNum);
}
}
/**
* Adds the references of the word to the index (reference = number of the file the word belongs to).
*/
protected void addRef(char[] word, int[] references) {
int size= references.length;
int i= 0;
while (i < size) {
if (references[i] != 0)
addRef(word, references[i]);
i++;
}
}
/**
* 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) {
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);
}
}
public void addRef(IndexedFile indexedFile, char[] word) {
addRef(word, indexedFile.getFileNumber());
}
public void addRef(IndexedFile indexedFile, String word) {
addRef(word.toCharArray(), indexedFile.getFileNumber());
}
public void addRelatives(IndexedFile indexedFile, String inclusion, String parent) {
addRelatives(indexedFile.getFileNumber(),inclusion.toCharArray(),(parent != null ) ? parent.toCharArray() : null);
}
protected void addRelatives(int fileNumber, char[] inclusion, char[] parent) {
IncludeEntry childEntry=null;
IncludeEntry parentEntry=null;
if (inclusion != null)
childEntry= (IncludeEntry) this.includes.get(inclusion);
if (parent != null)
parentEntry= (IncludeEntry) this.includes.get(parent);
childEntry.addParent(fileNumber,(parentEntry!=null) ? parentEntry.getID() : -1);
if (parent!=null)
parentEntry.addChild(fileNumber,(childEntry!=null) ? childEntry.getID() : -1);
}
/**
* Returns the footprint of the index.
*/
public long getFootprint() {
return this.footprint;
}
/**
* Returns the indexed files contained in the hashtable of includes.
*/
public IndexedFile[] getIndexedFiles(){
return this.files.asArray();
}
/**
* 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);
}
/**
* Returns the include entries contained in the hashtable of includes.
*/
public IncludeEntry[] getIncludeEntries() {
return this.includes.asArray();
}
/**
* Returns the include entry corresponding to the given include.
*/
protected IncludeEntry getIncludeEntry(char[] include) {
return (IncludeEntry) includes.get(include);
}
/**
* @see IIndex#getNumDocuments()
*/
public int getNumFiles() {
return files.size();
}
/**
* @see IIndex#getNumWords()
*/
public int getNumWords() {
return words.elementSize;
}
public int getNumIncludes() {
return includes.elementSize;
}
/**
* Returns the words contained in the hashtable of words, sorted by alphabetical order.
*/
protected IndexedFile[] getSortedFiles() {
if (this.sortedFiles == null) {
IndexedFile[] indexedFiles= files.asArray();
Util.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.asArray();
Util.sort(words);
this.sortedWordEntries= words;
}
return this.sortedWordEntries;
}
/**
* Returns the include entries contained in the hashtable of includeas, sorted by alphabetical order.
*/
protected IncludeEntry[] getSortedIncludeEntries() {
if (this.sortedIncludeEntries == null) {
IncludeEntry[] includes= this.includes.asArray();
Util.sort(includes);
this.sortedIncludeEntries= includes;
}
return this.sortedIncludeEntries;
}
/**
* Returns the word entry corresponding to the given word.
*/
protected WordEntry getWordEntry(char[] word) {
return (WordEntry) words.get(word);
}
/**
* Initialises the fields of the index
*/
public void init() {
includes= new IncludeEntryHashedArray(501);
words= new WordEntryHashedArray(501);
files= new IndexedFileHashedArray(101);
footprint= 0;
lastId=0;
sortedWordEntries= null;
sortedFiles= null;
sortedIncludeEntries=null;
}
/**
* Saves the index in the given file.
* Structure of the saved Index :
* - IndexedFiles in sorted order.
* + example:
* "c:/com/a.cpp 1"
* "c:/com/b.cpp 2"
* - References with the words in sorted order
* + example:
* "classDecl/a 1"
* "classDecl/b 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/a.cpp 1"
* "c:/com/b.cpp 2"
* - References with the words in sorted order
* + example:
* "classDecl/a 1"
* "classDecl/b 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();
}
}
}