diff --git a/core/org.eclipse.cdt.core.tests/.classpath b/core/org.eclipse.cdt.core.tests/.classpath
index cdd6d4f884e..744c6f2097b 100644
--- a/core/org.eclipse.cdt.core.tests/.classpath
+++ b/core/org.eclipse.cdt.core.tests/.classpath
@@ -6,6 +6,7 @@
+ * The first two bytes are read as if by
+ *
+ * This method blocks until all the bytes are read, the end of the
+ * stream is detected, or an exception is thrown.
+ *
+ * @param in a data input stream.
+ * @return a Unicode string.
+ * @exception EOFException if the input stream reaches the end
+ * before all the bytes.
+ * @exception IOException if an I/O error occurs.
+ * @exception UTFDataFormatException if the bytes do not represent a
+ * valid UTF-8 encoding of a Unicode string.
+ * @see java.io.DataInputStream#readUnsignedShort()
+ */
+ public final static char[] readUTF(DataInput in) throws IOException {
+ int utflen= in.readUnsignedShort();
+ char str[]= new char[utflen];
+ int count= 0;
+ int strlen= 0;
+ while (count < utflen) {
+ int c= in.readUnsignedByte();
+ int char2, char3;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ case 2 :
+ case 3 :
+ case 4 :
+ case 5 :
+ case 6 :
+ case 7 :
+ // 0xxxxxxx
+ count++;
+ str[strlen++]= (char) c;
+ break;
+ case 12 :
+ case 13 :
+ // 110x xxxx 10xx xxxx
+ count += 2;
+ if (count > utflen)
+ throw new UTFDataFormatException();
+ char2= in.readUnsignedByte();
+ if ((char2 & 0xC0) != 0x80)
+ throw new UTFDataFormatException();
+ str[strlen++]= (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
+ break;
+ case 14 :
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ count += 3;
+ if (count > utflen)
+ throw new UTFDataFormatException();
+ char2= in.readUnsignedByte();
+ char3= in.readUnsignedByte();
+ if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
+ throw new UTFDataFormatException();
+ str[strlen++]= (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
+ break;
+ default :
+ // 10xx xxxx, 1111 xxxx
+ throw new UTFDataFormatException();
+ }
+ }
+ if (strlen < utflen) {
+ System.arraycopy(str, 0, str= new char[strlen], 0, strlen);
+ }
+ return str;
+ }
+ public static void sort(char[][] list) {
+ if (list.length > 1)
+ quickSort(list, 0, list.length - 1);
+ }
+ public static void sort(int[] list) {
+ if (list.length > 1)
+ quickSort(list, 0, list.length - 1);
+ }
+ public static void sort(String[] list) {
+ if (list.length > 1)
+ quickSort(list, 0, list.length - 1);
+ }
+ public static void sort(IndexedFile[] list) {
+ if (list.length > 1)
+ quickSort(list, 0, list.length - 1);
+ }
+ public static void sort(WordEntry[] list) {
+ if (list.length > 1)
+ quickSort(list, 0, list.length - 1);
+ }
+ /**
+ * Writes a string to the given output stream using UTF-8
+ * encoding in a machine-independent manner.
+ *
+ * First, two bytes are written to the output stream as if by the
+ *
+ * For example:
+ * File
(FileDocument
),
+ * an IFile
(IFileDocument
),
+ * or other kinds of data sources (URL, ...). An IIndexer
indexes anIDocument
.
+ */
+
+public interface IDocument {
+ /**
+ * Returns the content of the document, in a byte array.
+ */
+ byte[] getByteContent() throws IOException;
+ /**
+ * Returns the content of the document, in a char array.
+ */
+ char[] getCharContent() throws IOException;
+ /**
+ * Returns the encoding for this document
+ */
+ String getEncoding();
+ /**
+ * returns the name of the document (e.g. its path for a File
, or its relative path
+ * in the workbench for an IFile
).
+ */
+ String getName();
+ /**
+ * Returns the content of the document, as a String.
+ */
+ public String getStringContent() throws IOException;
+ /**
+ * Returns the type of the document.
+ */
+ String getType();
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IEntryResult.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IEntryResult.java
new file mode 100644
index 00000000000..c68f0e75a3e
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IEntryResult.java
@@ -0,0 +1,17 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.index;
+
+public interface IEntryResult {
+ public int[] getFileReferences();
+ public char[] getWord();
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndex.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndex.java
new file mode 100644
index 00000000000..0b161277019
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndex.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.index;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * An IIndex is the interface used to generate an index file, and to make queries on
+ * this index.
+ */
+
+public interface IIndex {
+ /**
+ * Adds the given document to the index.
+ */
+ void add(IDocument document, IIndexer indexer) throws IOException;
+ /**
+ * Empties the index.
+ */
+ void empty() throws IOException;
+ /**
+ * Returns the index file on the disk.
+ */
+ File getIndexFile();
+ /**
+ * Returns the number of documents indexed.
+ */
+ int getNumDocuments() throws IOException;
+ /**
+ * Returns the number of unique words indexed.
+ */
+ int getNumWords() throws IOException;
+ /**
+ * Returns the path corresponding to a given document number
+ */
+ String getPath(int documentNumber) throws IOException;
+ /**
+ * Ansers true if has some changes to save.
+ */
+ boolean hasChanged();
+ /**
+ * Returns the paths of the documents containing the given word.
+ */
+ IQueryResult[] query(String word) throws IOException;
+ /**
+ * Returns all entries for a given word.
+ */
+ IEntryResult[] queryEntries(char[] pattern) throws IOException;
+ /**
+ * Returns the paths of the documents whose names contain the given word.
+ */
+ IQueryResult[] queryInDocumentNames(String word) throws IOException;
+ /**
+ * Returns the paths of the documents containing the given word prefix.
+ */
+ IQueryResult[] queryPrefix(char[] prefix) throws IOException;
+ /**
+ * Removes the corresponding document from the index.
+ */
+ void remove(String documentName) throws IOException;
+ /**
+ * Saves the index on the disk.
+ */
+ void save() throws IOException;
+
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndexer.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndexer.java
new file mode 100644
index 00000000000..5fb6d2ad0d9
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndexer.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.index;
+
+/**
+ * An IIndexer
indexes ONE document at each time. It adds the document names and
+ * the words references to an IIndex. Each IIndexer can index certain types of document, and should
+ * not index the other files.
+ */
+public interface IIndexer {
+ /**
+ * Returns the file types the IIndexer
handles.
+ */
+
+ String[] getFileTypes();
+ /**
+ * Indexes the given document, adding the document name and the word references
+ * to this document to the given IIndex
.The caller should use
+ * shouldIndex()
first to determine whether this indexer handles
+ * the given type of file, and only call this method if so.
+ */
+
+ void index(IDocument document, IIndexerOutput output) throws java.io.IOException;
+ /**
+ * Sets the document types the IIndexer
handles.
+ */
+
+ public void setFileTypes(String[] fileTypes);
+ /**
+ * Returns whether the IIndexer
can index the given document or not.
+ */
+
+ public boolean shouldIndex(IDocument document);
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndexerOutput.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndexerOutput.java
new file mode 100644
index 00000000000..8f861ac2647
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IIndexerOutput.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.index;
+
+/**
+ * This class represents the output from an indexer to an index
+ * for a single document.
+ */
+
+public interface IIndexerOutput {
+ public void addDocument(IDocument document);
+ public void addRef(char[] word);
+ public void addRef(String word);
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IQueryResult.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IQueryResult.java
new file mode 100644
index 00000000000..5360493799a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/IQueryResult.java
@@ -0,0 +1,15 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.index;
+
+public interface IQueryResult {
+ String getPath();
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Block.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Block.java
new file mode 100644
index 00000000000..26edf1f765a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Block.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * A block is a container that can hold information (a list of file names, a list of
+ * words, ...), be saved on the disk and loaded in memory.
+ */
+
+public abstract class Block {
+ /**
+ * Size of the block
+ */
+ protected int blockSize;
+
+ /**
+ * Field in which the information is stored
+ */
+ protected Field field;
+
+ public Block(int blockSize) {
+ this.blockSize= blockSize;
+ field= new Field(blockSize);
+ }
+ /**
+ * Empties the block.
+ */
+ public void clear() {
+ field.clear();
+ }
+ /**
+ * Flushes the block
+ */
+ public void flush() {
+ }
+ /**
+ * Loads the block with the given number in memory, reading it from a RandomAccessFile.
+ */
+ public void read(RandomAccessFile raf, int blockNum) throws IOException {
+ raf.seek(blockNum * (long) blockSize);
+ raf.readFully(field.buffer());
+ }
+ /**
+ * Writes the block in a RandomAccessFile, giving it a block number.
+ */
+ public void write(RandomAccessFile raf, int blockNum) throws IOException {
+ raf.seek(blockNum * (long) blockSize);
+ raf.write(field.buffer());
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/BlocksIndexInput.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/BlocksIndexInput.java
new file mode 100644
index 00000000000..7b79dc82a2d
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/BlocksIndexInput.java
@@ -0,0 +1,391 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+
+import org.eclipse.cdt.internal.core.search.CharOperation;
+import org.eclipse.cdt.internal.core.index.IDocument;
+import org.eclipse.cdt.internal.core.index.IEntryResult;
+import org.eclipse.cdt.internal.core.index.IQueryResult;
+import org.eclipse.cdt.internal.core.search.Util;
+import org.eclipse.cdt.internal.core.util.LRUCache;
+
+/**
+ * This input is used for reading indexes saved using a BlocksIndexOutput.
+ */
+public class BlocksIndexInput extends IndexInput {
+ public static final int CACHE_SIZE= 16; // Cache 16 blocks of 8K each, for a cache size of 128K
+ protected FileListBlock currentFileListBlock;
+ protected int currentFileListBlockNum;
+ protected int currentIndexBlockNum;
+ protected IndexBlock currentIndexBlock;
+ private RandomAccessFile raf;
+ protected File indexFile;
+ protected LRUCache blockCache;
+ protected boolean opened= false;
+ protected IndexSummary summary;
+
+ public BlocksIndexInput(File inputFile) {
+ this.indexFile= inputFile;
+ blockCache= new LRUCache(CACHE_SIZE);
+ }
+ /**
+ * @see IndexInput#clearCache()
+ */
+ public void clearCache() {
+ blockCache= new LRUCache(CACHE_SIZE);
+ }
+ /**
+ * @see IndexInput#close()
+ */
+ public void close() throws IOException {
+ if (opened) {
+ summary= null;
+ opened= false;
+ if (raf != null)
+ raf.close();
+ }
+ }
+ /**
+ * @see IndexInput#getCurrentFile()
+ */
+ public IndexedFile getCurrentFile() throws IOException {
+ if (!hasMoreFiles())
+ return null;
+ IndexedFile file= null;
+ if ((file= currentFileListBlock.getFile(filePosition)) == null) {
+ currentFileListBlockNum= summary.getBlockNumForFileNum(filePosition);
+ currentFileListBlock= getFileListBlock(currentFileListBlockNum);
+ file= currentFileListBlock.getFile(filePosition);
+ }
+ return file;
+ }
+ /**
+ * Returns the entry corresponding to the given word.
+ */
+ protected WordEntry getEntry(char[] word) throws IOException {
+ int blockNum= summary.getBlockNumForWord(word);
+ if (blockNum == -1) return null;
+ IndexBlock block= getIndexBlock(blockNum);
+ return block.findExactEntry(word);
+ }
+ /**
+ * Returns the FileListBlock with the given number.
+ */
+ protected FileListBlock getFileListBlock(int blockNum) throws IOException {
+ Integer key= new Integer(blockNum);
+ Block block= (Block) blockCache.get(key);
+ if (block != null && block instanceof FileListBlock)
+ return (FileListBlock) block;
+ FileListBlock fileListBlock= new FileListBlock(IIndexConstants.BLOCK_SIZE);
+ fileListBlock.read(raf, blockNum);
+ blockCache.put(key, fileListBlock);
+ return fileListBlock;
+ }
+ /**
+ * Returns the IndexBlock (containing words) with the given number.
+ */
+ protected IndexBlock getIndexBlock(int blockNum) throws IOException {
+ Integer key= new Integer(blockNum);
+ Block block= (Block) blockCache.get(key);
+ if (block != null && block instanceof IndexBlock)
+ return (IndexBlock) block;
+ IndexBlock indexBlock= new GammaCompressedIndexBlock(IIndexConstants.BLOCK_SIZE);
+ indexBlock.read(raf, blockNum);
+ blockCache.put(key, indexBlock);
+ return indexBlock;
+ }
+ /**
+ * @see IndexInput#getIndexedFile(int)
+ */
+ public IndexedFile getIndexedFile(int fileNum) throws IOException {
+ int blockNum= summary.getBlockNumForFileNum(fileNum);
+ if (blockNum == -1)
+ return null;
+ FileListBlock block= getFileListBlock(blockNum);
+ return block.getFile(fileNum);
+ }
+ /**
+ * @see IndexInput#getIndexedFile(IDocument)
+ */
+ public IndexedFile getIndexedFile(IDocument document) throws java.io.IOException {
+ setFirstFile();
+ String name= document.getName();
+ while (hasMoreFiles()) {
+ IndexedFile file= getCurrentFile();
+ String path= file.getPath();
+ if (path.equals(name))
+ return file;
+ moveToNextFile();
+ }
+ return null;
+ }
+ /**
+ * Returns the list of numbers of files containing the given word.
+ */
+
+ protected int[] getMatchingFileNumbers(char[] word) throws IOException {
+ int blockNum= summary.getBlockNumForWord(word);
+ if (blockNum == -1)
+ return new int[0];
+ IndexBlock block= getIndexBlock(blockNum);
+ WordEntry entry= block.findExactEntry(word);
+ return entry == null ? new int[0] : entry.getRefs();
+ }
+ /**
+ * @see IndexInput#getNumFiles()
+ */
+ public int getNumFiles() {
+ return summary.getNumFiles();
+ }
+ /**
+ * @see IndexInput#getNumWords()
+ */
+ public int getNumWords() {
+ return summary.getNumWords();
+ }
+ /**
+ * @see IndexInput#getSource()
+ */
+ public Object getSource() {
+ return indexFile;
+ }
+ /**
+ * Initialises the blocksIndexInput
+ */
+ protected void init() throws IOException {
+ clearCache();
+ setFirstFile();
+ setFirstWord();
+ }
+ /**
+ * @see IndexInput#moveToNextFile()
+ */
+ public void moveToNextFile() throws IOException {
+ filePosition++;
+ }
+ /**
+ * @see IndexInput#moveToNextWordEntry()
+ */
+ public void moveToNextWordEntry() throws IOException {
+ wordPosition++;
+ if (!hasMoreWords()) {
+ return;
+ }
+ //if end of the current block, we load the next one.
+ boolean endOfBlock= !currentIndexBlock.nextEntry(currentWordEntry);
+ if (endOfBlock) {
+ currentIndexBlock= getIndexBlock(++currentIndexBlockNum);
+ currentIndexBlock.nextEntry(currentWordEntry);
+ }
+ }
+ /**
+ * @see IndexInput#open()
+ */
+
+ public void open() throws IOException {
+ if (!opened) {
+ raf= new SafeRandomAccessFile(indexFile, "r"); //$NON-NLS-1$
+ String sig= raf.readUTF();
+ if (!sig.equals(IIndexConstants.SIGNATURE))
+ throw new IOException(Util.bind("exception.wrongFormat")); //$NON-NLS-1$
+ int summaryBlockNum= raf.readInt();
+ raf.seek(summaryBlockNum * (long) IIndexConstants.BLOCK_SIZE);
+ summary= new IndexSummary();
+ summary.read(raf);
+ init();
+ opened= true;
+ }
+ }
+ /**
+ * @see IndexInput#query(String)
+ */
+ public IQueryResult[] query(String word) throws IOException {
+ open();
+ int[] fileNums= getMatchingFileNumbers(word.toCharArray());
+ int size= fileNums.length;
+ IQueryResult[] files= new IQueryResult[size];
+ for (int i= 0; i < size; ++i) {
+ files[i]= getIndexedFile(fileNums[i]);
+ }
+ return files;
+ }
+ /**
+ * If no prefix is provided in the pattern, then this operation will have to walk
+ * all the entries of the whole index.
+ */
+ public IEntryResult[] queryEntriesMatching(char[] pattern/*, boolean isCaseSensitive*/) throws IOException {
+ open();
+
+ if (pattern == null || pattern.length == 0) return null;
+ int[] blockNums = null;
+ int firstStar = CharOperation.indexOf('*', pattern);
+ switch (firstStar){
+ case -1 :
+ WordEntry entry = getEntry(pattern);
+ if (entry == null) return null;
+ return new IEntryResult[]{ new EntryResult(entry.getWord(), entry.getRefs()) };
+ case 0 :
+ blockNums = summary.getAllBlockNums();
+ break;
+ default :
+ char[] prefix = CharOperation.subarray(pattern, 0, firstStar);
+ blockNums = summary.getBlockNumsForPrefix(prefix);
+ }
+ if (blockNums == null || blockNums.length == 0) return null;
+
+ IEntryResult[] entries = new IEntryResult[5];
+ int count = 0;
+ for (int i = 0, max = blockNums.length; i < max; i++) {
+ IndexBlock block = getIndexBlock(blockNums[i]);
+ block.reset();
+ boolean found = false;
+ WordEntry entry = new WordEntry();
+ while (block.nextEntry(entry)) {
+ if (CharOperation.match(entry.getWord(), pattern, true)) {
+ if (count == entries.length){
+ System.arraycopy(entries, 0, entries = new IEntryResult[count*2], 0, count);
+ }
+ entries[count++] = new EntryResult(entry.getWord(), entry.getRefs());
+ found = true;
+ } else {
+ if (found) break;
+ }
+ }
+ }
+ if (count != entries.length){
+ System.arraycopy(entries, 0, entries = new IEntryResult[count], 0, count);
+ }
+ return entries;
+ }
+ public IEntryResult[] queryEntriesPrefixedBy(char[] prefix) throws IOException {
+ open();
+
+ int blockLoc = summary.getFirstBlockLocationForPrefix(prefix);
+ if (blockLoc < 0) return null;
+
+ IEntryResult[] entries = new IEntryResult[5];
+ int count = 0;
+ while(blockLoc >= 0){
+ IndexBlock block = getIndexBlock(summary.getBlockNum(blockLoc));
+ block.reset();
+ boolean found = false;
+ WordEntry entry = new WordEntry();
+ while (block.nextEntry(entry)) {
+ if (CharOperation.prefixEquals(prefix, entry.getWord())) {
+ if (count == entries.length){
+ System.arraycopy(entries, 0, entries = new IEntryResult[count*2], 0, count);
+ }
+ entries[count++] = new EntryResult(entry.getWord(), entry.getRefs());
+ found = true;
+ } else {
+ if (found) break;
+ }
+ }
+ /* consider next block ? */
+ blockLoc = summary.getNextBlockLocationForPrefix(prefix, blockLoc);
+ }
+ if (count == 0) return null;
+ if (count != entries.length){
+ System.arraycopy(entries, 0, entries = new IEntryResult[count], 0, count);
+ }
+ return entries;
+ }
+ public IQueryResult[] queryFilesReferringToPrefix(char[] prefix) throws IOException {
+ open();
+
+ int blockLoc = summary.getFirstBlockLocationForPrefix(prefix);
+ if (blockLoc < 0) return null;
+
+ // each filename must be returned already once
+ org.eclipse.cdt.internal.core.search.HashtableOfInt fileMatches = new org.eclipse.cdt.internal.core.search.HashtableOfInt(20);
+ int count = 0;
+ while(blockLoc >= 0){
+ IndexBlock block = getIndexBlock(summary.getBlockNum(blockLoc));
+ block.reset();
+ boolean found = false;
+ WordEntry entry = new WordEntry();
+ while (block.nextEntry(entry)) {
+ if (CharOperation.prefixEquals(prefix, entry.getWord()/*, isCaseSensitive*/)) {
+ int [] refs = entry.getRefs();
+ for (int i = 0, max = refs.length; i < max; i++){
+ int ref = refs[i];
+ if (!fileMatches.containsKey(ref)){
+ count++;
+ fileMatches.put(ref, getIndexedFile(ref));
+ }
+ }
+ found = true;
+ } else {
+ if (found) break;
+ }
+ }
+ /* consider next block ? */
+ blockLoc = summary.getNextBlockLocationForPrefix(prefix, blockLoc);
+ }
+ /* extract indexed files */
+ IQueryResult[] files = new IQueryResult[count];
+ Object[] indexedFiles = fileMatches.valueTable;
+ for (int i = 0, index = 0, max = indexedFiles.length; i < max; i++){
+ IndexedFile indexedFile = (IndexedFile) indexedFiles[i];
+ if (indexedFile != null){
+ files[index++] = indexedFile;
+ }
+ }
+ return files;
+ }
+ /**
+ * @see IndexInput#queryInDocumentNames(String)
+ */
+ public IQueryResult[] queryInDocumentNames(String word) throws IOException {
+ open();
+ ArrayList matches= new ArrayList();
+ setFirstFile();
+ while (hasMoreFiles()) {
+ IndexedFile file= getCurrentFile();
+ if (file.getPath().indexOf(word) != -1)
+ matches.add(file);
+ moveToNextFile();
+ }
+ IQueryResult[] match= new IQueryResult[matches.size()];
+ matches.toArray(match);
+ return match;
+ }
+ /**
+ * @see IndexInput#setFirstFile()
+ */
+
+ protected void setFirstFile() throws IOException {
+ filePosition= 1;
+ if (getNumFiles() > 0) {
+ currentFileListBlockNum= summary.getBlockNumForFileNum(1);
+ currentFileListBlock= getFileListBlock(currentFileListBlockNum);
+ }
+ }
+ /**
+ * @see IndexInput#setFirstWord()
+ */
+
+ protected void setFirstWord() throws IOException {
+ wordPosition= 1;
+ if (getNumWords() > 0) {
+ currentIndexBlockNum= summary.getFirstWordBlockNum();
+ currentIndexBlock= getIndexBlock(currentIndexBlockNum);
+ currentWordEntry= new WordEntry();
+ currentIndexBlock.reset();
+ currentIndexBlock.nextEntry(currentWordEntry);
+ }
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/BlocksIndexOutput.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/BlocksIndexOutput.java
new file mode 100644
index 00000000000..44f3bd85937
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/BlocksIndexOutput.java
@@ -0,0 +1,167 @@
+ /*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * A blocksIndexOutput is used to save an index in a file with the given structure:
+ * - Signature of the file;
+ * - FileListBlocks;
+ * - IndexBlocks;
+ * - Summary of the index.
+ */
+
+public class BlocksIndexOutput extends IndexOutput {
+ protected RandomAccessFile indexOut;
+ protected int blockNum;
+ protected boolean opened= false;
+ protected File indexFile;
+ protected FileListBlock fileListBlock;
+ protected IndexBlock indexBlock;
+ protected int numWords= 0;
+ protected IndexSummary summary;
+ protected int numFiles= 0;
+ protected boolean firstInBlock;
+ protected boolean firstIndexBlock;
+ protected boolean firstFileListBlock;
+
+ public BlocksIndexOutput(File indexFile) {
+ this.indexFile= indexFile;
+ summary= new IndexSummary();
+ blockNum= 1;
+ firstInBlock= true;
+ firstIndexBlock= true;
+ firstFileListBlock= true;
+ }
+ /**
+ * @see IndexOutput#addFile
+ */
+ public void addFile(IndexedFile indexedFile) throws IOException {
+ if (firstFileListBlock) {
+ firstInBlock= true;
+ fileListBlock= new FileListBlock(IIndexConstants.BLOCK_SIZE);
+ firstFileListBlock= false;
+ }
+ if (fileListBlock.addFile(indexedFile)) {
+ if (firstInBlock) {
+ summary.addFirstFileInBlock(indexedFile, blockNum);
+ firstInBlock= false;
+ }
+ numFiles++;
+ } else {
+ if (fileListBlock.isEmpty()) {
+ return;
+ }
+ flushFiles();
+ addFile(indexedFile);
+ }
+ }
+ /**
+ * @see IndexOutput#addWord
+ */
+ public void addWord(WordEntry entry) throws IOException {
+ if (firstIndexBlock) {
+ indexBlock= new GammaCompressedIndexBlock(IIndexConstants.BLOCK_SIZE);
+ firstInBlock= true;
+ firstIndexBlock= false;
+ }
+ if (entry.getNumRefs() == 0)
+ return;
+ if (indexBlock.addEntry(entry)) {
+ if (firstInBlock) {
+ summary.addFirstWordInBlock(entry.getWord(), blockNum);
+ firstInBlock= false;
+ }
+ numWords++;
+ } else {
+ if (indexBlock.isEmpty()) {
+ return;
+ }
+ flushWords();
+ addWord(entry);
+ }
+ }
+ /**
+ * @see IndexOutput#close
+ */
+ public void close() throws IOException {
+ if (opened) {
+ indexOut.close();
+ summary= null;
+ numFiles= 0;
+ opened= false;
+ }
+ }
+ /**
+ * @see IndexOutput#flush
+ */
+ public void flush() throws IOException {
+
+ summary.setNumFiles(numFiles);
+ summary.setNumWords(numWords);
+ indexOut.seek(blockNum * (long) IIndexConstants.BLOCK_SIZE);
+ summary.write(indexOut);
+ indexOut.seek(0);
+ indexOut.writeUTF(IIndexConstants.SIGNATURE);
+ indexOut.writeInt(blockNum);
+ }
+ /**
+ * Writes the current fileListBlock on the disk and initialises it
+ * (when it's full or it's the end of the index).
+ */
+ protected void flushFiles() throws IOException {
+ if (!firstFileListBlock
+ && fileListBlock != null) {
+ fileListBlock.flush();
+ fileListBlock.write(indexOut, blockNum++);
+ fileListBlock.clear();
+ firstInBlock= true;
+ }
+ }
+ /**
+ * Writes the current indexBlock on the disk and initialises it
+ * (when it's full or it's the end of the index).
+ */
+ protected void flushWords() throws IOException {
+ if (!firstInBlock
+ && indexBlock != null) { // could have added a document without any indexed word, no block created yet
+ indexBlock.flush();
+ indexBlock.write(indexOut, blockNum++);
+ indexBlock.clear();
+ firstInBlock= true;
+ }
+ }
+ /**
+ * @see IndexOutput#getDestination
+ */
+ public Object getDestination() {
+ return indexFile;
+ }
+ /**
+ * @see IndexOutput#open
+ */
+ public void open() throws IOException {
+ if (!opened) {
+ summary= new IndexSummary();
+ numFiles= 0;
+ numWords= 0;
+ blockNum= 1;
+ firstInBlock= true;
+ firstIndexBlock= true;
+ firstFileListBlock= true;
+ indexOut= new SafeRandomAccessFile(this.indexFile, "rw"); //$NON-NLS-1$
+ opened= true;
+ }
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/CodeByteStream.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/CodeByteStream.java
new file mode 100644
index 00000000000..b4c386047a2
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/CodeByteStream.java
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.UTFDataFormatException;
+
+public class CodeByteStream {
+ protected byte[] bytes;
+ protected int byteOffset= 0;
+ protected int bitOffset= 0;
+ protected int markByteOffset= -1;
+ protected int markBitOffset= -1;
+
+ public CodeByteStream() {
+ this(16);
+ }
+ public CodeByteStream(byte[] bytes) {
+ this.bytes= bytes;
+ }
+ public CodeByteStream(int initialByteLength) {
+ bytes= new byte[initialByteLength];
+ }
+ public int byteLength() {
+ return (bitOffset + 7) / 8 + byteOffset;
+ }
+ public byte[] getBytes(int startOffset, int endOffset) {
+ int byteLength= byteLength();
+ if (startOffset > byteLength || endOffset > byteLength || startOffset > endOffset)
+ throw new IndexOutOfBoundsException();
+ int length= endOffset - startOffset;
+ byte[] result= new byte[length];
+ System.arraycopy(bytes, startOffset, result, 0, length);
+ if (endOffset == byteLength && bitOffset != 0) {
+ int mask= (1 << bitOffset) - 1;
+ result[length - 1] &= (mask << 8 - bitOffset);
+ }
+ return result;
+ }
+ protected void grow() {
+ byte[] newBytes= new byte[bytes.length * 2 + 1];
+ System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
+ bytes= newBytes;
+ }
+ public void mark() {
+ markByteOffset= byteOffset;
+ markBitOffset= bitOffset;
+ }
+ /**
+ * Reads a single bit (value == 0 or == 1).
+ */
+ public int readBit() {
+ int value= (bytes[byteOffset] >> (7 - bitOffset)) & 1;
+ if (++bitOffset >= 8) {
+ bitOffset= 0;
+ ++byteOffset;
+ }
+ return value;
+ }
+ /**
+ * Read up to 32 bits from the stream.
+ */
+ public int readBits(int numBits) {
+ int value= 0;
+ while (numBits > 0) {
+ int bitsToRead= 8 - bitOffset;
+ if (bitsToRead > numBits)
+ bitsToRead= numBits;
+ int mask= (1 << bitsToRead) - 1;
+ value |= ((bytes[byteOffset] >> (8 - bitOffset - bitsToRead)) & mask) << (numBits - bitsToRead);
+ numBits -= bitsToRead;
+ bitOffset += bitsToRead;
+ if (bitOffset >= 8) {
+ bitOffset -= 8;
+ byteOffset += 1;
+ }
+ }
+ return value;
+ }
+ public final int readByte() {
+
+ // no need to rebuild byte value from bit sequences
+ if (bitOffset == 0) return bytes[byteOffset++] & 255;
+
+ int value= 0;
+ int numBits = 8;
+ while (numBits > 0) {
+ int bitsToRead= 8 - bitOffset;
+ if (bitsToRead > numBits)
+ bitsToRead= numBits;
+ int mask= (1 << bitsToRead) - 1;
+ value |= ((bytes[byteOffset] >> (8 - bitOffset - bitsToRead)) & mask) << (numBits - bitsToRead);
+ numBits -= bitsToRead;
+ bitOffset += bitsToRead;
+ if (bitOffset >= 8) {
+ bitOffset -= 8;
+ byteOffset += 1;
+ }
+ }
+ return value;
+ }
+ /**
+ * Reads a value using Gamma coding.
+ */
+ public int readGamma() {
+ int numBits= readUnary();
+ return readBits(numBits - 1) | (1 << (numBits - 1));
+ }
+ public char[] readUTF() throws UTFDataFormatException {
+ int utflen= readByte();
+ if (utflen == 255) {
+ // long UTF
+ int high = readByte();
+ int low = readByte();
+ utflen = (high << 8) + low;
+ }
+ char str[]= new char[utflen];
+ int count= 0;
+ int strlen= 0;
+ while (count < utflen) {
+ int c= readByte();
+ int char2, char3;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ case 2 :
+ case 3 :
+ case 4 :
+ case 5 :
+ case 6 :
+ case 7 :
+ // 0xxxxxxx
+ count++;
+ str[strlen++]= (char) c;
+ break;
+ case 12 :
+ case 13 :
+ // 110x xxxx 10xx xxxx
+ count += 2;
+ if (count > utflen)
+ throw new UTFDataFormatException();
+ char2= readByte();
+ if ((char2 & 0xC0) != 0x80)
+ throw new UTFDataFormatException();
+ str[strlen++]= (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
+ break;
+ case 14 :
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ count += 3;
+ if (count > utflen)
+ throw new UTFDataFormatException();
+ char2= readByte();
+ char3= readByte();
+ if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
+ throw new UTFDataFormatException();
+ str[strlen++]= (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
+ break;
+ default :
+ // 10xx xxxx, 1111 xxxx
+ throw new UTFDataFormatException();
+ }
+ }
+ if (strlen < utflen)
+ System.arraycopy(str, 0, str= new char[strlen], 0, strlen);
+ return str;
+ }
+ /**
+ * Reads a value in unary.
+ */
+ public int readUnary() {
+ int value= 1;
+ int mask= 1 << (7 - bitOffset);
+ while ((bytes[byteOffset] & mask) != 0) {
+ ++value;
+ if (++bitOffset >= 8) {
+ bitOffset= 0;
+ ++byteOffset;
+ mask= 0x80;
+ } else {
+ mask >>>= 1;
+ }
+ }
+ // skip the 0 bit
+ if (++bitOffset >= 8) {
+ bitOffset= 0;
+ ++byteOffset;
+ }
+ return value;
+ }
+ public void reset() {
+ byteOffset= bitOffset= 0;
+ markByteOffset= markBitOffset= -1;
+ }
+ public void reset(byte[] bytes) {
+ this.bytes= bytes;
+ reset();
+ }
+ public void reset(byte[] bytes, int byteOffset) {
+ reset(bytes);
+ this.byteOffset= byteOffset;
+ }
+ public boolean resetToMark() {
+ if (markByteOffset == -1)
+ return false;
+ byteOffset= markByteOffset;
+ bitOffset= markBitOffset;
+ markByteOffset= markBitOffset= -1;
+ return true;
+ }
+ public void skipBits(int numBits) {
+ int newOffset= byteOffset * 8 + bitOffset + numBits;
+ if (newOffset < 0 || (newOffset + 7) / 8 >= bytes.length)
+ throw new IllegalArgumentException();
+ byteOffset= newOffset / 8;
+ bitOffset= newOffset % 8;
+ }
+ public byte[] toByteArray() {
+ return getBytes(0, byteLength());
+ }
+ /**
+ * Writes a single bit (value == 0 or == 1).
+ */
+ public void writeBit(int value) {
+ bytes[byteOffset] |= (value & 1) << (7 - bitOffset);
+ if (++bitOffset >= 8) {
+ bitOffset= 0;
+ if (++byteOffset >= bytes.length)
+ grow();
+ }
+ }
+ /**
+ * Write up to 32 bits to the stream.
+ * The least significant numBits bits of value are written.
+ */
+ public void writeBits(int value, int numBits) {
+ while (numBits > 0) {
+ int bitsToWrite= 8 - bitOffset;
+ if (bitsToWrite > numBits)
+ bitsToWrite= numBits;
+ int shift= 8 - bitOffset - bitsToWrite;
+ int mask= ((1 << bitsToWrite) - 1) << shift;
+ bytes[byteOffset]= (byte) ((bytes[byteOffset] & ~mask) | (((value >>> (numBits - bitsToWrite)) << shift) & mask));
+ numBits -= bitsToWrite;
+ bitOffset += bitsToWrite;
+ if (bitOffset >= 8) {
+ bitOffset -= 8;
+ if (++byteOffset >= bytes.length)
+ grow();
+ }
+ }
+ }
+ public void writeByte(int value) {
+ writeBits(value, 8);
+ }
+ /**
+ * Writes the given value using Gamma coding, in which positive integer x
+ * is represented by coding floor(log2(x) in unary followed by the value
+ * of x - 2**floor(log2(x)) in binary.
+ * The value must be >= 1.
+ */
+ public void writeGamma(int value) {
+ if (value < 1)
+ throw new IllegalArgumentException();
+ int temp= value;
+ int numBits= 0;
+ while (temp != 0) {
+ temp >>>= 1;
+ ++numBits;
+ }
+ writeUnary(numBits);
+ writeBits(value, numBits - 1);
+ }
+ public void writeUTF(char[] str, int start, int end) {
+ int utflen= 0;
+ for (int i= start; i < end; i++) {
+ int c= str[i];
+ if ((c >= 0x0001) && (c <= 0x007F)) {
+ utflen++;
+ } else if (c > 0x07FF) {
+ utflen += 3;
+ } else {
+ utflen += 2;
+ }
+ }
+ if (utflen < 255) {
+ writeByte(utflen & 0xFF);
+ } else if (utflen > 65535) {
+ throw new IllegalArgumentException();
+ } else {
+ writeByte(255); // marker for long UTF
+ writeByte((utflen >>> 8) & 0xFF); // high byte
+ writeByte((utflen >>> 0) & 0xFF); // low byte
+ }
+ for (int i= start; i < end; i++) {
+ int c= str[i];
+ if ((c >= 0x0001) && (c <= 0x007F)) {
+ writeByte(c);
+ } else if (c > 0x07FF) {
+ writeByte(0xE0 | ((c >> 12) & 0x0F));
+ writeByte(0x80 | ((c >> 6) & 0x3F));
+ writeByte(0x80 | ((c >> 0) & 0x3F));
+ } else {
+ writeByte(0xC0 | ((c >> 6) & 0x1F));
+ writeByte(0x80 | ((c >> 0) & 0x3F));
+ }
+ }
+ }
+ /**
+ * Write the given value in unary. The value must be >= 1.
+ */
+ public void writeUnary(int value) {
+ if (value < 1)
+ throw new IllegalArgumentException();
+ int mask= 1 << (7 - bitOffset);
+ // write N-1 1-bits
+ while (--value > 0) {
+ bytes[byteOffset] |= mask;
+ if (++bitOffset >= 8) {
+ bitOffset= 0;
+ if (++byteOffset >= bytes.length)
+ grow();
+ mask= 0x80;
+ } else {
+ mask >>>= 1;
+ }
+ }
+ // write a 0-bit
+ bytes[byteOffset] &= ~mask;
+ if (++bitOffset >= 8) {
+ bitOffset= 0;
+ if (++byteOffset >= bytes.length)
+ grow();
+ }
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/EntryResult.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/EntryResult.java
new file mode 100644
index 00000000000..09a2845f78c
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/EntryResult.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import org.eclipse.cdt.internal.core.index.IEntryResult;
+import org.eclipse.cdt.internal.core.search.CharOperation;
+
+
+public class EntryResult implements IEntryResult {
+ private char[] word;
+ private int[] fileRefs;
+
+public EntryResult(char[] word, int[] refs) {
+ this.word = word;
+ this.fileRefs = refs;
+}
+public boolean equals(Object anObject){
+
+ if (this == anObject) {
+ return true;
+ }
+ if ((anObject != null) && (anObject instanceof EntryResult)) {
+ EntryResult anEntryResult = (EntryResult) anObject;
+ if (!CharOperation.equals(this.word, anEntryResult.word)) return false;
+
+ int length;
+ int[] refs, otherRefs;
+ if ((length = (refs = this.fileRefs).length) != (otherRefs = anEntryResult.fileRefs).length) return false;
+ for (int i = 0; i < length; i++){
+ if (refs[i] != otherRefs[i]) return false;
+ }
+ return true;
+ }
+ return false;
+
+}
+public int[] getFileReferences() {
+ return fileRefs;
+}
+public char[] getWord() {
+ return word;
+}
+public int hashCode(){
+ return CharOperation.hashCode(word);
+}
+public String toString(){
+ StringBuffer buffer = new StringBuffer(word.length * 2);
+ buffer.append("EntryResult: word="); //$NON-NLS-1$
+ buffer.append(word);
+ buffer.append(", refs={"); //$NON-NLS-1$
+ for (int i = 0; i < fileRefs.length; i++){
+ if (i > 0) buffer.append(',');
+ buffer.append(' ');
+ buffer.append(fileRefs[i]);
+ }
+ buffer.append(" }"); //$NON-NLS-1$
+ return buffer.toString();
+}
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Field.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Field.java
new file mode 100644
index 00000000000..dade592a620
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Field.java
@@ -0,0 +1,382 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.UTFDataFormatException;
+
+public class Field {
+ protected byte[] buffer; // contents
+ protected int offset; // offset of the field within the byte array
+ protected int length; // length of the field
+
+ /**
+ * ByteSegment constructor comment.
+ */
+ public Field(byte[] bytes) {
+ this.buffer= bytes;
+ this.offset= 0;
+ this.length= bytes.length;
+ }
+ /**
+ * ByteSegment constructor comment.
+ */
+ public Field(byte[] bytes, int length) {
+ this.buffer= bytes;
+ this.offset= 0;
+ this.length= length;
+ }
+ /**
+ * ByteSegment constructor comment.
+ */
+ public Field(byte[] bytes, int offset, int length) {
+ this.buffer= bytes;
+ this.offset= offset;
+ this.length= length;
+ }
+ /**
+ * Creates a new field containing an empty buffer of the given length.
+ */
+ public Field(int length) {
+ this.buffer= new byte[length];
+ this.offset= 0;
+ this.length= length;
+ }
+ public byte[] buffer() {
+ return buffer;
+ }
+ public Field buffer(byte[] buffer) {
+ this.buffer= buffer;
+ return this;
+ }
+ public Field clear() {
+ clear(buffer, offset, length);
+ return this;
+ }
+ protected static void clear(byte[] buffer, int offset, int length) {
+ int n= offset;
+ for (int i= 0; i < length; i++) {
+ buffer[n]= 0;
+ n++;
+ }
+ }
+ public Field clear(int length) {
+ clear(buffer, offset, length);
+ return this;
+ }
+ public Field clear(int offset, int length) {
+ clear(buffer, this.offset + offset, length);
+ return this;
+ }
+ protected static int compare(byte[] buffer1, int offset1, int length1, byte[] buffer2, int offset2, int length2) {
+ int n= Math.min(length1, length2);
+ for (int i= 0; i < n; i++) {
+ int j1= buffer1[offset1 + i] & 255;
+ int j2= buffer2[offset2 + i] & 255;
+ if (j1 > j2)
+ return 1;
+ if (j1 < j2)
+ return -1;
+ }
+ if (length1 > n) {
+ for (int i= n; i < length1; i++)
+ if (buffer1[offset1 + i] != 0)
+ return 1;
+ return 0;
+ }
+ for (int i= n; i < length2; i++)
+ if (buffer2[offset2 + i] != 0)
+ return -1;
+ return 0;
+ }
+ public static int compare(Field f1, Field f2) {
+ return compare(f1.buffer, f1.offset, f1.length, f2.buffer, f2.offset, f2.length);
+ }
+ // copy bytes from one offset to another within the field
+ public Field copy(int fromOffset, int toOffset, int length) {
+ System.arraycopy(buffer, offset + fromOffset, buffer, offset + toOffset, length);
+ return this;
+ }
+ public Field dec(int n) {
+ offset -= n;
+ return this;
+ }
+ public byte[] get() {
+ byte[] result= new byte[length];
+ System.arraycopy(buffer, offset, result, 0, length);
+ return result;
+ }
+ public byte[] get(int offset, int length) {
+ byte[] result= new byte[length];
+ System.arraycopy(buffer, this.offset + offset, result, 0, length);
+ return result;
+ }
+ public Field getField(int offset, int length) {
+ return new Field(buffer, this.offset + offset, length);
+ }
+ public int getInt1() {
+ return buffer[this.offset];
+ }
+ public int getInt1(int offset) {
+ return buffer[this.offset + offset];
+ }
+ public int getInt2() {
+ int i= this.offset;
+ int v= buffer[i++];
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getInt2(int offset) {
+ int i= this.offset + offset;
+ int v= buffer[i++];
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getInt3() {
+ int i= this.offset;
+ int v= buffer[i++];
+ v= (v << 8) | (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getInt3(int offset) {
+ int i= this.offset + offset;
+ int v= buffer[i++];
+ v= (v << 8) | (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getInt4() {
+ int i= this.offset;
+ int v= buffer[i++];
+ v= (v << 8) | (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getInt4(int offset) {
+ int i= this.offset + offset;
+ int v= buffer[i++];
+ v= (v << 8) | (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getUInt1() {
+ return buffer[this.offset] & 255;
+ }
+ public int getUInt1(int offset) {
+ return buffer[this.offset + offset] & 255;
+ }
+ public int getUInt2() {
+ int i= this.offset;
+ int v= (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getUInt2(int offset) {
+ int i= this.offset + offset;
+ int v= (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getUInt3() {
+ int i= this.offset;
+ int v= (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public int getUInt3(int offset) {
+ int i= this.offset + offset;
+ int v= (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ v= (v << 8) | (buffer[i++] & 255);
+ return v;
+ }
+ public char[] getUTF(int offset) throws UTFDataFormatException {
+ int pos= this.offset + offset;
+ int utflen= getUInt2(pos);
+ pos += 2;
+ char str[]= new char[utflen];
+ int count= 0;
+ int strlen= 0;
+ while (count < utflen) {
+ int c= buffer[pos++] & 0xFF;
+ int char2, char3;
+ switch (c >> 4) {
+ case 0 :
+ case 1 :
+ case 2 :
+ case 3 :
+ case 4 :
+ case 5 :
+ case 6 :
+ case 7 :
+ // 0xxxxxxx
+ count++;
+ str[strlen++]= (char) c;
+ break;
+ case 12 :
+ case 13 :
+ // 110x xxxx 10xx xxxx
+ count += 2;
+ if (count > utflen)
+ throw new UTFDataFormatException();
+ char2= buffer[pos++] & 0xFF;
+ if ((char2 & 0xC0) != 0x80)
+ throw new UTFDataFormatException();
+ str[strlen++]= (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
+ break;
+ case 14 :
+ // 1110 xxxx 10xx xxxx 10xx xxxx
+ count += 3;
+ if (count > utflen)
+ throw new UTFDataFormatException();
+ char2= buffer[pos++] & 0xFF;
+ char3= buffer[pos++] & 0xFF;
+ if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
+ throw new UTFDataFormatException();
+ str[strlen++]= (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
+ break;
+ default :
+ // 10xx xxxx, 1111 xxxx
+ throw new UTFDataFormatException();
+ }
+ }
+ if (strlen < utflen)
+ System.arraycopy(str, 0, str= new char[strlen], 0, strlen);
+ return str;
+ }
+ public Field inc(int n) {
+ offset += n;
+ return this;
+ }
+ public int length() {
+ return length;
+ }
+ public Field length(int length) {
+ this.length= length;
+ return this;
+ }
+ /**
+ Returns the offset into the underlying byte array that this field is defined over.
+ */
+ public int offset() {
+ return offset;
+ }
+ public Field offset(int offset) {
+ this.offset= offset;
+ return this;
+ }
+ public Field pointTo(int offset) {
+ return new Field(buffer, this.offset + offset, 0);
+ }
+ public Field put(byte[] b) {
+ return put(0, b);
+ }
+ public Field put(int offset, byte[] b) {
+ System.arraycopy(b, 0, buffer, this.offset + offset, b.length);
+ return this;
+ }
+ public Field put(int offset, Field f) {
+ System.arraycopy(f.buffer, f.offset, buffer, this.offset + offset, f.length);
+ return this;
+ }
+ public Field put(Field f) {
+ System.arraycopy(f.buffer, f.offset, buffer, offset, f.length);
+ return this;
+ }
+ public Field putInt1(int n) {
+ buffer[offset]= (byte) (n);
+ return this;
+ }
+ public Field putInt1(int offset, int n) {
+ buffer[this.offset + offset]= (byte) (n);
+ return this;
+ }
+ public Field putInt2(int n) {
+ int i= offset;
+ buffer[i++]= (byte) (n >> 8);
+ buffer[i++]= (byte) (n >> 0);
+ return this;
+ }
+ public Field putInt2(int offset, int n) {
+ int i= this.offset + offset;
+ buffer[i++]= (byte) (n >> 8);
+ buffer[i++]= (byte) (n >> 0);
+ return this;
+ }
+ public Field putInt3(int n) {
+ int i= offset;
+ buffer[i++]= (byte) (n >> 16);
+ buffer[i++]= (byte) (n >> 8);
+ buffer[i++]= (byte) (n >> 0);
+ return this;
+ }
+ public Field putInt3(int offset, int n) {
+ int i= this.offset + offset;
+ buffer[i++]= (byte) (n >> 16);
+ buffer[i++]= (byte) (n >> 8);
+ buffer[i++]= (byte) (n >> 0);
+ return this;
+ }
+ public Field putInt4(int n) {
+ int i= offset;
+ buffer[i++]= (byte) (n >> 24);
+ buffer[i++]= (byte) (n >> 16);
+ buffer[i++]= (byte) (n >> 8);
+ buffer[i++]= (byte) (n >> 0);
+ return this;
+ }
+ public Field putInt4(int offset, int n) {
+ int i= this.offset + offset;
+ buffer[i++]= (byte) (n >> 24);
+ buffer[i++]= (byte) (n >> 16);
+ buffer[i++]= (byte) (n >> 8);
+ buffer[i++]= (byte) (n >> 0);
+ return this;
+ }
+ public int putUTF(int offset, char[] str) {
+ int strlen= str.length;
+ int utflen= 0;
+ for (int i= 0; i < strlen; i++) {
+ int c= str[i];
+ if ((c >= 0x0001) && (c <= 0x007F)) {
+ utflen++;
+ } else if (c > 0x07FF) {
+ utflen += 3;
+ } else {
+ utflen += 2;
+ }
+ }
+ if (utflen > 65535)
+ throw new IllegalArgumentException();
+ int pos= this.offset + offset;
+ buffer[pos++]= (byte) ((utflen >>> 8) & 0xFF);
+ buffer[pos++]= (byte) ((utflen >>> 0) & 0xFF);
+ for (int i= 0; i < strlen; i++) {
+ int c= str[i];
+ if ((c >= 0x0001) && (c <= 0x007F)) {
+ buffer[pos++]= ((byte) c);
+ } else if (c > 0x07FF) {
+ buffer[pos++]= ((byte) (0xE0 | ((c >> 12) & 0x0F)));
+ buffer[pos++]= ((byte) (0x80 | ((c >> 6) & 0x3F)));
+ buffer[pos++]= ((byte) (0x80 | ((c >> 0) & 0x3F)));
+ } else {
+ buffer[pos++]= ((byte) (0xC0 | ((c >> 6) & 0x1F)));
+ buffer[pos++]= ((byte) (0x80 | ((c >> 0) & 0x3F)));
+ }
+ }
+ return 2 + utflen;
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/FileListBlock.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/FileListBlock.java
new file mode 100644
index 00000000000..a3fc669d564
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/FileListBlock.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+ package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class FileListBlock extends Block {
+
+ protected int offset= 0;
+ protected String prevPath= null;
+ protected String[] paths= null;
+
+ public FileListBlock(int blockSize) {
+ super(blockSize);
+ }
+ /**
+ * add the name of the indexedfile to the buffr of the field.
+ * The name is not the entire name of the indexedfile, but the
+ * difference between its name and the name of the previous indexedfile ...
+ */
+ public boolean addFile(IndexedFile indexedFile) {
+ int offset= this.offset;
+ if (isEmpty()) {
+ field.putInt4(offset, indexedFile.getFileNumber());
+ offset += 4;
+ }
+ String path= indexedFile.getPath();
+ int prefixLen= prevPath == null ? 0 : Util.prefixLength(prevPath, path);
+ int sizeEstimate= 2 + 2 + (path.length() - prefixLen) * 3;
+ if (offset + sizeEstimate > blockSize - 2)
+ return false;
+ field.putInt2(offset, prefixLen);
+ offset += 2;
+ char[] chars= new char[path.length() - prefixLen];
+ path.getChars(prefixLen, path.length(), chars, 0);
+ offset += field.putUTF(offset, chars);
+ this.offset= offset;
+ prevPath= path;
+ return true;
+ }
+ public void clear() {
+ reset();
+ super.clear();
+ }
+ public void flush() {
+ if (offset > 0) {
+ field.putInt2(offset, 0);
+ field.putInt2(offset + 2, 0);
+ offset= 0;
+ }
+ }
+ public IndexedFile getFile(int fileNum) throws IOException {
+ IndexedFile resp= null;
+ try {
+ String[] paths= getPaths();
+ int i= fileNum - field.getInt4(0);
+ resp= new IndexedFile(paths[i], fileNum);
+ } catch (Exception e) {
+ //fileNum too big
+ }
+ return resp;
+ }
+ /**
+ * Creates a vector of paths reading the buffer of the field.
+ */
+ protected String[] getPaths() throws IOException {
+ if (paths == null) {
+ ArrayList v= new ArrayList();
+ int offset= 4;
+ char[] prevPath= null;
+ for (;;) {
+ int prefixLen= field.getUInt2(offset);
+ offset += 2;
+ int utfLen= field.getUInt2(offset);
+ char[] path= field.getUTF(offset);
+ offset += 2 + utfLen;
+ if (prefixLen != 0) {
+ char[] temp= new char[prefixLen + path.length];
+ System.arraycopy(prevPath, 0, temp, 0, prefixLen);
+ System.arraycopy(path, 0, temp, prefixLen, path.length);
+ path= temp;
+ }
+ if (path.length == 0)
+ break;
+ v.add(new String(path));
+ prevPath= path;
+ }
+ paths= new String[v.size()];
+ v.toArray(paths);
+ }
+ return paths;
+ }
+ public boolean isEmpty() {
+ return offset == 0;
+ }
+ public void reset() {
+ offset= 0;
+ prevPath= null;
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/GammaCompressedIndexBlock.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/GammaCompressedIndexBlock.java
new file mode 100644
index 00000000000..cae67fda640
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/GammaCompressedIndexBlock.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.UTFDataFormatException;
+
+/**
+ * Uses prefix coding on words, and gamma coding of document numbers differences.
+ */
+public class GammaCompressedIndexBlock extends IndexBlock {
+ CodeByteStream writeCodeStream= new CodeByteStream();
+ CodeByteStream readCodeStream;
+ char[] prevWord= null;
+ int offset= 0;
+
+ public GammaCompressedIndexBlock(int blockSize) {
+ super(blockSize);
+ readCodeStream= new CodeByteStream(field.buffer());
+ }
+ /**
+ * @see IndexBlock#addEntry
+ */
+ public boolean addEntry(WordEntry entry) {
+ writeCodeStream.reset();
+ encodeEntry(entry, prevWord, writeCodeStream);
+ if (offset + writeCodeStream.byteLength() > this.blockSize - 2) {
+ return false;
+ }
+ byte[] bytes= writeCodeStream.toByteArray();
+ field.put(offset, bytes);
+ offset += bytes.length;
+ prevWord= entry.getWord();
+ return true;
+ }
+ protected void encodeEntry(WordEntry entry, char[] prevWord, CodeByteStream codeStream) {
+ char[] word= entry.getWord();
+ int prefixLen= prevWord == null ? 0 : Util.prefixLength(prevWord, word);
+ codeStream.writeByte(prefixLen);
+ codeStream.writeUTF(word, prefixLen, word.length);
+ int n= entry.getNumRefs();
+ codeStream.writeGamma(n);
+ int prevRef= 0;
+ for (int i= 0; i < n; ++i) {
+ int ref= entry.getRef(i);
+ if (ref <= prevRef)
+ throw new IllegalArgumentException();
+ codeStream.writeGamma(ref - prevRef);
+ prevRef= ref;
+ }
+ }
+ /**
+ * @see IndexBlock#flush
+ */
+ public void flush() {
+ if (offset > 0) {
+ field.putInt2(offset, 0);
+ offset= 0;
+ prevWord= null;
+ }
+ }
+ /**
+ * @see IndexBlock#isEmpty
+ */
+ public boolean isEmpty() {
+ return offset == 0;
+ }
+ /**
+ * @see IndexBlock#nextEntry
+ */
+ public boolean nextEntry(WordEntry entry) {
+ try {
+ readCodeStream.reset(field.buffer(), offset);
+ int prefixLength= readCodeStream.readByte();
+ char[] word= readCodeStream.readUTF();
+ if (prevWord != null && prefixLength > 0) {
+ char[] temp= new char[prefixLength + word.length];
+ System.arraycopy(prevWord, 0, temp, 0, prefixLength);
+ System.arraycopy(word, 0, temp, prefixLength, word.length);
+ word= temp;
+ }
+ if (word.length == 0) {
+ return false;
+ }
+ entry.reset(word);
+ int n= readCodeStream.readGamma();
+ int prevRef= 0;
+ for (int i= 0; i < n; ++i) {
+ int ref= prevRef + readCodeStream.readGamma();
+ if (ref < prevRef)
+ throw new InternalError();
+ entry.addRef(ref);
+ prevRef= ref;
+ }
+ offset= readCodeStream.byteLength();
+ prevWord= word;
+ return true;
+ } catch (UTFDataFormatException e) {
+ return false;
+ }
+ }
+ /**
+ * @see IndexBlock#reset
+ */
+ public void reset() {
+ super.reset();
+ offset= 0;
+ prevWord= null;
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IFileDocument.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IFileDocument.java
new file mode 100644
index 00000000000..ffa3f6274ce
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IFileDocument.java
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.cdt.internal.core.search.CharOperation;
+
+
+/**
+ * An IFileDocument
represents an IFile.
+ */
+
+public class IFileDocument extends PropertyDocument {
+ protected IFile file;
+
+ // cached contents if needed - only one of them is used at a time
+ protected char[] charContents;
+ protected byte[] byteContents;
+ /**
+ * IFileDocument constructor comment.
+ */
+ public IFileDocument(IFile file) {
+ this(file, (char[])null);
+ }
+ /**
+ * IFileDocument constructor comment.
+ */
+ public IFileDocument(IFile file, byte[] byteContents) {
+ this.file= file;
+ this.byteContents= byteContents;
+ }
+ /**
+ * IFileDocument constructor comment.
+ */
+ public IFileDocument(IFile file, char[] charContents) {
+ this.file= file;
+ this.charContents= charContents;
+ }
+ /**
+ * @see org.eclipse.jdt.internal.core.index.IDocument#getByteContent()
+ */
+ public byte[] getByteContent() throws IOException {
+ if (byteContents != null) return byteContents;
+ IPath location = file.getLocation();
+ if (location == null) return new byte[0];
+ return byteContents = org.eclipse.cdt.internal.core.search.Util.getFileByteContent(location.toFile());
+ }
+ /**
+ * @see org.eclipse.jdt.internal.core.index.IDocument#getCharContent()
+ */
+ public char[] getCharContent() throws IOException {
+ if (charContents != null) return charContents;
+ IPath location = file.getLocation();
+ if (location == null) return CharOperation.NO_CHAR;
+ return charContents = org.eclipse.cdt.internal.core.search.Util.getFileCharContent(
+ location.toFile(),
+ getEncoding());
+ }
+ /**
+ * @see org.eclipse.jdt.internal.core.index.IDocument#getEncoding()
+ */
+ public String getEncoding() {
+ //TODO: Indexer - get encoding
+ return null;
+ }
+ /**
+ * @see org.eclipse.jdt.internal.core.index.IDocument#getName()
+ */
+ public String getName() {
+ return file.getFullPath().toString();
+ }
+ /**
+ * @see org.eclipse.jdt.internal.core.index.IDocument#getStringContent()
+ */
+ public String getStringContent() throws java.io.IOException {
+ return new String(getCharContent());
+ }
+ /**
+ * @see org.eclipse.jdt.internal.core.index.IDocument#getType()
+ */
+ public String getType() {
+ String extension= file.getFileExtension();
+ if (extension == null)
+ return ""; //$NON-NLS-1$
+ return extension;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IIndexConstants.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IIndexConstants.java
new file mode 100644
index 00000000000..760aa79e3c6
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IIndexConstants.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+/**
+ * This interface provides constants used by the search engine.
+ */
+public interface IIndexConstants {
+ /**
+ * The signature of the index file.
+ */
+ public static final String SIGNATURE= "INDEX FILE 0.012"; //$NON-NLS-1$
+ /**
+ * The separator for files in the index file.
+ */
+ public static final char FILE_SEPARATOR= '/';
+ /**
+ * The size of a block for a Block
.
+ */
+ public static final int BLOCK_SIZE= 8192;
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/InMemoryIndex.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/InMemoryIndex.java
new file mode 100644
index 00000000000..2d620b68cb0
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/InMemoryIndex.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+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 ObjectVector
, and the words in
+ * an HashtableOfObjects
.
+ */
+
+public class InMemoryIndex {
+
+ /**
+ * 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 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;
+ }
+ /**
+ * 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());
+ }
+ /**
+ * 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.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 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() {
+ words= new WordEntryHashedArray(501);
+ 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/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();
+ }
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Index.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Index.java
new file mode 100644
index 00000000000..f284d260959
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Index.java
@@ -0,0 +1,364 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.cdt.internal.core.index.IDocument;
+import org.eclipse.cdt.internal.core.index.IEntryResult;
+import org.eclipse.cdt.internal.core.index.IIndex;
+import org.eclipse.cdt.internal.core.index.IIndexer;
+import org.eclipse.cdt.internal.core.index.IQueryResult;
+
+/**
+ * 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.
+ *
+ * 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;
+
+ /**
+ * Index in memory, who is merged with mainIndex each times it
+ * reaches a certain size.
+ */
+ protected InMemoryIndex addsIndex;
+ protected IndexInput addsIndexInput;
+
+ /**
+ * State of the indexGenerator: addsIndex empty <=> MERGED, or
+ * addsIndex not empty <=> CAN_MERGE
+ */
+ protected int state;
+
+ /**
+ * Files removed form the addsIndex.
+ */
+ protected Map removedInAdds;
+
+ /**
+ * Files removed form the oldIndex.
+ */
+ protected Map removedInOld;
+ protected static final int CAN_MERGE= 0;
+ protected static final int MERGED= 1;
+ private File indexFile;
+
+ /**
+ * String representation of this index.
+ */
+ public String toString;
+
+ public Index(File indexDirectory, boolean reuseExistingFile) throws IOException {
+ this(indexDirectory,".index", reuseExistingFile); //$NON-NLS-1$
+ }
+
+ public Index(File indexDirectory, String indexName, boolean reuseExistingFile) throws IOException {
+ super();
+ state= MERGED;
+ indexFile= new File(indexDirectory, indexName);
+ initialize(reuseExistingFile);
+ }
+
+ public Index(String indexName, boolean reuseExistingFile) throws IOException {
+ this(indexName, null, reuseExistingFile);
+ }
+
+ public Index(String indexName, String toString, boolean reuseExistingFile) throws IOException {
+ super();
+ state= MERGED;
+ indexFile= new File(indexName);
+ this.toString = toString;
+ initialize(reuseExistingFile);
+ }
+ /**
+ * Indexes the given document, using the appropriate indexer registered in the indexerRegistry.
+ * If the document already exists in the index, it overrides the previous one. The changes will be
+ * taken into account after a merge.
+ */
+ public void add(IDocument document, IIndexer indexer) throws IOException {
+ if (timeToMerge()) {
+ merge();
+ }
+ IndexedFile indexedFile= addsIndex.getIndexedFile(document.getName());
+ if (indexedFile != null /*&& removedInAdds.get(document.getName()) == null*/
+ )
+ remove(indexedFile, MergeFactory.ADDS_INDEX);
+ IndexerOutput output= new IndexerOutput(addsIndex);
+ indexer.index(document, output);
+ state= CAN_MERGE;
+ }
+ /**
+ * Returns true if the index in memory is not empty, so
+ * merge() can be called to fill the mainIndex with the files and words
+ * contained in the addsIndex.
+ */
+ protected boolean canMerge() {
+ return state == CAN_MERGE;
+ }
+ /**
+ * Initialises the indexGenerator.
+ */
+ public void empty() throws IOException {
+
+ if (indexFile.exists()){
+ indexFile.delete();
+ //initialisation of mainIndex
+ InMemoryIndex mainIndex= new InMemoryIndex();
+ IndexOutput mainIndexOutput= new BlocksIndexOutput(indexFile);
+ if (!indexFile.exists())
+ mainIndex.save(mainIndexOutput);
+ }
+
+ //initialisation of addsIndex
+ addsIndex= new InMemoryIndex();
+ addsIndexInput= new SimpleIndexInput(addsIndex);
+
+ //vectors who keep track of the removed Files
+ removedInAdds= new HashMap(11);
+ removedInOld= new HashMap(11);
+ }
+ /**
+ * @see IIndex#getIndexFile
+ */
+ public File getIndexFile() {
+ return indexFile;
+ }
+ /**
+ * @see IIndex#getNumDocuments
+ */
+ public int getNumDocuments() throws IOException {
+ //save();
+ IndexInput input= new BlocksIndexInput(indexFile);
+ try {
+ input.open();
+ return input.getNumFiles();
+ } finally {
+ input.close();
+ }
+ }
+ /**
+ * @see IIndex#getNumWords
+ */
+ public int getNumWords() throws IOException {
+ //save();
+ IndexInput input= new BlocksIndexInput(indexFile);
+ try {
+ input.open();
+ return input.getNumWords();
+ } finally {
+ input.close();
+ }
+ }
+ /**
+ * Returns the path corresponding to a given document number
+ */
+ public String getPath(int documentNumber) throws IOException {
+ //save();
+ IndexInput input= new BlocksIndexInput(indexFile);
+ try {
+ input.open();
+ IndexedFile file = input.getIndexedFile(documentNumber);
+ if (file == null) return null;
+ return file.getPath();
+ } finally {
+ input.close();
+ }
+ }
+ /**
+ * see IIndex.hasChanged
+ */
+ public boolean hasChanged() {
+ return canMerge();
+ }
+ /**
+ * Initialises the indexGenerator.
+ */
+ public void initialize(boolean reuseExistingFile) throws IOException {
+ //initialisation of addsIndex
+ addsIndex= new InMemoryIndex();
+ addsIndexInput= new SimpleIndexInput(addsIndex);
+
+ //vectors who keep track of the removed Files
+ removedInAdds= new HashMap(11);
+ removedInOld= new HashMap(11);
+
+ // check whether existing index file can be read
+ if (reuseExistingFile && indexFile.exists()) {
+ IndexInput mainIndexInput= new BlocksIndexInput(indexFile);
+ try {
+ mainIndexInput.open();
+ } catch(IOException e) {
+ BlocksIndexInput input = (BlocksIndexInput)mainIndexInput;
+ try {
+ input.opened = true;
+ input.close();
+ } finally {
+ input.opened = false;
+ }
+ indexFile.delete();
+ mainIndexInput = null;
+ throw e;
+ }
+ mainIndexInput.close();
+ } else {
+ InMemoryIndex mainIndex= new InMemoryIndex();
+ IndexOutput mainIndexOutput= new BlocksIndexOutput(indexFile);
+ mainIndex.save(mainIndexOutput);
+ }
+ }
+ /**
+ * Merges the in memory index and the index on the disk, and saves the results on the disk.
+ */
+ protected void merge() throws IOException {
+ //initialisation of tempIndex
+ File tempFile= new File(indexFile.getAbsolutePath() + "TempVA"); //$NON-NLS-1$
+
+ IndexInput mainIndexInput= new BlocksIndexInput(indexFile);
+ BlocksIndexOutput tempIndexOutput= new BlocksIndexOutput(tempFile);
+
+ try {
+ //invoke a mergeFactory
+ new MergeFactory(
+ mainIndexInput,
+ addsIndexInput,
+ tempIndexOutput,
+ removedInOld,
+ removedInAdds).merge();
+
+ //rename the file created to become the main index
+ File mainIndexFile= (File) mainIndexInput.getSource();
+ File tempIndexFile= (File) tempIndexOutput.getDestination();
+ mainIndexFile.delete();
+ tempIndexFile.renameTo(mainIndexFile);
+ } finally {
+ //initialise remove vectors and addsindex, and change the state
+ removedInAdds.clear();
+ removedInOld.clear();
+ addsIndex.init();
+ addsIndexInput= new SimpleIndexInput(addsIndex);
+ state= MERGED;
+ }
+ }
+ /**
+ * @see IIndex#query
+ */
+ public IQueryResult[] query(String word) throws IOException {
+ //save();
+ IndexInput input= new BlocksIndexInput(indexFile);
+ try {
+ return input.query(word);
+ } finally {
+ input.close();
+ }
+ }
+ public IEntryResult[] queryEntries(char[] prefix) throws IOException {
+ //save();
+ IndexInput input= new BlocksIndexInput(indexFile);
+ try {
+ return input.queryEntriesPrefixedBy(prefix);
+ } finally {
+ input.close();
+ }
+ }
+ /**
+ * @see IIndex#queryInDocumentNames
+ */
+ public IQueryResult[] queryInDocumentNames(String word) throws IOException {
+ //save();
+ IndexInput input= new BlocksIndexInput(indexFile);
+ try {
+ return input.queryInDocumentNames(word);
+ } finally {
+ input.close();
+ }
+ }
+ /**
+ * @see IIndex#queryPrefix
+ */
+ public IQueryResult[] queryPrefix(char[] prefix) throws IOException {
+ //save();
+ IndexInput input= new BlocksIndexInput(indexFile);
+ try {
+ return input.queryFilesReferringToPrefix(prefix);
+ } finally {
+ input.close();
+ }
+ }
+ /**
+ * @see IIndex#remove
+ */
+ public void remove(String documentName) throws IOException {
+ IndexedFile file= addsIndex.getIndexedFile(documentName);
+ if (file != null) {
+ //the file is in the adds Index, we remove it from this one
+ Int lastRemoved= (Int) removedInAdds.get(documentName);
+ if (lastRemoved != null) {
+ int fileNum= file.getFileNumber();
+ if (lastRemoved.value < fileNum)
+ lastRemoved.value= fileNum;
+ } else
+ removedInAdds.put(documentName, new Int(file.getFileNumber()));
+ } else {
+ //we remove the file from the old index
+ removedInOld.put(documentName, new Int(1));
+ }
+ state= CAN_MERGE;
+ }
+ /**
+ * Removes the given document from the given index (MergeFactory.ADDS_INDEX for the
+ * in memory index, MergeFactory.OLD_INDEX for the index on the disk).
+ */
+ protected void remove(IndexedFile file, int index) throws IOException {
+ String name= file.getPath();
+ if (index == MergeFactory.ADDS_INDEX) {
+ Int lastRemoved= (Int) removedInAdds.get(name);
+ if (lastRemoved != null) {
+ if (lastRemoved.value < file.getFileNumber())
+ lastRemoved.value= file.getFileNumber();
+ } else
+ removedInAdds.put(name, new Int(file.getFileNumber()));
+ } else if (index == MergeFactory.OLD_INDEX)
+ removedInOld.put(name, new Int(1));
+ else
+ throw new Error();
+ state= CAN_MERGE;
+ }
+ /**
+ * @see IIndex#save
+ */
+ public void save() throws IOException {
+ if (canMerge())
+ merge();
+ }
+ /**
+ * Returns true if the in memory index reaches a critical size,
+ * to merge it with the index on the disk.
+ */
+ protected boolean timeToMerge() {
+ return (addsIndex.getFootprint() >= MAX_FOOTPRINT);
+ }
+ public String toString() {
+ String str = this.toString;
+ if (str == null) str = super.toString();
+ str += "(length: "+ getIndexFile().length() +")"; //$NON-NLS-1$ //$NON-NLS-2$
+ return str;
+}
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexBlock.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexBlock.java
new file mode 100644
index 00000000000..440720dc393
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexBlock.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import org.eclipse.cdt.internal.core.search.CharOperation;
+
+/**
+ * An indexBlock stores wordEntries.
+ */
+public abstract class IndexBlock extends Block {
+
+ public IndexBlock(int blockSize) {
+ super(blockSize);
+ }
+ /**
+ * Adds the given wordEntry to the indexBlock.
+ */
+ public abstract boolean addEntry(WordEntry entry);
+ /**
+ * @see Block#clear()
+ */
+ public void clear() {
+ reset();
+ super.clear();
+ }
+ public WordEntry findEntryMatching(char[] pattern, boolean isCaseSensitive) {
+ reset();
+ WordEntry entry= new WordEntry();
+ while (nextEntry(entry)) {
+ if (CharOperation.match(pattern, entry.getWord(), isCaseSensitive)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+ public WordEntry findEntryPrefixedBy(char[] word, boolean isCaseSensitive) {
+ reset();
+ WordEntry entry= new WordEntry();
+ while (nextEntry(entry)) {
+ if (CharOperation.prefixEquals(entry.getWord(), word, isCaseSensitive)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+ public WordEntry findExactEntry(char[] word) {
+ reset();
+ WordEntry entry= new WordEntry();
+ while (nextEntry(entry)) {
+ if (CharOperation.equals(entry.getWord(), word)) {
+ return entry;
+ }
+ }
+ return null;
+ }
+ /**
+ * Returns whether the block is empty or not (if it doesn't contain any wordEntry).
+ */
+ public abstract boolean isEmpty();
+ /**
+ * Finds the next wordEntry and stores it in the given entry.
+ */
+ public abstract boolean nextEntry(WordEntry entry);
+ public void reset() {
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexInput.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexInput.java
new file mode 100644
index 00000000000..9acf65294e3
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexInput.java
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+import org.eclipse.cdt.internal.core.index.IDocument;
+import org.eclipse.cdt.internal.core.index.IEntryResult;
+import org.eclipse.cdt.internal.core.index.IQueryResult;
+
+
+/**
+ * This class provides an input on an index, after it has been generated.
+ * You can access all the files of an index via getNextFile(), getCurrentFile()
+ * and moveToNextFile() (idem for the word entries).
+ * The usage is the same for every subclass: creation (constructor), opening
+ * (the open() method), usage, and closing (the close() method), to release the
+ * data source used by this input.
+ */
+public abstract class IndexInput {
+ protected int filePosition;
+ protected WordEntry currentWordEntry;
+ protected int wordPosition;
+
+
+ public IndexInput() {
+ super();
+ wordPosition= 1;
+ filePosition= 1;
+ }
+ /**
+ * clears the cache of this indexInput, if it keeps track of the information already read.
+ */
+ public abstract void clearCache();
+ /**
+ * Closes the IndexInput. For example, if the input is on a RandomAccessFile,
+ * it calls the close() method of RandomAccessFile.
+ */
+ public abstract void close() throws IOException;
+ /**
+ * Returns the current file the indexInput is pointing to in the index.
+ */
+ public abstract IndexedFile getCurrentFile() throws IOException;
+ /**
+ * Returns the current file the indexInput is pointing to in the index.
+ */
+ public WordEntry getCurrentWordEntry() throws IOException {
+ if (!hasMoreWords())
+ return null;
+ return currentWordEntry;
+ }
+ /**
+ * Returns the position of the current file the input is pointing to in the index.
+ */
+ public int getFilePosition() {
+ return filePosition;
+ }
+ /**
+ * Returns the indexedFile corresponding to the given document number in the index the input
+ * reads in, or null if such indexedFile does not exist.
+ */
+ public abstract IndexedFile getIndexedFile(int fileNum) throws IOException;
+ /**
+ * Returns the indexedFile corresponding to the given document in the index the input
+ * reads in (e.g. the indexedFile with the same path in this index), or null if such
+ * indexedFile does not exist.
+ */
+ public abstract IndexedFile getIndexedFile(IDocument document) throws IOException;
+ /**
+ * Returns the number of files in the index.
+ */
+ public abstract int getNumFiles();
+ /**
+ * Returns the number of unique words in the index.
+ */
+ public abstract int getNumWords();
+ /**
+ * Returns the Object the input is reading from. It can be an IIndex,
+ * a File, ...
+ */
+ public abstract Object getSource();
+ /**
+ * Returns true if the input has not reached the end of the index for the files.
+ */
+ public boolean hasMoreFiles() {
+ return getFilePosition() <= getNumFiles();
+ }
+ /**
+ * Returns true if the input has not reached the end of the index for the files.
+ */
+ public boolean hasMoreWords() {
+ return wordPosition <= getNumWords();
+ }
+ /**
+ * Moves the pointer on the current file to the next file in the index.
+ */
+ public abstract void moveToNextFile() throws IOException;
+ /**
+ * Moves the pointer on the current word to the next file in the index.
+ */
+ public abstract void moveToNextWordEntry() throws IOException;
+ /**
+ * Open the Source where the input gets the information from.
+ */
+ public abstract void open() throws IOException;
+ /**
+ * Returns the list of the files containing the given word in the index.
+ */
+ public abstract IQueryResult[] query(String word) throws IOException;
+ public abstract IEntryResult[] queryEntriesPrefixedBy(char[] prefix) throws IOException;
+ public abstract IQueryResult[] queryFilesReferringToPrefix(char[] prefix) throws IOException;
+ /**
+ * Returns the list of the files whose name contain the given word in the index.
+ */
+ public abstract IQueryResult[] queryInDocumentNames(String word) throws IOException;
+ /**
+ * Set the pointer on the current file to the first file of the index.
+ */
+ protected abstract void setFirstFile() throws IOException;
+ /**
+ * Set the pointer on the current word to the first word of the index.
+ */
+ protected abstract void setFirstWord() throws IOException;
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexOutput.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexOutput.java
new file mode 100644
index 00000000000..5d7d78c7021
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexOutput.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+
+/**
+ * An indexOutput is used to write an index into a different object (a File, ...).
+ */
+public abstract class IndexOutput {
+ /**
+ * Adds a File to the destination.
+ */
+ public abstract void addFile(IndexedFile file) throws IOException;
+ /**
+ * Adds a word to the destination.
+ */
+ public abstract void addWord(WordEntry word) throws IOException;
+ /**
+ * Closes the output, releasing the resources it was using.
+ */
+ public abstract void close() throws IOException;
+ /**
+ * Flushes the output.
+ */
+ public abstract void flush() throws IOException;
+ /**
+ * Returns the Object the output is writing to. It can be a file, another type of index, ...
+ */
+ public abstract Object getDestination();
+ /**
+ * Opens the output, before writing any information.
+ */
+ public abstract void open() throws IOException;
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexSummary.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexSummary.java
new file mode 100644
index 00000000000..fbd810af93a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexSummary.java
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+
+import org.eclipse.cdt.internal.core.search.CharOperation;
+
+/**
+ * An indexSummary is used when saving an index into a BlocksIndexOuput or
+ * reading it from a BlocksIndexInput. It contains basic informations about
+ * an index: first files/words in each block, number of files/words.
+ */
+
+public class IndexSummary {
+ /**
+ * First file for each block.
+ */
+ protected ArrayList firstFilesInBlocks= new ArrayList();
+ /**
+ * First word for each block.
+ */
+ protected ArrayList firstWordsInBlocks= new ArrayList();
+ /**
+ * Number of files in the index.
+ */
+ protected int numFiles;
+ /**
+ * Number of words in the index.
+ */
+ protected int numWords;
+
+ static class FirstFileInBlock {
+ IndexedFile indexedFile;
+ int blockNum;
+ }
+
+ static class FirstWordInBlock {
+ char[] word;
+ int blockNum;
+ public String toString(){
+ return "FirstWordInBlock: " + new String(word) + ", blockNum: " + blockNum; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ protected int firstWordBlockNum;
+ protected boolean firstWordAdded= true;
+ /**
+ * Adds the given file as the first file for the given Block number.
+ */
+ public void addFirstFileInBlock(IndexedFile indexedFile, int blockNum) {
+ FirstFileInBlock entry= new FirstFileInBlock();
+ entry.indexedFile= indexedFile;
+ entry.blockNum= blockNum;
+ firstFilesInBlocks.add(entry);
+ }
+ /**
+ * Adds the given word as the first word for the given Block number.
+ */
+ public void addFirstWordInBlock(char[] word, int blockNum) {
+ if (firstWordAdded) {
+ firstWordBlockNum= blockNum;
+ firstWordAdded= false;
+ }
+ FirstWordInBlock entry= new FirstWordInBlock();
+ entry.word= word;
+ entry.blockNum= blockNum;
+ firstWordsInBlocks.add(entry);
+ }
+ /**
+ * Returns the numbers of all the blocks
+ */
+ public int[] getAllBlockNums() {
+
+ int max = firstWordsInBlocks.size();
+ int[] blockNums = new int[max];
+ for (int i = 0; i < max; i++){
+ blockNums[i] = ((FirstWordInBlock)firstWordsInBlocks.get(i)).blockNum;
+ }
+ return blockNums;
+ }
+ public int getBlockNum(int blockLocation) {
+ return ((FirstWordInBlock) firstWordsInBlocks.get(blockLocation)).blockNum;
+ }
+ /**
+ * Returns the number of the Block containing the file with the given number.
+ */
+ public int getBlockNumForFileNum(int fileNum) {
+ int min= 0;
+ int max= firstFilesInBlocks.size() - 1;
+ while (min <= max) {
+ int mid= (min + max) / 2;
+ FirstFileInBlock entry= (FirstFileInBlock) firstFilesInBlocks.get(mid);
+ int compare= fileNum - entry.indexedFile.getFileNumber();
+ if (compare == 0)
+ return entry.blockNum;
+ if (compare < 0)
+ max= mid - 1;
+ else
+ min= mid + 1;
+ }
+ if (max < 0)
+ return -1;
+ FirstFileInBlock entry= (FirstFileInBlock) firstFilesInBlocks.get(max);
+ return entry.blockNum;
+ }
+ /**
+ * Returns the number of the Block containing the given word.
+ */
+ public int getBlockNumForWord(char[] word) {
+ int min= 0;
+ int max= firstWordsInBlocks.size() - 1;
+ while (min <= max) {
+ int mid= (min + max) / 2;
+ FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(mid);
+ int compare= Util.compare(word, entry.word);
+ if (compare == 0)
+ return entry.blockNum;
+ if (compare < 0)
+ max= mid - 1;
+ else
+ min= mid + 1;
+ }
+ if (max < 0)
+ return -1;
+ FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(max);
+ return entry.blockNum;
+ }
+ public int[] getBlockNumsForPrefix(char[] prefix) {
+ int min= 0;
+ int size= firstWordsInBlocks.size();
+ int max= size - 1;
+ int match= -1;
+ while (min <= max && match < 0) {
+ int mid= (min + max) / 2;
+ FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(mid);
+ int compare= CharOperation.compareWith(entry.word, prefix);
+ if (compare == 0) {
+ match= mid;
+ break;
+ }
+ if (compare >= 0)
+ max= mid - 1;
+ else
+ min= mid + 1;
+ }
+ if (max < 0)
+ return new int[0];
+
+ if (match < 0)
+ match= max;
+
+ int firstBlock= match - 1;
+ // Look if previous blocks are affected
+ for (; firstBlock >= 0; firstBlock--) {
+ FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(firstBlock);
+ if (!CharOperation.prefixEquals(prefix, entry.word))
+ break;
+ }
+ if (firstBlock < 0)
+ firstBlock= 0;
+
+ // Look if next blocks are affected
+ int firstNotIncludedBlock= match + 1;
+ for (; firstNotIncludedBlock < size; firstNotIncludedBlock++) {
+ FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(firstNotIncludedBlock);
+ if (!CharOperation.prefixEquals(prefix, entry.word))
+ break;
+ }
+
+ int numberOfBlocks= firstNotIncludedBlock - firstBlock;
+ int[] result= new int[numberOfBlocks];
+ int pos= firstBlock;
+ for (int i= 0; i < numberOfBlocks; i++, pos++) {
+ FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(pos);
+ result[i]= entry.blockNum;
+ }
+ return result;
+ }
+ public int getFirstBlockLocationForPrefix(char[] prefix) {
+ int min = 0;
+ int size = firstWordsInBlocks.size();
+ int max = size - 1;
+ int match = -1;
+ while (min <= max) {
+ int mid = (min + max) / 2;
+ FirstWordInBlock entry = (FirstWordInBlock) firstWordsInBlocks.get(mid);
+ int compare = CharOperation.compareWith(entry.word, prefix);
+ if (compare == 0) {
+ match = mid;
+ break;
+ }
+ if (compare >= 0) {
+ max = mid - 1;
+ } else {
+ match = mid; // not perfect match, but could be inside
+ min = mid + 1;
+ }
+ }
+ if (max < 0) return -1;
+
+ // no match at all, might be some matching entries inside max block
+ if (match < 0){
+ match = max;
+ } else {
+ // look for possible matches inside previous blocks
+ while (match > 0){
+ FirstWordInBlock entry = (FirstWordInBlock) firstWordsInBlocks.get(match);
+ if (!CharOperation.prefixEquals(prefix, entry.word))
+ break;
+ match--;
+ }
+ }
+ return match;
+ }
+ /**
+ * Returns the number of the first IndexBlock (containing words).
+ */
+ public int getFirstWordBlockNum() {
+ return firstWordBlockNum;
+ }
+ /**
+ * Blocks are contiguous, so the next one is a potential candidate if its first word starts with
+ * the given prefix
+ */
+ public int getNextBlockLocationForPrefix(char[] prefix, int blockLoc) {
+ if (++blockLoc < firstWordsInBlocks.size()){
+ FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(blockLoc);
+ if (CharOperation.prefixEquals(prefix, entry.word)) return blockLoc;
+ }
+ return -1;
+ }
+ /**
+ * Returns the number of files contained in the index.
+ */
+ public int getNumFiles() {
+ return numFiles;
+ }
+ /**
+ * Returns the number of words contained in the index.
+ */
+ public int getNumWords() {
+ return numWords;
+ }
+ /**
+ * Loads the summary in memory.
+ */
+ public void read(RandomAccessFile raf) throws IOException {
+ numFiles= raf.readInt();
+ numWords= raf.readInt();
+ firstWordBlockNum= raf.readInt();
+ int numFirstFiles= raf.readInt();
+ for (int i= 0; i < numFirstFiles; ++i) {
+ FirstFileInBlock entry= new FirstFileInBlock();
+ String path= raf.readUTF();
+ int fileNum= raf.readInt();
+ entry.indexedFile= new IndexedFile(path, fileNum);
+ entry.blockNum= raf.readInt();
+ firstFilesInBlocks.add(entry);
+ }
+ int numFirstWords= raf.readInt();
+ for (int i= 0; i < numFirstWords; ++i) {
+ FirstWordInBlock entry= new FirstWordInBlock();
+ entry.word= raf.readUTF().toCharArray();
+ entry.blockNum= raf.readInt();
+ firstWordsInBlocks.add(entry);
+ }
+ }
+ /**
+ * Sets the number of files of the index.
+ */
+
+ public void setNumFiles(int numFiles) {
+ this.numFiles= numFiles;
+ }
+ /**
+ * Sets the number of words of the index.
+ */
+
+ public void setNumWords(int numWords) {
+ this.numWords= numWords;
+ }
+ /**
+ * Saves the summary on the disk.
+ */
+ public void write(RandomAccessFile raf) throws IOException {
+ raf.writeInt(numFiles);
+ raf.writeInt(numWords);
+ raf.writeInt(firstWordBlockNum);
+ raf.writeInt(firstFilesInBlocks.size());
+ for (int i= 0, size= firstFilesInBlocks.size(); i < size; ++i) {
+ FirstFileInBlock entry= (FirstFileInBlock) firstFilesInBlocks.get(i);
+ raf.writeUTF(entry.indexedFile.getPath());
+ raf.writeInt(entry.indexedFile.getFileNumber());
+ raf.writeInt(entry.blockNum);
+ }
+ raf.writeInt(firstWordsInBlocks.size());
+ for (int i= 0, size= firstWordsInBlocks.size(); i < size; ++i) {
+ FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(i);
+ raf.writeUTF(new String(entry.word));
+ raf.writeInt(entry.blockNum);
+ }
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexedFile.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexedFile.java
new file mode 100644
index 00000000000..037e5a04140
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexedFile.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import org.eclipse.cdt.internal.core.index.IQueryResult;
+import org.eclipse.cdt.internal.core.index.IDocument;
+
+/**
+ * An indexedFile associates a number to a document path, and document properties.
+ * It is what we add into an index, and the result of a query.
+ */
+
+public class IndexedFile implements IQueryResult {
+ protected String path;
+ protected int fileNumber;
+
+ public IndexedFile(String path, int fileNum) {
+ if (fileNum < 1)
+ throw new IllegalArgumentException();
+ this.fileNumber= fileNum;
+ this.path= path;
+ }
+ public IndexedFile(IDocument document, int fileNum) {
+ if (fileNum < 1)
+ throw new IllegalArgumentException();
+ this.path= document.getName();
+ this.fileNumber= fileNum;
+ }
+ /**
+ * Returns the size of the indexedFile.
+ */
+ public int footprint() {
+ //object+ 2 slots + size of the string (header + 4 slots + char[])
+ return 8 + (2 * 4) + (8 + (4 * 4) + 8 + path.length() * 2);
+ }
+ /**
+ * Returns the file number.
+ */
+ public int getFileNumber() {
+ return fileNumber;
+ }
+ /**
+ * Returns the path.
+ */
+ public String getPath() {
+ return path;
+ }
+ /**
+ * Sets the file number.
+ */
+ public void setFileNumber(int fileNumber) {
+ this.fileNumber= fileNumber;
+ }
+ public String toString() {
+ return "IndexedFile(" + fileNumber + ": " + path + ")"; //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-3$
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexedFileHashedArray.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexedFileHashedArray.java
new file mode 100644
index 00000000000..e40e80c51bf
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexedFileHashedArray.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.util.ArrayList;
+
+import org.eclipse.cdt.internal.core.index.IDocument;
+
+public final class IndexedFileHashedArray {
+
+private IndexedFile elements[];
+private int elementSize; // number of elements in the table
+private int threshold;
+private int lastId;
+private ArrayList replacedElements;
+
+public IndexedFileHashedArray(int size) {
+ if (size < 7) size = 7;
+ this.elements = new IndexedFile[2 * size + 1];
+ this.elementSize = 0;
+ this.threshold = size + 1; // size is the expected number of elements
+ this.lastId = 0;
+ this.replacedElements = null;
+}
+
+public IndexedFile add(IDocument document) {
+ return add(new IndexedFile(document, ++lastId));
+}
+
+private IndexedFile add(IndexedFile file) {
+ int length = elements.length;
+ String path = file.getPath();
+ int index = (path.hashCode() & 0x7FFFFFFF) % length;
+ IndexedFile current;
+ while ((current = elements[index]) != null) {
+ if (current.getPath().equals(path)) {
+ if (replacedElements == null) replacedElements = new ArrayList(5);
+ replacedElements.add(current);
+ return elements[index] = file;
+ }
+ if (++index == length) index = 0;
+ }
+ elements[index] = file;
+
+ // assumes the threshold is never equal to the size of the table
+ if (++elementSize > threshold) grow();
+ return file;
+}
+
+public IndexedFile[] asArray() {
+ IndexedFile[] array = new IndexedFile[lastId];
+ for (int i = 0, length = elements.length; i < length; i++) {
+ IndexedFile current = elements[i];
+ if (current != null)
+ array[current.fileNumber - 1] = current;
+ }
+ if (replacedElements != null) {
+ for (int i = 0, length = replacedElements.size(); i < length; i++) {
+ IndexedFile current = (IndexedFile) replacedElements.get(i);
+ array[current.fileNumber - 1] = current;
+ }
+ }
+ return array;
+}
+
+public IndexedFile get(String path) {
+ int length = elements.length;
+ int index = (path.hashCode() & 0x7FFFFFFF) % length;
+ IndexedFile current;
+ while ((current = elements[index]) != null) {
+ if (current.getPath().equals(path)) return current;
+ if (++index == length) index = 0;
+ }
+ return null;
+}
+
+private void grow() {
+ IndexedFileHashedArray newArray = new IndexedFileHashedArray(elementSize * 2); // double the number of expected elements
+ for (int i = 0, length = elements.length; i < length; i++)
+ if (elements[i] != null)
+ newArray.add(elements[i]);
+
+ // leave replacedElements as is
+ this.elements = newArray.elements;
+ this.elementSize = newArray.elementSize;
+ this.threshold = newArray.threshold;
+}
+
+public int size() {
+ return elementSize + (replacedElements == null ? 0 : replacedElements.size());
+}
+
+public String toString() {
+ String s = ""; //$NON-NLS-1$
+ IndexedFile[] files = asArray();
+ for (int i = 0, length = files.length; i < length; i++)
+ s += files[i].toString() + "\n"; //$NON-NLS-1$
+ return s;
+}
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexerOutput.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexerOutput.java
new file mode 100644
index 00000000000..4e2eb020049
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/IndexerOutput.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import org.eclipse.cdt.internal.core.index.IIndexerOutput;
+import org.eclipse.cdt.internal.core.index.IDocument;
+
+/**
+ * An indexerOutput is used by an indexer to add documents and word references to
+ * an inMemoryIndex. It keeps track of the document being indexed and add the
+ * word references to this document (so you do not need to precise the document
+ * each time you add a word).
+ */
+
+public class IndexerOutput implements IIndexerOutput {
+ protected InMemoryIndex index;
+ protected IndexedFile indexedFile;
+ protected IDocument document;
+ /**
+ * IndexerOutput constructor comment.
+ */
+ public IndexerOutput(InMemoryIndex index) {
+ this.index= index;
+ }
+ /**
+ * Adds the given document to the inMemoryIndex.
+ */
+ public void addDocument(IDocument document) {
+ if (indexedFile == null) {
+ indexedFile= index.addDocument(document);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+ /**
+ * Adds a reference to the given word to the inMemoryIndex.
+ */
+ public void addRef(char[] word) {
+ if (indexedFile == null) {
+ throw new IllegalStateException();
+ }
+ index.addRef(indexedFile, word);
+ }
+ /**
+ * Adds a reference to the given word to the inMemoryIndex.
+ */
+ public void addRef(String word) {
+ addRef(word.toCharArray());
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Int.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Int.java
new file mode 100644
index 00000000000..a57b2db21b5
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Int.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+public class Int {
+ public int value;
+ /**
+ * Int constructor comment.
+ */
+ public Int(int i) {
+ value= i;
+ }
+}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/MergeFactory.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/MergeFactory.java
new file mode 100644
index 00000000000..bf7b2a3c110
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/MergeFactory.java
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * A mergeFactory is used to merge 2 indexes into one. One of the indexes
+ * (oldIndex) is on the disk and the other(addsIndex) is in memory.
+ * The merge respects the following rules:
+ * - The files are sorted in alphabetical order;
+ * - if a file is in oldIndex and addsIndex, the one which is added
+ * is the one in the addsIndex.
+ */
+public class MergeFactory {
+ /**
+ * Input on the addsIndex.
+ */
+ protected IndexInput addsInput;
+ /**
+ * Input on the oldIndex.
+ */
+ protected IndexInput oldInput;
+ /**
+ * Output to write the result of the merge in.
+ */
+ protected BlocksIndexOutput mergeOutput;
+ /**
+ * Files removed from oldIndex.
+ */
+ protected Map removedInOld;
+ /**
+ * Files removed from addsIndex.
+ */
+ protected Map removedInAdds;
+ protected int[] mappingOld;
+ protected int[] mappingAdds;
+ public static final int ADDS_INDEX= 0;
+ public static final int OLD_INDEX= 1;
+ /**
+ * MergeFactory constructor comment.
+ * @param directory java.io.File
+ */
+ public MergeFactory(IndexInput oldIndexInput, IndexInput addsIndexInput, BlocksIndexOutput mergeIndexOutput, Map removedInOld, Map removedInAdds) {
+ oldInput= oldIndexInput;
+ addsInput= addsIndexInput;
+ mergeOutput= mergeIndexOutput;
+ this.removedInOld= removedInOld;
+ this.removedInAdds= removedInAdds;
+ }
+ /**
+ * Initialise the merge.
+ */
+ protected void init() {
+ mappingOld= new int[oldInput.getNumFiles() + 1];
+ mappingAdds= new int[addsInput.getNumFiles() + 1];
+
+ }
+ /**
+ * Merges the 2 indexes into a new one on the disk.
+ */
+ public void merge() throws IOException {
+ try {
+ //init
+ addsInput.open();
+ oldInput.open();
+ mergeOutput.open();
+ init();
+ //merge
+ //findChanges();
+ mergeFiles();
+ mergeReferences();
+ mergeOutput.flush();
+ } finally {
+ //closes everything
+ oldInput.close();
+ addsInput.close();
+ mergeOutput.close();
+ }
+ }
+ /**
+ * Merges the files of the 2 indexes in the new index, removes the files
+ * to be removed, and records the changes made to propagate them to the
+ * word references.
+ */
+
+ protected void mergeFiles() throws IOException {
+ int positionInMerge= 1;
+ int compare;
+ while (oldInput.hasMoreFiles() || addsInput.hasMoreFiles()) {
+ IndexedFile file1= oldInput.getCurrentFile();
+ IndexedFile file2= addsInput.getCurrentFile();
+
+ //if the file has been removed we don't take it into account
+ while (file1 != null && wasRemoved(file1, OLD_INDEX)) {
+ oldInput.moveToNextFile();
+ file1= oldInput.getCurrentFile();
+ }
+ while (file2 != null && wasRemoved(file2, ADDS_INDEX)) {
+ addsInput.moveToNextFile();
+ file2= addsInput.getCurrentFile();
+ }
+
+ //the addsIndex was empty, we just removed files from the oldIndex
+ if (file1 == null && file2 == null)
+ break;
+
+ //test if we reached the end of one the 2 index
+ if (file1 == null)
+ compare= 1;
+ else if (file2 == null)
+ compare= -1;
+ else
+ compare= file1.getPath().compareTo(file2.getPath());
+
+ //records the changes to Make
+ if (compare == 0) {
+ //the file has been modified:
+ //we remove it from the oldIndex and add it to the addsIndex
+ removeFile(file1, OLD_INDEX);
+ mappingAdds[file2.getFileNumber()]= positionInMerge;
+ file1.setFileNumber(positionInMerge);
+ mergeOutput.addFile(file1);
+ oldInput.moveToNextFile();
+ addsInput.moveToNextFile();
+ } else if (compare < 0) {
+ mappingOld[file1.getFileNumber()]= positionInMerge;
+ file1.setFileNumber(positionInMerge);
+ mergeOutput.addFile(file1);
+ oldInput.moveToNextFile();
+ } else {
+ mappingAdds[file2.getFileNumber()]= positionInMerge;
+ file2.setFileNumber(positionInMerge);
+ mergeOutput.addFile(file2);
+ addsInput.moveToNextFile();
+ }
+ positionInMerge++;
+ }
+ mergeOutput.flushFiles();
+ }
+ /**
+ * Merges the files of the 2 indexes in the new index, according to the changes
+ * recorded during mergeFiles().
+ */
+ protected void mergeReferences() throws IOException {
+ int compare;
+ while (oldInput.hasMoreWords() || addsInput.hasMoreWords()) {
+ WordEntry word1= oldInput.getCurrentWordEntry();
+ WordEntry word2= addsInput.getCurrentWordEntry();
+
+ if (word1 == null && word2 == null)
+ break;
+
+ if (word1 == null)
+ compare= 1;
+ else if (word2 == null)
+ compare= -1;
+ else
+ compare= Util.compare(word1.getWord(), word2.getWord());
+ if (compare < 0) {
+ word1.mapRefs(mappingOld);
+ mergeOutput.addWord(word1);
+ oldInput.moveToNextWordEntry();
+ } else if (compare > 0) {
+ word2.mapRefs(mappingAdds);
+ mergeOutput.addWord(word2);
+ addsInput.moveToNextWordEntry();
+ } else {
+ word1.mapRefs(mappingOld);
+ word2.mapRefs(mappingAdds);
+ word1.addRefs(word2.getRefs());
+ mergeOutput.addWord(word1);
+ addsInput.moveToNextWordEntry();
+ oldInput.moveToNextWordEntry();
+ }
+ }
+ mergeOutput.flushWords();
+ }
+ /**
+ * Records the deletion of one file.
+ */
+ protected void removeFile(IndexedFile file, int index) {
+ if (index == OLD_INDEX)
+ mappingOld[file.getFileNumber()]= -1;
+ else
+ mappingAdds[file.getFileNumber()]= -1;
+ }
+ /**
+ * Returns whether the given file has to be removed from the given index
+ * (ADDS_INDEX or OLD_INDEX). If it has to be removed, the mergeFactory
+ * deletes it and records the changes.
+ */
+
+ protected boolean wasRemoved(IndexedFile indexedFile, int index) {
+ String path= indexedFile.getPath();
+ if (index == OLD_INDEX) {
+ if (removedInOld.remove(path) != null) {
+ mappingOld[indexedFile.getFileNumber()]= -1;
+ return true;
+ }
+ } else if (index == ADDS_INDEX) {
+ Int lastRemoved= (Int) removedInAdds.get(path);
+ if (lastRemoved != null) {
+ int fileNum= indexedFile.getFileNumber();
+ if (lastRemoved.value >= fileNum) {
+ mappingAdds[fileNum]= -1;
+ //if (lastRemoved.value == fileNum) // ONLY if files in sorted order for names AND fileNums
+ //removedInAdds.remove(path);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/PropertyDocument.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/PropertyDocument.java
new file mode 100644
index 00000000000..45ba60960f6
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/PropertyDocument.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import org.eclipse.cdt.internal.core.index.IDocument;
+
+/**
+ * The properties of a document are stored into a hashtable.
+ * @see IDocument
+ */
+
+public abstract class PropertyDocument implements IDocument {
+ protected Hashtable properties;
+ public PropertyDocument() {
+ properties= new Hashtable(5);
+ }
+ /**
+ * @see IDocument#getProperty
+ */
+ public String getProperty(String property) {
+ return (String) properties.get(property);
+ }
+ /**
+ * @see IDocument#getPropertyNames
+ */
+
+ public Enumeration getPropertyNames() {
+ return properties.keys();
+ }
+ /**
+ * @see IDocument#setProperty
+ */
+
+ public void setProperty(String property, String value) {
+ properties.put(property, value);
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/SafeRandomAccessFile.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/SafeRandomAccessFile.java
new file mode 100644
index 00000000000..28a4b5bbfe2
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/SafeRandomAccessFile.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/**
+ * A safe subclass of RandomAccessFile, which ensure that it's closed
+ * on finalize.
+ */
+public class SafeRandomAccessFile extends RandomAccessFile {
+ public SafeRandomAccessFile(java.io.File file, String mode) throws java.io.IOException {
+ super(file, mode);
+ }
+ public SafeRandomAccessFile(String name, String mode) throws java.io.IOException {
+ super(name, mode);
+ }
+ protected void finalize() throws IOException {
+ close();
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/SimpleIndexInput.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/SimpleIndexInput.java
new file mode 100644
index 00000000000..0a375d3e30a
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/SimpleIndexInput.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import org.eclipse.cdt.internal.core.index.IDocument;
+import org.eclipse.cdt.internal.core.index.IEntryResult;
+import org.eclipse.cdt.internal.core.index.IQueryResult;
+
+/**
+ * A simpleIndexInput is an input on an in memory Index.
+ */
+
+public class SimpleIndexInput extends IndexInput {
+ protected WordEntry[] sortedWordEntries;
+ protected IndexedFile currentFile;
+ protected IndexedFile[] sortedFiles;
+ protected InMemoryIndex index;
+
+ public SimpleIndexInput(InMemoryIndex index) {
+ super();
+ this.index= index;
+ }
+ /**
+ * @see IndexInput#clearCache()
+ */
+ public void clearCache() {
+ }
+ /**
+ * @see IndexInput#close()
+ */
+ public void close() throws IOException {
+ sortedFiles= null;
+ }
+ /**
+ * @see IndexInput#getCurrentFile()
+ */
+ public IndexedFile getCurrentFile() throws IOException {
+ if (!hasMoreFiles())
+ return null;
+ return currentFile;
+ }
+ /**
+ * @see IndexInput#getIndexedFile(int)
+ */
+ public IndexedFile getIndexedFile(int fileNum) throws IOException {
+ for (int i= 0; i < sortedFiles.length; i++)
+ if (sortedFiles[i].getFileNumber() == fileNum)
+ return sortedFiles[i];
+ return null;
+ }
+ /**
+ * @see IndexInput#getIndexedFile(IDocument)
+ */
+ public IndexedFile getIndexedFile(IDocument document) throws IOException {
+ String name= document.getName();
+ for (int i= index.getNumFiles(); i >= 1; i--) {
+ IndexedFile file= getIndexedFile(i);
+ if (name.equals(file.getPath()))
+ return file;
+ }
+ return null;
+ }
+ /**
+ * @see IndexInput#getNumFiles()
+ */
+ public int getNumFiles() {
+ return index.getNumFiles();
+ }
+ /**
+ * @see IndexInput#getNumWords()
+ */
+ public int getNumWords() {
+ return sortedWordEntries.length;
+ }
+ /**
+ * @see IndexInput#getSource()
+ */
+ public Object getSource() {
+ return index;
+ }
+ public void init() {
+ index.init();
+
+ }
+ /**
+ * @see IndexInput#moveToNextFile()
+ */
+ public void moveToNextFile() throws IOException {
+ filePosition++;
+ if (!hasMoreFiles()) {
+ return;
+ }
+ currentFile= sortedFiles[filePosition - 1];
+ }
+ /**
+ * @see IndexInput#moveToNextWordEntry()
+ */
+ public void moveToNextWordEntry() throws IOException {
+ wordPosition++;
+ if (hasMoreWords())
+ currentWordEntry= sortedWordEntries[wordPosition - 1];
+ }
+ /**
+ * @see IndexInput#open()
+ */
+ public void open() throws IOException {
+ sortedWordEntries= index.getSortedWordEntries();
+ sortedFiles= index.getSortedFiles();
+ filePosition= 1;
+ wordPosition= 1;
+ setFirstFile();
+ setFirstWord();
+ }
+ /**
+ * @see IndexInput#query(String)
+ */
+ public IQueryResult[] query(String word) throws IOException {
+ char[] wordChar= word.toCharArray();
+ WordEntry wordEntry= index.getWordEntry(wordChar);
+ int[] fileNums= wordEntry.getRefs();
+ IQueryResult[] files= new IQueryResult[fileNums.length];
+ for (int i= 0; i < files.length; i++)
+ files[i]= getIndexedFile(fileNums[i]);
+ return files;
+ }
+ public IEntryResult[] queryEntriesPrefixedBy(char[] prefix) throws IOException {
+ return null;
+ }
+ public IQueryResult[] queryFilesReferringToPrefix(char[] prefix) throws IOException {
+ return null;
+ }
+ /**
+ * @see IndexInput#queryInDocumentNames(String)
+ */
+ public IQueryResult[] queryInDocumentNames(String word) throws IOException {
+ setFirstFile();
+ ArrayList matches= new ArrayList();
+ while (hasMoreFiles()) {
+ IndexedFile file= getCurrentFile();
+ if (file.getPath().indexOf(word) != -1)
+ matches.add(file.getPath());
+ moveToNextFile();
+ }
+ IQueryResult[] match= new IQueryResult[matches.size()];
+ matches.toArray(match);
+ return match;
+ }
+ /**
+ * @see IndexInput#setFirstFile()
+ */
+ protected void setFirstFile() throws IOException {
+ filePosition= 1;
+ if (sortedFiles.length > 0) {
+ currentFile= sortedFiles[0];
+ }
+ }
+ /**
+ * @see IndexInput#setFirstWord()
+ */
+ protected void setFirstWord() throws IOException {
+ wordPosition= 1;
+ if (sortedWordEntries.length > 0)
+ currentWordEntry= sortedWordEntries[0];
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Util.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Util.java
new file mode 100644
index 00000000000..4e4e5e89a63
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/Util.java
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UTFDataFormatException;
+
+public class Util {
+
+ private Util() {
+ }
+ /**
+ * Compares two strings lexicographically.
+ * The comparison is based on the Unicode value of each character in
+ * the strings.
+ *
+ * @return the value 0
if the str1 is equal to str2;
+ * a value less than 0
if str1
+ * is lexicographically less than str2;
+ * and a value greater than 0
if str1 is
+ * lexicographically greater than str2.
+ */
+ public static int compare(char[] str1, char[] str2) {
+ int len1= str1.length;
+ int len2= str2.length;
+ int n= Math.min(len1, len2);
+ int i= 0;
+ while (n-- != 0) {
+ char c1= str1[i];
+ char c2= str2[i++];
+ if (c1 != c2) {
+ return c1 - c2;
+ }
+ }
+ return len1 - len2;
+ }
+
+ /**
+ * Returns the length of the common prefix between s1 and s2.
+ */
+ public static int prefixLength(char[] s1, char[] s2) {
+ int len= 0;
+ int max= Math.min(s1.length, s2.length);
+ for (int i= 0; i < max && s1[i] == s2[i]; ++i)
+ ++len;
+ return len;
+ }
+ /**
+ * Returns the length of the common prefix between s1 and s2.
+ */
+ public static int prefixLength(String s1, String s2) {
+ int len= 0;
+ int max= Math.min(s1.length(), s2.length());
+ for (int i= 0; i < max && s1.charAt(i) == s2.charAt(i); ++i)
+ ++len;
+ return len;
+ }
+ private static void quickSort(char[][] list, int left, int right) {
+ int original_left= left;
+ int original_right= right;
+ char[] mid= list[(left + right) / 2];
+ do {
+ while (compare(list[left], mid) < 0) {
+ left++;
+ }
+ while (compare(mid, list[right]) < 0) {
+ right--;
+ }
+ if (left <= right) {
+ char[] tmp= list[left];
+ list[left]= list[right];
+ list[right]= tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(list, original_left, right);
+ }
+ if (left < original_right) {
+ quickSort(list, left, original_right);
+ }
+ }
+ private static void quickSort(int[] list, int left, int right) {
+ int original_left= left;
+ int original_right= right;
+ int mid= list[(left + right) / 2];
+ do {
+ while (list[left] < mid) {
+ left++;
+ }
+ while (mid < list[right]) {
+ right--;
+ }
+ if (left <= right) {
+ int tmp= list[left];
+ list[left]= list[right];
+ list[right]= tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(list, original_left, right);
+ }
+ if (left < original_right) {
+ quickSort(list, left, original_right);
+ }
+ }
+ private static void quickSort(String[] list, int left, int right) {
+ int original_left= left;
+ int original_right= right;
+ String mid= list[(left + right) / 2];
+ do {
+ while (list[left].compareTo(mid) < 0) {
+ left++;
+ }
+ while (mid.compareTo(list[right]) < 0) {
+ right--;
+ }
+ if (left <= right) {
+ String tmp= list[left];
+ list[left]= list[right];
+ list[right]= tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(list, original_left, right);
+ }
+ if (left < original_right) {
+ quickSort(list, left, original_right);
+ }
+ }
+ private static void quickSort(IndexedFile[] list, int left, int right) {
+ int original_left= left;
+ int original_right= right;
+ String mid= list[(left + right) / 2].path;
+ do {
+ while (list[left].path.compareTo(mid) < 0) {
+ left++;
+ }
+ while (mid.compareTo(list[right].path) < 0) {
+ right--;
+ }
+ if (left <= right) {
+ IndexedFile tmp= list[left];
+ list[left]= list[right];
+ list[right]= tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(list, original_left, right);
+ }
+ if (left < original_right) {
+ quickSort(list, left, original_right);
+ }
+ }
+ private static void quickSort(WordEntry[] list, int left, int right) {
+ int original_left= left;
+ int original_right= right;
+ char[] mid= list[(left + right) / 2].fWord;
+ do {
+ while (compare(list[left].fWord, mid) < 0) {
+ left++;
+ }
+ while (compare(mid, list[right].fWord) < 0) {
+ right--;
+ }
+ if (left <= right) {
+ WordEntry tmp= list[left];
+ list[left]= list[right];
+ list[right]= tmp;
+ left++;
+ right--;
+ }
+ } while (left <= right);
+ if (original_left < right) {
+ quickSort(list, original_left, right);
+ }
+ if (left < original_right) {
+ quickSort(list, left, original_right);
+ }
+ }
+ /**
+ * Reads in a string from the specified data input stream. The
+ * string has been encoded using a modified UTF-8 format.
+ * readUnsignedShort
. This value gives the number of
+ * following bytes that are in the encoded string, not
+ * the length of the resulting string. The following bytes are then
+ * interpreted as bytes encoding characters in the UTF-8 format
+ * and are converted into characters.
+ * writeShort
method giving the number of bytes to
+ * follow. This value is the number of bytes actually written out,
+ * not the length of the string. Following the length, each character
+ * of the string is output, in sequence, using the UTF-8 encoding
+ * for the character.
+ *
+ * @param str a string to be written.
+ * @exception IOException if an I/O error occurs.
+ * @since JDK1.0
+ */
+ public static void writeUTF(OutputStream out, char[] str) throws IOException {
+ int strlen= str.length;
+ int utflen= 0;
+ for (int i= 0; i < strlen; i++) {
+ int c= str[i];
+ if ((c >= 0x0001) && (c <= 0x007F)) {
+ utflen++;
+ } else if (c > 0x07FF) {
+ utflen += 3;
+ } else {
+ utflen += 2;
+ }
+ }
+ if (utflen > 65535)
+ throw new UTFDataFormatException();
+ out.write((utflen >>> 8) & 0xFF);
+ out.write((utflen >>> 0) & 0xFF);
+ for (int i= 0; i < strlen; i++) {
+ int c= str[i];
+ if ((c >= 0x0001) && (c <= 0x007F)) {
+ out.write(c);
+ } else if (c > 0x07FF) {
+ out.write(0xE0 | ((c >> 12) & 0x0F));
+ out.write(0x80 | ((c >> 6) & 0x3F));
+ out.write(0x80 | ((c >> 0) & 0x3F));
+ } else {
+ out.write(0xC0 | ((c >> 6) & 0x1F));
+ out.write(0x80 | ((c >> 0) & 0x3F));
+ }
+ }
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/WordEntry.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/WordEntry.java
new file mode 100644
index 00000000000..e495a7e11db
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/WordEntry.java
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import org.eclipse.cdt.internal.core.search.CharOperation;
+
+public class WordEntry {
+ protected char[] fWord;
+ protected int fNumRefs;
+ protected int[] fRefs;
+ public WordEntry() {
+ this(CharOperation.NO_CHAR);
+ }
+ public WordEntry(char[] word) {
+ fWord= word;
+ fNumRefs= 0;
+ fRefs= new int[1];
+ }
+ /**
+ * Adds a reference and records the change in footprint.
+ */
+ public int addRef(int fileNum) {
+ if (fNumRefs > 0 && fRefs[fNumRefs - 1] == fileNum) {
+ return 0;
+ }
+ if (fNumRefs < fRefs.length) {
+ fRefs[fNumRefs++]= fileNum;
+ return 0;
+ }
+
+ // For rt.jar, 73265 word entries are created. 51997 have 1 ref, then 9438, 3738, 1980, 1214, 779, 547, 429, 371 etc.
+ int newSize= fNumRefs < 4 ? 4 : fNumRefs * 2; // so will start @ 1, grow to 4, 8, 16, 32, 64 etc.
+ System.arraycopy(fRefs, 0, fRefs= new int[newSize], 0, fNumRefs);
+ fRefs[fNumRefs++]= fileNum;
+ return (newSize - fNumRefs + 1) * 4;
+ }
+ /**
+ * Adds a set of references and records the change in footprint.
+ */
+ public void addRefs(int[] refs) {
+ int[] newRefs= new int[fNumRefs + refs.length];
+ int pos1= 0;
+ int pos2= 0;
+ int posNew= 0;
+ int compare;
+ int r1= 0;
+ int r2= 0;
+ while (pos1 < fNumRefs || pos2 < refs.length) {
+ if (pos1 >= fNumRefs) {
+ r2= refs[pos2];
+ compare= -1;
+ } else if (pos2 >= refs.length) {
+ compare= 1;
+ r1= fRefs[pos1];
+ } else {
+ r1= fRefs[pos1];
+ r2= refs[pos2];
+ compare= r2 - r1;
+ }
+ if (compare > 0) {
+ newRefs[posNew]= r1;
+ posNew++;
+ pos1++;
+ } else {
+ if (r2 != 0) {
+ newRefs[posNew]= r2;
+ posNew++;
+ }
+ pos2++;
+ }
+ }
+ fRefs= newRefs;
+ fNumRefs= posNew;
+ /*for (int i = 0; i < refs.length; i++)
+ addRef(refs[i]);
+ int[] newRefs = new int[fNumRefs];
+ System.arraycopy(fRefs, 0, newRefs, 0, fNumRefs);
+ fRefs = newRefs;
+ Util.sort(fRefs);*/
+ }
+ /**
+ * Returns the size of the wordEntry
+ */
+ public int footprint() {
+ return 8 + (3 * 4) + (8 + fWord.length * 2) + (8 + fRefs.length * 4);
+ }
+ /**
+ * Returns the number of references, e.g. the number of files this word appears in.
+ */
+ public int getNumRefs() {
+ return fNumRefs;
+ }
+ /**
+ * returns the file number in the i position in the list of references.
+ */
+ public int getRef(int i) {
+ if (i < fNumRefs) return fRefs[i];
+ throw new IndexOutOfBoundsException();
+ }
+ /**
+ * Returns the references of the wordEntry (the number of the files it appears in).
+ */
+ public int[] getRefs() {
+ int[] result= new int[fNumRefs];
+ System.arraycopy(fRefs, 0, result, 0, fNumRefs);
+ return result;
+ }
+ /**
+ * returns the word of the wordEntry.
+ */
+ public char[] getWord() {
+ return fWord;
+ }
+ /**
+ * Changes the references of the wordEntry to match the mapping. For example,
+ * if the current references are [1 3 4]
+ * and mapping is [1 2 3 4 5]
+ * in references 1 becomes mapping[1] = 2, 3->4, and 4->5
+ * => references = [2 4 5].
+ */
+ public void mapRefs(int[] mappings) {
+ int position= 0;
+ for (int i= 0; i < fNumRefs; i++) {
+ int map= mappings[fRefs[i]];
+ if (map != -1 && map != 0)
+ fRefs[position++]= map;
+ }
+ fNumRefs= position;
+
+ //to be changed!
+ System.arraycopy(fRefs, 0, (fRefs= new int[fNumRefs]), 0, fNumRefs);
+ Util.sort(fRefs);
+ }
+ /**
+ * Clears the wordEntry.
+ */
+ public void reset(char[] word) {
+ for (int i= fNumRefs; i-- > 0;) {
+ fRefs[i]= 0;
+ }
+ fNumRefs= 0;
+ fWord= word;
+ }
+ public String toString() {
+ return new String(fWord);
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/WordEntryHashedArray.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/WordEntryHashedArray.java
new file mode 100644
index 00000000000..ff61a600976
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/index/impl/WordEntryHashedArray.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.index.impl;
+
+import org.eclipse.cdt.internal.core.search.CharOperation;
+
+public final class WordEntryHashedArray {
+
+ // to avoid using Enumerations, walk the objects skipping nulls
+ public WordEntry elements[];
+ public int elementSize; // number of elements in the table
+ public int threshold;
+
+ public WordEntryHashedArray(int size) {
+ if (size < 7) size = 7;
+ this.elements = new WordEntry[2 * size + 1];
+ this.elementSize = 0;
+ this.threshold = size + 1; // size is the expected number of elements
+ }
+
+ public WordEntry add(WordEntry entry) {
+ int length = elements.length;
+ char[] word = entry.getWord();
+ int index = CharOperation.hashCode(word) % length;
+ WordEntry current;
+ while ((current = elements[index]) != null) {
+ if (CharOperation.equals(current.getWord(), word)) return elements[index] = entry;
+ if (++index == length) index = 0;
+ }
+ elements[index] = entry;
+
+ // assumes the threshold is never equal to the size of the table
+ if (++elementSize > threshold) grow();
+ return entry;
+ }
+
+ public WordEntry[] asArray() {
+ WordEntry[] array = new WordEntry[elementSize];
+ for (int i = 0, j = 0, length = elements.length; i < length; i++) {
+ WordEntry current = elements[i];
+ if (current != null) array[j++] = current;
+ }
+ return array;
+ }
+
+ public WordEntry get(char[] word) {
+ int length = elements.length;
+ int index = CharOperation.hashCode(word) % length;
+ WordEntry current;
+ while ((current = elements[index]) != null) {
+ if (CharOperation.equals(current.getWord(), word)) return current;
+ if (++index == length) index = 0;
+ }
+ return null;
+ }
+
+ private void grow() {
+ WordEntryHashedArray newArray = new WordEntryHashedArray(elementSize * 2); // double the number of expected elements
+ for (int i = 0, length = elements.length; i < length; i++)
+ if (elements[i] != null)
+ newArray.add(elements[i]);
+
+ this.elements = newArray.elements;
+ this.elementSize = newArray.elementSize;
+ this.threshold = newArray.threshold;
+ }
+
+ public String toString() {
+ String s = ""; //$NON-NLS-1$
+ WordEntry[] entries = asArray();
+ for (int i = 0, length = entries.length; i < length; i++)
+ s += entries[i].toString() + "\n"; //$NON-NLS-1$
+ return s;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/CharOperation.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/CharOperation.java
new file mode 100644
index 00000000000..1e403551aaa
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/CharOperation.java
@@ -0,0 +1,2548 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.search;
+
+/**
+ * This class is a collection of helper methods to manipulate char arrays.
+ *
+ * @since 2.1
+ */
+public final class CharOperation {
+
+ /**
+ * Constant for an empty char array
+ */
+ public static final char[] NO_CHAR = new char[0];
+ /**
+ * Constant for an empty char array with two dimensions.
+ */
+ public static final char[][] NO_CHAR_CHAR = new char[0][];
+ /**
+ * Answers a new array with appending the suffix character at the end of the array.
+ *
+ *
+ * For example:
+ *
+ *
+ *
+ * @param array the array that is concanated with the suffix character
+ * @param suffix the suffix character
+ * @return the new array
+ */
+ public static final char[] append(char[] array, char suffix) {
+ if (array == null)
+ return new char[] { suffix };
+ int length = array.length;
+ System.arraycopy(array, 0, array = new char[length + 1], 0, length);
+ array[length] = suffix;
+ return array;
+ }
+ /**
+ * Append the given subarray to the target array starting at the given index in the target array.
+ * The start of the subarray is inclusive, the end is exclusive.
+ * Answers a new target array if it needs to grow, otherwise answers the same target array.
+ *
+ * array = { 'a', 'b' }
+ * suffix = 'c'
+ * => result = { 'a', 'b' , 'c' }
+ *
+ *
+ * array = null
+ * suffix = 'c'
+ * => result = { 'c' }
+ *
+ * For example:
+ *
+ *
+ *
+ * @param target the given target
+ * @param index the given index
+ * @param array the given array
+ * @param start the given start index
+ * @param end the given end index
+ *
+ * @return the new array
+ * @throws NullPointerException if the target array is null
+ */
+ public static final char[] append(char[] target, int index, char[] array, int start, int end) {
+ int targetLength = target.length;
+ int subLength = end-start;
+ int newTargetLength = subLength+index;
+ if (newTargetLength > targetLength) {
+ System.arraycopy(target, 0, target = new char[newTargetLength*2], 0, index);
+ }
+ System.arraycopy(array, start, target, index, subLength);
+ return target;
+ }
+ /**
+ * Answers the concatenation of the two arrays. It answers null if the two arrays are null.
+ * If the first array is null, then the second array is returned.
+ * If the second array is null, then the first array is returned.
+ *
+ * target = { 'a', 'b', '0' }
+ * index = 2
+ * array = { 'c', 'd' }
+ * start = 0
+ * end = 1
+ * => result = { 'a', 'b' , 'c' }
+ *
+ *
+ * target = { 'a', 'b' }
+ * index = 2
+ * array = { 'c', 'd' }
+ * start = 0
+ * end = 1
+ * => result = { 'a', 'b' , 'c', '0', '0' , '0' } (new array)
+ *
+ * target = { 'a', 'b', 'c' }
+ * index = 1
+ * array = { 'c', 'd', 'e', 'f' }
+ * start = 1
+ * end = 4
+ * => result = { 'a', 'd' , 'e', 'f', '0', '0', '0', '0' } (new array)
+ *
+ *
+ * For example:
+ *
+ *
+ *
+ * @param first the first array to concatenate
+ * @param second the second array to concatenate
+ * @return the concatenation of the two arrays, or null if the two arrays are null.
+ */
+ public static final char[][] arrayConcat(char[][] first, char[][] second) {
+ if (first == null)
+ return second;
+ if (second == null)
+ return first;
+
+ int length1 = first.length;
+ int length2 = second.length;
+ char[][] result = new char[length1 + length2][];
+ System.arraycopy(first, 0, result, 0, length1);
+ System.arraycopy(second, 0, result, length1, length2);
+ return result;
+ }
+ /**
+ * Answers a new array adding the second array at the end of first array.
+ * It answers null if the first and second are null.
+ * If the first array is null, then a new array char[][] is created with second.
+ * If the second array is null, then the first array is returned.
+ *
+ * first = null
+ * second = null
+ * => result = null
+ *
+ *
+ * first = { { ' a' } }
+ * second = null
+ * => result = { { ' a' } }
+ *
+ *
+ * first = null
+ * second = { { ' a' } }
+ * => result = { { ' a' } }
+ *
+ *
+ * first = { { ' b' } }
+ * second = { { ' a' } }
+ * => result = { { ' b' }, { ' a' } }
+ *
+ *
+ *
+ * For example:
+ *
+ *
+ *
+ * @param first the first array to concatenate
+ * @param second the array to add at the end of the first array
+ * @return a new array adding the second array at the end of first array, or null if the two arrays are null.
+ */
+ public static final char[][] arrayConcat(char[][] first, char[] second) {
+ if (second == null)
+ return first;
+ if (first == null)
+ return new char[][] { second };
+
+ int length = first.length;
+ char[][] result = new char[length + 1][];
+ System.arraycopy(first, 0, result, 0, length);
+ result[length] = second;
+ return result;
+ }
+
+ /**
+ * Compares the contents of the two arrays array and prefix. Returns
+ *
+ * first = null
+ * second = { 'a' }
+ * => result = { { ' a' } }
+ *
+ *
+ * first = { { ' a' } }
+ * second = null
+ * => result = { { ' a' } }
+ *
+ *
+ * first = { { ' a' } }
+ * second = { ' b' }
+ * => result = { { ' a' } , { ' b' } }
+ *
+ *
+ *
+ *
+ *
+ *
+ * array = null
+ * prefix = null
+ * => result = NullPointerException
+ *
+ *
+ * array = { 'a', 'b', 'c', 'd', 'e' }
+ * prefix = { 'a', 'b', 'c'}
+ * => result = 0
+ *
+ *
+ * array = { 'a', 'b', 'c', 'd', 'e' }
+ * prefix = { 'a', 'B', 'c'}
+ * => result = 32
+ *
+ *
+ * array = { 'd', 'b', 'c', 'd', 'e' }
+ * prefix = { 'a', 'b', 'c'}
+ * => result = 3
+ *
+ *
+ * array = { 'a', 'b', 'c', 'd', 'e' }
+ * prefix = { 'd', 'b', 'c'}
+ * => result = -3
+ *
+ *
+ * array = { 'a', 'a', 'c', 'd', 'e' }
+ * prefix = { 'a', 'e', 'c'}
+ * => result = -4
+ *
+ *
+ * first = null + * second = { 'a' } + * => result = { ' a' } + *+ *
+ * first = { ' a' } + * second = null + * => result = { ' a' } + *+ *
+ * first = { ' a' } + * second = { ' b' } + * => result = { ' a' , ' b' } + *+ *
+ * first = null + * second = { 'a' } + * third = { 'b' } + * => result = { ' a', 'b' } + *+ *
+ * first = { 'a' } + * second = null + * third = { 'b' } + * => result = { ' a', 'b' } + *+ *
+ * first = { 'a' } + * second = { 'b' } + * third = null + * => result = { ' a', 'b' } + *+ *
+ * first = null + * second = null + * third = null + * => result = null + *+ *
+ * first = { 'a' } + * second = { 'b' } + * third = { 'c' } + * => result = { 'a', 'b', 'c' } + *+ *
+ * first = null + * second = { 'a' } + * separator = '/' + * => result = { ' a' } + *+ *
+ * first = { ' a' } + * second = null + * separator = '/' + * => result = { ' a' } + *+ *
+ * first = { ' a' } + * second = { ' b' } + * separator = '/' + * => result = { ' a' , '/', 'b' } + *+ *
+ * first = null + * sep1 = '/' + * second = { 'a' } + * sep2 = ':' + * third = { 'b' } + * => result = { ' a' , ':', 'b' } + *+ *
+ * first = { 'a' } + * sep1 = '/' + * second = null + * sep2 = ':' + * third = { 'b' } + * => result = { ' a' , '/', 'b' } + *+ *
+ * first = { 'a' } + * sep1 = '/' + * second = { 'b' } + * sep2 = ':' + * third = null + * => result = { ' a' , '/', 'b' } + *+ *
+ * first = { 'a' } + * sep1 = '/' + * second = { 'b' } + * sep2 = ':' + * third = { 'c' } + * => result = { ' a' , '/', 'b' , ':', 'c' } + *+ *
+ * prefix = 'a' + * array = { 'b' } + * suffix = 'c' + * => result = { 'a', 'b' , 'c' } + *+ *
+ * prefix = 'a' + * array = null + * suffix = 'c' + * => result = { 'a', 'c' } + *
+ * name = { 'c' } + * array = { { 'a' }, { 'b' } } + * separator = '.' + * => result = { 'a', '.', 'b' , '.', 'c' } + *+ *
+ * name = null + * array = { { 'a' }, { 'b' } } + * separator = '.' + * => result = { 'a', '.', 'b' } + *
+ * name = { ' c' } + * array = null + * separator = '.' + * => result = { 'c' } + *
+ * name = { 'c' } + * array = { { 'a' }, { 'b' } } + * separator = '.' + * => result = { 'a', '.', 'b' , '.', 'c' } + *+ *
+ * name = null + * array = { { 'a' }, { 'b' } } + * separator = '.' + * => result = { 'a', '.', 'b' } + *
+ * name = { ' c' } + * array = null + * separator = '.' + * => result = { 'c' } + *
+ * array = { { 'a' }, { 'b' } } + * separator = '.' + * => result = { 'a', '.', 'b' } + *+ *
+ * array = null + * separator = '.' + * => result = { } + *
+ * character = 'c' + * array = { { ' a' }, { ' b' } } + * result => false + *+ *
+ * character = 'a' + * array = { { ' a' }, { ' b' } } + * result => true + *+ *
+ * character = 'c' + * array = { ' b' } + * result => false + *+ *
+ * character = 'a' + * array = { ' a' , ' b' } + * result => true + *+ *
+ * array = { 'a', 'b', 'c', 'd' } + * toBeFound = { 'b', 'c' } + * result => false + *+ *
+ * array = { 'a', 'b', 'c' } + * toBeFound = { 'b', 'c' } + * result => true + *+ *
+ * first = null + * second = null + * result => true + *+ *
+ * first = { { } } + * second = null + * result => false + *+ *
+ * first = { { 'a' } } + * second = { { 'a' } } + * result => true + *+ *
+ * first = { { 'A' } } + * second = { { 'a' } } + * result => false + *+ *
+ * first = null + * second = null + * isCaseSensitive = true + * result => true + *+ *
+ * first = { { } } + * second = null + * isCaseSensitive = true + * result => false + *+ *
+ * first = { { 'A' } } + * second = { { 'a' } } + * isCaseSensitive = true + * result => false + *+ *
+ * first = { { 'A' } } + * second = { { 'a' } } + * isCaseSensitive = false + * result => true + *+ *
+ * first = null + * second = null + * result => true + *+ *
+ * first = { } + * second = null + * result => false + *+ *
+ * first = { 'a' } + * second = { 'a' } + * result => true + *+ *
+ * first = { 'a' } + * second = { 'A' } + * result => false + *+ *
+ * first = null + * second = null + * isCaseSensitive = true + * result => true + *+ *
+ * first = { } + * second = null + * isCaseSensitive = true + * result => false + *+ *
+ * first = { 'A' } + * second = { 'a' } + * isCaseSensitive = true + * result => false + *+ *
+ * first = { 'A' } + * second = { 'a' } + * isCaseSensitive = false + * result => true + *+ *
+ * fragment = { 'b', 'c' , 'd' } + * name = { 'a', 'b', 'c' , 'd' } + * startIndex = 1 + * isCaseSensitive = true + * result => true + *+ *
+ * fragment = { 'b', 'c' , 'd' } + * name = { 'a', 'b', 'C' , 'd' } + * startIndex = 1 + * isCaseSensitive = true + * result => false + *+ *
+ * fragment = { 'b', 'c' , 'd' } + * name = { 'a', 'b', 'C' , 'd' } + * startIndex = 0 + * isCaseSensitive = false + * result => false + *+ *
+ * fragment = { 'b', 'c' , 'd' } + * name = { 'a', 'b'} + * startIndex = 0 + * isCaseSensitive = true + * result => false + *+ *
+ * c = ' ' + * result => true + *+ *
+ * c = '\u3000' + * result => false + *+ *
+ * toBeFound = 'c' + * array = { ' a', 'b', 'c', 'd' } + * result => 2 + *+ *
+ * toBeFound = 'e' + * array = { ' a', 'b', 'c', 'd' } + * result => -1 + *+ *
+ * toBeFound = 'c' + * array = { ' a', 'b', 'c', 'd' } + * start = 2 + * result => 2 + *+ *
+ * toBeFound = 'c' + * array = { ' a', 'b', 'c', 'd' } + * start = 3 + * result => -1 + *+ *
+ * toBeFound = 'e' + * array = { ' a', 'b', 'c', 'd' } + * start = 1 + * result => -1 + *+ *
+ * toBeFound = 'c' + * array = { ' a', 'b', 'c', 'd' , 'c', 'e' } + * result => 4 + *+ *
+ * toBeFound = 'e' + * array = { ' a', 'b', 'c', 'd' } + * result => -1 + *+ *
+ * toBeFound = 'c' + * array = { ' a', 'b', 'c', 'd' } + * startIndex = 2 + * result => 2 + *+ *
+ * toBeFound = 'c' + * array = { ' a', 'b', 'c', 'd', 'e' } + * startIndex = 3 + * result => -1 + *+ *
+ * toBeFound = 'e' + * array = { ' a', 'b', 'c', 'd' } + * startIndex = 0 + * result => -1 + *+ *
+ * toBeFound = 'c' + * array = { ' a', 'b', 'c', 'd' } + * startIndex = 2 + * endIndex = 2 + * result => 2 + *+ *
+ * toBeFound = 'c' + * array = { ' a', 'b', 'c', 'd', 'e' } + * startIndex = 3 + * endIndex = 4 + * result => -1 + *+ *
+ * toBeFound = 'e' + * array = { ' a', 'b', 'c', 'd' } + * startIndex = 0 + * endIndex = 3 + * result => -1 + *+ *
+ * lastSegment("java.lang.Object".toCharArray(),'.') --> Object + *+ * + * @param array the array + * @param separator the given separator + * @return the last portion of a name given a separator + * @exception NullPointerException if array is null + */ + final static public char[] lastSegment(char[] array, char separator) { + int pos = lastIndexOf(separator, array); + if (pos < 0) + return array; + return subarray(array, pos + 1, array.length); + } + /** + * Answers true if the pattern matches the given name, false otherwise. This char[] pattern matching + * accepts wild-cards '*' and '?'. + * + * When not case sensitive, the pattern is assumed to already be lowercased, the + * name will be lowercased character per character as comparing. + * If name is null, the answer is false. + * If pattern is null, the answer is true if name is not null. + *
+ * pattern = { '?', 'b', '*' } + * name = { 'a', 'b', 'c' , 'd' } + * isCaseSensitive = true + * result => true + *+ *
+ * pattern = { '?', 'b', '?' } + * name = { 'a', 'b', 'c' , 'd' } + * isCaseSensitive = true + * result => false + *+ *
+ * pattern = { 'b', '*' } + * name = { 'a', 'b', 'c' , 'd' } + * isCaseSensitive = true + * result => false + *+ *
+ * pattern = { '?', 'b', '*' } + * patternStart = 1 + * patternEnd = 3 + * name = { 'a', 'b', 'c' , 'd' } + * nameStart = 1 + * nameEnd = 4 + * isCaseSensitive = true + * result => true + *+ *
+ * pattern = { '?', 'b', '*' } + * patternStart = 1 + * patternEnd = 2 + * name = { 'a', 'b', 'c' , 'd' } + * nameStart = 1 + * nameEnd = 2 + * isCaseSensitive = true + * result => false + *+ *
+ * toBeFound = 'b' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * result => 3 + *+ *
+ * toBeFound = 'c' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * result => 0 + *+ *
+ * toBeFound = 'b' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * start = 2 + * result => 2 + *+ *
+ * toBeFound = 'c' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * start = 0 + * result => 0 + *+ *
+ * prefix = { 'a' , 'b' } + * name = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * result => true + *+ *
+ * prefix = { 'a' , 'c' } + * name = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * result => false + *+ *
+ * prefix = { 'a' , 'B' } + * name = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * isCaseSensitive = false + * result => true + *+ *
+ * prefix = { 'a' , 'B' } + * name = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * isCaseSensitive = true + * result => false + *+ *
+ * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * toBeReplaced = 'b' + * replacementChar = 'a' + * result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a' } + *+ *
+ * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * toBeReplaced = 'c' + * replacementChar = 'a' + * result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'a', 'b', 'a' } + *+ *
+ * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * toBeReplaced = { 'b' } + * replacementChar = { 'a', 'a' } + * result => { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' } + *+ *
+ * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * toBeReplaced = { 'c' } + * replacementChar = { 'a' } + * result => { 'a' , 'b', 'b', 'a', 'b', 'a' } + *+ *
+ * divider = 'b' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * result => { { 'a' }, { }, { 'a' }, { 'a' } } + *+ *
+ * divider = 'c' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } } + *+ *
+ * divider = 'b' + * array = { 'a' , ' ', 'b', 'b', 'a', 'b', 'a' } + * result => { { 'a' }, { }, { 'a' }, { 'a' } } + *+ *
+ * divider = 'c' + * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' } + * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } } + *+ *
+ * divider = 'b' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * result => { { 'a' }, { }, { 'a' }, { 'a' } } + *+ *
+ * divider = 'c' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * result => { { 'a', 'b', 'b', 'a', 'b', 'a' } } + *+ *
+ * divider = 'c' + * array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' } + * result => { { ' ', 'a', 'b', 'b', 'a', 'b', 'a', ' ' } } + *+ *
+ * divider = 'b' + * array = { 'a' , 'b', 'b', 'a', 'b', 'a' } + * start = 2 + * end = 5 + * result => { { }, { }, { 'a' } } + *+ *
+ * array = { { 'a' } , { 'b' } } + * start = 0 + * end = 1 + * result => { { 'a' } } + *+ *
+ * array = { { 'a' } , { 'b' } } + * start = 0 + * end = -1 + * result => { { 'a' }, { 'b' } } + *+ *
+ * array = { 'a' , 'b' } + * start = 0 + * end = 1 + * result => { 'a' } + *+ *
+ * array = { 'a', 'b' } + * start = 0 + * end = -1 + * result => { 'a' , 'b' } + *+ *
+ * chars = { 'a' , 'b' } + * result => { 'a' , 'b' } + *+ *
+ * array = { 'A', 'b' } + * result => { 'a' , 'b' } + *+ *
+ * chars = { ' ', 'a' , 'b', ' ', ' ' } + * result => { 'a' , 'b' } + *+ *
+ * array = { 'A', 'b' } + * result => { 'A' , 'b' } + *+ *
+ * array = { { 'a' } , { 'b' } } + * result => "a.b" + *+ *
+ * array = { { ' ', 'a' } , { 'b' } } + * result => " a.b" + *+ *
IIndexer
handles.
+ */
+ public abstract String[] getFileTypes();
+ /**
+ * @see IIndexer#index(IDocument document, IIndexerOutput output)
+ */
+ public void index(IDocument document, IIndexerOutput output) throws IOException {
+ this.output = output;
+ if (shouldIndex(document)) indexFile(document);
+ }
+
+ protected abstract void indexFile(IDocument document) throws IOException;
+ /**
+ * @see IIndexer#shouldIndex(IDocument document)
+ */
+ public boolean shouldIndex(IDocument document) {
+ String type = document.getType();
+ String[] supportedTypes = this.getFileTypes();
+ for (int i = 0; i < supportedTypes.length; ++i) {
+ if (supportedTypes[i].equals(type))
+ return true;
+ }
+ return false;
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddCompilationUnitToIndex.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddCompilationUnitToIndex.java
new file mode 100644
index 00000000000..a74c3c93731
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddCompilationUnitToIndex.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.cdt.internal.core.index.IIndex;
+import org.eclipse.cdt.internal.core.index.impl.IFileDocument;
+
+public class AddCompilationUnitToIndex extends AddFileToIndex {
+ char[] contents;
+
+ public AddCompilationUnitToIndex(IFile resource, IPath indexedContainer, IndexManager manager) {
+ super(resource, indexedContainer, manager);
+ }
+ protected boolean indexDocument(IIndex index) throws IOException {
+ if (!initializeContents()) return false;
+ index.add(new IFileDocument(resource, this.contents), new SourceIndexer(resource));
+ return true;
+ }
+ public boolean initializeContents() {
+ if (this.contents == null) {
+ try {
+ IPath location = resource.getLocation();
+ if (location != null)
+ this.contents = org.eclipse.cdt.internal.core.search.Util.getFileCharContent(location.toFile(), null);
+ } catch (IOException e) {
+ }
+ }
+ return this.contents != null;
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddFileToIndex.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddFileToIndex.java
new file mode 100644
index 00000000000..856298d7373
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddFileToIndex.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.cdt.internal.core.index.IIndex;
+import org.eclipse.cdt.internal.core.search.processing.JobManager;
+
+public abstract class AddFileToIndex extends IndexRequest {
+ IFile resource;
+
+ public AddFileToIndex(IFile resource, IPath indexPath, IndexManager manager) {
+ super(indexPath, manager);
+ this.resource = resource;
+ }
+
+ public boolean execute(IProgressMonitor progressMonitor) {
+ if (progressMonitor != null && progressMonitor.isCanceled()) return true;
+ /* ensure no concurrent write access to index */
+ IIndex index = manager.getIndex(this.indexPath, true, /*reuse index file*/ true /*create if none*/);
+ if (index == null) return true;
+ ReadWriteMonitor monitor = manager.getMonitorFor(index);
+ if (monitor == null) return true; // index got deleted since acquired
+ try {
+ monitor.enterWrite(); // ask permission to write
+ if (!indexDocument(index)) return false;
+ } catch (IOException e) {
+ if (JobManager.VERBOSE) {
+ JobManager.verbose("-> failed to index " + this.resource + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
+ e.printStackTrace();
+ }
+ return false;
+ } finally {
+ monitor.exitWrite(); // free write lock
+ }
+ return true;
+ }
+
+ protected abstract boolean indexDocument(IIndex index) throws IOException;
+
+ public String toString() {
+ return "indexing " + this.resource.getFullPath(); //$NON-NLS-1$
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddFolderToIndex.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddFolderToIndex.java
new file mode 100644
index 00000000000..b45c352ac60
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/AddFolderToIndex.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.cdt.internal.core.search.Util;
+import org.eclipse.cdt.internal.core.index.IIndex;
+import org.eclipse.cdt.internal.core.search.processing.JobManager;
+
+class AddFolderToIndex extends IndexRequest {
+ IPath folderPath;
+ IProject project;
+ char[][] exclusionPattern;
+
+ public AddFolderToIndex(IPath folderPath, IProject project, char[][] exclusionPattern, IndexManager manager) {
+ super(project.getFullPath(), manager);
+ this.folderPath = folderPath;
+ this.project = project;
+ this.exclusionPattern = exclusionPattern;
+ }
+
+ public boolean execute(IProgressMonitor progressMonitor) {
+ if (progressMonitor != null && progressMonitor.isCanceled()) return true;
+ if (!project.isAccessible()) return true; // nothing to do
+ IResource folder = this.project.getParent().findMember(this.folderPath);
+ if (folder == null || folder.getType() == IResource.FILE) return true; // nothing to do, source folder was removed
+
+ /* ensure no concurrent write access to index */
+ IIndex index = manager.getIndex(this.indexPath, true, /*reuse index file*/ true /*create if none*/);
+ if (index == null) return true;
+ ReadWriteMonitor monitor = manager.getMonitorFor(index);
+ if (monitor == null) return true; // index got deleted since acquired
+
+ try {
+ monitor.enterRead(); // ask permission to read
+
+ final IPath container = this.indexPath;
+ final IndexManager indexManager = this.manager;
+ final char[][] pattern = exclusionPattern;
+ folder.accept(
+ new IResourceProxyVisitor() {
+ public boolean visit(IResourceProxy proxy) throws CoreException {
+ switch(proxy.getType()) {
+ case IResource.FILE :
+// TODO: BOG Put the file name checking back
+ //if (Util.isJavaFileName(proxy.getName())) {
+ IResource resource = proxy.requestResource();
+ if (pattern == null || !Util.isExcluded(resource, pattern))
+ indexManager.addSource((IFile)resource, container);
+ //}
+ //return false;
+ case IResource.FOLDER :
+ if (pattern != null && Util.isExcluded(proxy.requestResource(), pattern))
+ return false;
+ }
+ return true;
+ }
+ },
+ IResource.NONE
+ );
+ } catch (CoreException e) {
+ if (JobManager.VERBOSE) {
+ JobManager.verbose("-> failed to add " + this.folderPath + " to index because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
+ e.printStackTrace();
+ }
+ return false;
+ } finally {
+ monitor.exitRead(); // free read lock
+ }
+ return true;
+ }
+
+ public String toString() {
+ return "adding " + this.folderPath + " to index " + this.indexPath; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+}
+
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IIndexConstants.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IIndexConstants.java
new file mode 100644
index 00000000000..c206297f000
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IIndexConstants.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+/**
+ * @author bgheorgh
+ */
+public interface IIndexConstants {
+
+ /* index encoding */
+ char[] REF= "ref/".toCharArray(); //$NON-NLS-1$
+
+ char[] TYPE_REF= "typeRef/".toCharArray(); //$NON-NLS-1$
+ char[] TYPE_DECL = "typeDecl/".toCharArray(); //$NON-NLS-1$
+ int TYPE_DECL_LENGTH = 9;
+
+ char[] FUNCTION_REF= "functionRef/".toCharArray(); //$NON-NLS-1$
+ char[] FUNCTION_DECL= "functionDecl/".toCharArray(); //$NON-NLS-1$
+
+ char[] CONSTRUCTOR_REF= "constructorRef/".toCharArray(); //$NON-NLS-1$
+ char[] CONSTRUCTOR_DECL= "constructorDecl/".toCharArray(); //$NON-NLS-1$
+
+ char[] NAMESPACE_REF= "namespaceRef/".toCharArray(); //$NON-NLS-1$
+ char[] NAMESPACE_DECL= "namespaceDecl/".toCharArray(); //$NON-NLS-1$
+
+ char[] MEMBER_REF= "memberRef/".toCharArray(); //$NON-NLS-1$
+ char[] MEMBER_DECL= "memberDecl/".toCharArray(); //$NON-NLS-1$
+
+ //a Var REF will be treated as a typeREF
+ //char[] VAR_REF= "varRef/".toCharArray(); //$NON-NLS-1$
+
+ //a Struct REF will be treated as a typeREF
+ //char[] STRUCT_REF= "structRef/".toCharArray(); //$NON-NLS-1$
+
+ //a Enum REF will be treated as a typeREF
+ //char[] ENUM_REF= "enumRef/".toCharArray(); //$NON-NLS-1$
+
+ //a UNION REF will be treated as a typeREF
+ //char[] UNION_REF= "unionRef/".toCharArray(); //$NON-NLS-1$
+
+
+ char[] SUPER_REF = "superRef/".toCharArray(); //$NON-NLS-1$
+
+ char[] CLASS_DECL= "typeDecl/C/".toCharArray(); //$NON-NLS-1$
+ char[] VAR_DECL= "typeDecl/V/".toCharArray(); //$NON-NLS-1$
+ char[] STRUCT_DECL= "typeDecl/S/".toCharArray(); //$NON-NLS-1$
+ char[] ENUM_DECL= "typeDecl/E/".toCharArray(); //$NON-NLS-1$
+ char[] UNION_DECL= "typeDecl/U/".toCharArray(); //$NON-NLS-1$
+
+ char[] OBJECT = "Object".toCharArray(); //$NON-NLS-1$
+ char[][] COUNTS=
+ new char[][] { new char[] {'0'}, new char[] {'1'}, new char[] {'2'}, new char[] {'3'}, new char[] {'4'}, new char[] {'5'}, new char[] {'6'}, new char[] {'7'}, new char[] {'8'}, new char[] {'9'}
+ };
+ char CLASS_SUFFIX = 'C';
+ char VAR_SUFFIX = 'V';
+ char STRUCT_SUFFIX = 'S';
+ char ENUM_SUFFIX = 'E';
+ char UNION_SUFFIX = 'U';
+
+ char TYPE_SUFFIX = 0;
+ char SEPARATOR= '/';
+
+ char[] ONE_STAR = new char[] {'*'};
+ char[][] ONE_STAR_CHAR = new char[][] {ONE_STAR};
+
+ // used as special marker for enclosing type name of local and anonymous classes
+ char[] ONE_ZERO = new char[] {'0'};
+ char[][] ONE_ZERO_CHAR = new char[][] {ONE_ZERO};
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexAllProject.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexAllProject.java
new file mode 100644
index 00000000000..0cde9fd2446
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexAllProject.java
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 1, 2003
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+
+import java.io.IOException;
+import java.util.HashSet;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.internal.core.search.Util;
+import org.eclipse.cdt.internal.core.index.IIndex;
+import org.eclipse.cdt.internal.core.index.IQueryResult;
+import org.eclipse.cdt.internal.core.index.impl.IFileDocument;
+import org.eclipse.cdt.internal.core.search.processing.JobManager;
+import org.eclipse.cdt.internal.core.search.SimpleLookupTable;
+import org.eclipse.cdt.internal.core.model.CModel;
+import org.eclipse.cdt.internal.core.model.CModelManager;
+import org.eclipse.cdt.core.model.ICElement;
+
+
+public class IndexAllProject extends IndexRequest {
+ IProject project;
+
+ public IndexAllProject(IProject project, IndexManager manager) {
+ super(project.getFullPath(), manager);
+ this.project = project;
+ }
+
+ public boolean equals(Object o) {
+ if (o instanceof IndexAllProject)
+ return this.project.equals(((IndexAllProject) o).project);
+ return false;
+ }
+ /**
+ * Ensure consistency of a project index. Need to walk all nested resources,
+ * and discover resources which have either been changed, added or deleted
+ * since the index was produced.
+ */
+ public boolean execute(IProgressMonitor progressMonitor) {
+
+ if (progressMonitor != null && progressMonitor.isCanceled()) return true;
+ if (!project.isAccessible()) return true; // nothing to do
+
+ IIndex index = this.manager.getIndex(this.indexPath, true, /*reuse index file*/ true /*create if none*/);
+ if (index == null) return true;
+ ReadWriteMonitor monitor = this.manager.getMonitorFor(index);
+ if (monitor == null) return true; // index got deleted since acquired
+
+ try {
+ monitor.enterRead(); // ask permission to read
+ saveIfNecessary(index, monitor);
+
+ IQueryResult[] results = index.queryInDocumentNames(""); // all file names //$NON-NLS-1$
+ int max = results == null ? 0 : results.length;
+ final SimpleLookupTable indexedFileNames = new SimpleLookupTable(max == 0 ? 33 : max + 11);
+ final String OK = "OK"; //$NON-NLS-1$
+ final String DELETED = "DELETED"; //$NON-NLS-1$
+ for (int i = 0; i < max; i++)
+ indexedFileNames.put(results[i].getPath(), DELETED);
+ final long indexLastModified = max == 0 ? 0L : index.getIndexFile().lastModified();
+
+ CModel model = (CModel) CModelManager.getDefault().getCModel();
+ ICProject cProject = model.getCProject(project.getName());
+ ICElement[] kids = cProject.getChildren();
+ IPath cProjectPath = cProject.getPath();
+
+ IWorkspaceRoot root = this.project.getWorkspace().getRoot();
+ IResource sourceFolder = root.findMember(cProjectPath);
+
+ if (this.isCancelled) return false;
+
+ if (sourceFolder != null) {
+
+ // collect output locations if source is project (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32041)
+ final HashSet outputs = new HashSet();
+
+ final boolean hasOutputs = !outputs.isEmpty();
+
+ final char[][] patterns = null;
+ if (max == 0) {
+ sourceFolder.accept(
+ new IResourceProxyVisitor() {
+ public boolean visit(IResourceProxy proxy) {
+ if (isCancelled) return false;
+ switch(proxy.getType()) {
+ case IResource.FILE :
+ //TODO: BOG Put the file name checking back
+ //if (Util.isCCFileName(proxy.getName())) {
+ IResource resource = proxy.requestResource();
+ if (resource.getLocation() != null && (patterns == null || !Util.isExcluded(resource, patterns))) {
+ String name = new IFileDocument((IFile) resource).getName();
+ indexedFileNames.put(name, resource);
+ }
+ //}
+ // return false;
+
+ case IResource.FOLDER :
+ if (patterns != null && Util.isExcluded(proxy.requestResource(), patterns))
+ return false;
+ if (hasOutputs && outputs.contains(proxy.requestFullPath())) {
+ return false;
+ }
+ }
+ return true;
+ }
+ },
+ IResource.NONE
+ );
+ } else {
+ sourceFolder.accept(
+ new IResourceProxyVisitor() {
+ public boolean visit(IResourceProxy proxy) {
+ if (isCancelled) return false;
+ switch(proxy.getType()) {
+ case IResource.FILE :
+// TODO: BOG Put the file name checking back
+ //if (Util.isCCFileName(proxy.getName())) {
+ IResource resource = proxy.requestResource();
+ IPath path = resource.getLocation();
+ if (path != null && (patterns == null || !Util.isExcluded(resource, patterns))) {
+ String name = new IFileDocument((IFile) resource).getName();
+ indexedFileNames.put(name,
+ indexedFileNames.get(name) == null || indexLastModified < path.toFile().lastModified()
+ ? (Object) resource
+ : (Object) OK);
+ }
+ //}
+ //return false;
+ case IResource.FOLDER :
+ if (patterns != null && Util.isExcluded(proxy.requestResource(), patterns))
+ return false;
+ if (hasOutputs && outputs.contains(proxy.requestFullPath())) {
+ return false;
+ }
+ }
+ return true;
+ }
+ },
+ IResource.NONE
+ );
+ }
+ }
+
+ Object[] names = indexedFileNames.keyTable;
+ Object[] values = indexedFileNames.valueTable;
+ boolean shouldSave = false;
+ for (int i = 0, length = names.length; i < length; i++) {
+ String name = (String) names[i];
+ if (name != null) {
+ if (this.isCancelled) return false;
+
+ Object value = values[i];
+ if (value != OK) {
+ shouldSave = true;
+ if (value == DELETED)
+ this.manager.remove(name, this.indexPath);
+ else
+ this.manager.addSource((IFile) value, this.indexPath);
+ }
+ }
+ }
+
+ // request to save index when all cus have been indexed
+ if (shouldSave)
+ this.manager.request(new SaveIndex(this.indexPath, this.manager));
+
+ } catch (CoreException e) {
+ if (JobManager.VERBOSE) {
+ JobManager.verbose("-> failed to index " + this.project + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
+ e.printStackTrace();
+ }
+ this.manager.removeIndex(this.indexPath);
+ return false;
+ } catch (IOException e) {
+ if (JobManager.VERBOSE) {
+ JobManager.verbose("-> failed to index " + this.project + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$
+ e.printStackTrace();
+ }
+ this.manager.removeIndex(this.indexPath);
+ return false;
+ } finally {
+ monitor.exitRead(); // free read lock
+ }
+ return true;
+ }
+
+ public int hashCode() {
+ return this.project.hashCode();
+ }
+
+ protected Integer updatedIndexState() {
+ return IndexManager.REBUILDING_STATE;
+ }
+
+ public String toString() {
+ return "indexing project " + this.project.getFullPath(); //$NON-NLS-1$
+ }
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexManager.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexManager.java
new file mode 100644
index 00000000000..b26929d7580
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexManager.java
@@ -0,0 +1,611 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.zip.CRC32;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.cdt.internal.core.search.processing.JobManager;
+import org.eclipse.cdt.internal.core.search.processing.IJob;
+import org.eclipse.cdt.internal.core.search.SimpleLookupTable;
+import org.eclipse.cdt.internal.core.search.CharOperation;
+import org.eclipse.cdt.internal.core.index.IIndex;
+import org.eclipse.cdt.internal.core.index.impl.Index;
+import org.eclipse.cdt.internal.core.model.CProject;
+import org.eclipse.cdt.core.CCorePlugin;
+
+public class IndexManager extends JobManager implements IIndexConstants {
+ /* number of file contents in memory */
+ public static int MAX_FILES_IN_MEMORY = 0;
+
+ public IWorkspace workspace;
+ public SimpleLookupTable indexNames = new SimpleLookupTable();
+ private Map indexes = new HashMap(5);
+
+ /* read write monitors */
+ private Map monitors = new HashMap(5);
+
+ /* need to save ? */
+ private boolean needToSave = false;
+ private static final CRC32 checksumCalculator = new CRC32();
+ private IPath javaPluginLocation = null;
+
+ /* can only replace a current state if its less than the new one */
+ private SimpleLookupTable indexStates = null;
+ private File savedIndexNamesFile =
+ new File(getJavaPluginWorkingLocation().append("savedIndexNames.txt").toOSString()); //$NON-NLS-1$
+ public static Integer SAVED_STATE = new Integer(0);
+ public static Integer UPDATING_STATE = new Integer(1);
+ public static Integer UNKNOWN_STATE = new Integer(2);
+ public static Integer REBUILDING_STATE = new Integer(3);
+
+ public synchronized void aboutToUpdateIndex(IPath path, Integer newIndexState) {
+ // newIndexState is either UPDATING_STATE or REBUILDING_STATE
+ // must tag the index as inconsistent, in case we exit before the update job is started
+ String indexName = computeIndexName(path);
+ Object state = getIndexStates().get(indexName);
+ Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state;
+ if (currentIndexState.equals(REBUILDING_STATE)) return; // already rebuilding the index
+
+ int compare = newIndexState.compareTo(currentIndexState);
+ if (compare > 0) {
+ // so UPDATING_STATE replaces SAVED_STATE and REBUILDING_STATE replaces everything
+ updateIndexState(indexName, newIndexState);
+ } else if (compare < 0 && this.indexes.get(path) == null) {
+ // if already cached index then there is nothing more to do
+ rebuildIndex(indexName, path);
+ }
+ }
+ /**
+ * Not at the moment...
+ * @param resource
+ * @param indexedContainer
+ */
+ /*
+ public void addBinary(IFile resource, IPath indexedContainer){
+ if (JavaCore.getPlugin() == null) return;
+ AddClassFileToIndex job = new AddClassFileToIndex(resource, indexedContainer, this);
+ if (this.awaitingJobsCount() < MAX_FILES_IN_MEMORY) {
+ // reduces the chance that the file is open later on, preventing it from being deleted
+ if (!job.initializeContents()) return;
+ }
+ request(job);
+ }
+ */
+ /**
+ * Trigger addition of a resource to an index
+ * Note: the actual operation is performed in background
+ */
+ public void addSource(IFile resource, IPath indexedContainer){
+ if (CCorePlugin.getDefault() == null) return;
+ AddCompilationUnitToIndex job = new AddCompilationUnitToIndex(resource, indexedContainer, this);
+ if (this.awaitingJobsCount() < MAX_FILES_IN_MEMORY) {
+ // reduces the chance that the file is open later on, preventing it from being deleted
+ if (!job.initializeContents()) return;
+ }
+ request(job);
+ }
+
+ String computeIndexName(IPath path) {
+ String name = (String) indexNames.get(path);
+ if (name == null) {
+ String pathString = path.toOSString();
+ checksumCalculator.reset();
+ checksumCalculator.update(pathString.getBytes());
+ String fileName = Long.toString(checksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
+ if (VERBOSE)
+ JobManager.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$
+ name = getJavaPluginWorkingLocation().append(fileName).toOSString();
+ indexNames.put(path, name);
+ }
+ return name;
+ }
+ /**
+ * Returns the index for a given project, according to the following algorithm:
+ * - if index is already in memory: answers this one back
+ * - if (reuseExistingFile) then read it and return this index and record it in memory
+ * - if (createIfMissing) then create a new empty index and record it in memory
+ *
+ * Warning: Does not check whether index is consistent (not being used)
+ */
+ public synchronized IIndex getIndex(IPath path, boolean reuseExistingFile, boolean createIfMissing) {
+ // Path is already canonical per construction
+ IIndex index = (IIndex) indexes.get(path);
+ if (index == null) {
+ String indexName = computeIndexName(path);
+ Object state = getIndexStates().get(indexName);
+ Integer currentIndexState = state == null ? UNKNOWN_STATE : (Integer) state;
+ if (currentIndexState == UNKNOWN_STATE) {
+ // should only be reachable for query jobs
+ // IF you put an index in the cache, then AddJarFileToIndex fails because it thinks there is nothing to do
+ rebuildIndex(indexName, path);
+ return null;
+ }
+
+ // index isn't cached, consider reusing an existing index file
+ if (reuseExistingFile) {
+ File indexFile = new File(indexName);
+ if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing
+ try {
+ index = new Index(indexName, "Index for " + path.toOSString(), true /*reuse index file*/); //$NON-NLS-1$
+ indexes.put(path, index);
+ monitors.put(index, new ReadWriteMonitor());
+ return index;
+ } catch (IOException e) {
+ // failed to read the existing file or its no longer compatible
+ if (currentIndexState != REBUILDING_STATE) { // rebuild index if existing file is corrupt, unless the index is already being rebuilt
+ if (VERBOSE)
+ JobManager.verbose("-> cannot reuse existing index: "+indexName+" path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+ rebuildIndex(indexName, path);
+ return null;
+ } else {
+ index = null; // will fall thru to createIfMissing & create a empty index for the rebuild all job to populate
+ }
+ }
+ }
+ if (currentIndexState == SAVED_STATE) { // rebuild index if existing file is missing
+ rebuildIndex(indexName, path);
+ return null;
+ }
+ }
+ // index wasn't found on disk, consider creating an empty new one
+ if (createIfMissing) {
+ try {
+ if (VERBOSE)
+ JobManager.verbose("-> create empty index: "+indexName+" path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+ index = new Index(indexName, "Index for " + path.toOSString(), false /*do not reuse index file*/); //$NON-NLS-1$
+ indexes.put(path, index);
+ monitors.put(index, new ReadWriteMonitor());
+ return index;
+ } catch (IOException e) {
+ if (VERBOSE)
+ JobManager.verbose("-> unable to create empty index: "+indexName+" path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+ // The file could not be created. Possible reason: the project has been deleted.
+ return null;
+ }
+ }
+ }
+ //System.out.println(" index name: " + path.toOSString() + " <----> " + index.getIndexFile().getName());
+ return index;
+ }
+
+ private SimpleLookupTable getIndexStates() {
+ if (indexStates != null) return indexStates;
+
+ this.indexStates = new SimpleLookupTable();
+ char[] savedIndexNames = readIndexState();
+ if (savedIndexNames.length > 0) {
+ char[][] names = CharOperation.splitOn('\n', savedIndexNames);
+ for (int i = 0, l = names.length; i < l; i++) {
+ char[] name = names[i];
+ if (name.length > 0)
+ this.indexStates.put(new String(name), SAVED_STATE);
+ }
+ }
+ return this.indexStates;
+ }
+
+ private IPath getJavaPluginWorkingLocation() {
+ if (this.javaPluginLocation != null) return this.javaPluginLocation;
+
+ return this.javaPluginLocation = CCorePlugin.getDefault().getStateLocation();
+ }
+ /**
+ * Index access is controlled through a read-write monitor so as
+ * to ensure there is no concurrent read and write operations
+ * (only concurrent reading is allowed).
+ */
+ public ReadWriteMonitor getMonitorFor(IIndex index){
+ return (ReadWriteMonitor) monitors.get(index);
+ }
+ /**
+ * Trigger addition of the entire content of a project
+ * Note: the actual operation is performed in background
+ */
+ public void indexAll(IProject project) {
+ if (CCorePlugin.getDefault() == null) return;
+
+ /******
+ *TODO: Remove these methods once the new indexer is
+ *fully integrated
+ */
+ if (!isEnabled(project)) return;
+
+ // check if the same request is not already in the queue
+ IndexRequest request = new IndexAllProject(project, this);
+ for (int i = this.jobEnd; i > this.jobStart; i--) // NB: don't check job at jobStart, as it may have already started (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32488)
+ if (request.equals(this.awaitingJobs[i])) return;
+ this.request(request);
+ }
+ /**
+ * Index the content of the given source folder.
+ */
+ public void indexSourceFolder(CProject javaProject, IPath sourceFolder, final char[][] exclusionPattern) {
+ IProject project = javaProject.getProject();
+ if (this.jobEnd > this.jobStart) {
+ // check if a job to index the project is not already in the queue
+ IndexRequest request = new IndexAllProject(project, this);
+ for (int i = this.jobEnd; i > this.jobStart; i--) // NB: don't check job at jobStart, as it may have already started (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32488)
+ if (request.equals(this.awaitingJobs[i])) return;
+ }
+ this.request(new AddFolderToIndex(sourceFolder, project, exclusionPattern, this));
+ }
+
+ public void jobWasCancelled(IPath path) {
+ Object o = this.indexes.get(path);
+ if (o instanceof IIndex) {
+ this.monitors.remove(o);
+ this.indexes.remove(path);
+ }
+ updateIndexState(computeIndexName(path), UNKNOWN_STATE);
+ }
+ /**
+ * Advance to the next available job, once the current one has been completed.
+ * Note: clients awaiting until the job count is zero are still waiting at this point.
+ */
+ protected synchronized void moveToNextJob() {
+ // remember that one job was executed, and we will need to save indexes at some point
+ needToSave = true;
+ super.moveToNextJob();
+ }
+ /**
+ * No more job awaiting.
+ */
+ protected void notifyIdle(long idlingTime){
+ if (idlingTime > 1000 && needToSave) saveIndexes();
+ }
+ /*
+ * For debug purpose
+ */
+ public IIndex peekAtIndex(IPath path) {
+ return (IIndex) indexes.get(path);
+ }
+ /**
+ * Name of the background process
+ */
+ public String processName(){
+ return org.eclipse.cdt.internal.core.search.Util.bind("process.name"); //$NON-NLS-1$
+ }
+
+ private void rebuildIndex(String indexName, IPath path) {
+ Object target = org.eclipse.cdt.internal.core.search.Util.getTarget(ResourcesPlugin.getWorkspace().getRoot(), path, true);
+ if (target == null) return;
+
+ if (VERBOSE)
+ JobManager.verbose("-> request to rebuild index: "+indexName+" path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+
+ updateIndexState(indexName, REBUILDING_STATE);
+ IndexRequest request = null;
+ if (target instanceof IProject) {
+ IProject p = (IProject) target;
+ //if (JavaProject.hasJavaNature(p))
+ request = new IndexAllProject(p, this);
+ }
+
+ if (request != null)
+ request(request);
+ }
+ /**
+ * Recreates the index for a given path, keeping the same read-write monitor.
+ * Returns the new empty index or null if it didn't exist before.
+ * Warning: Does not check whether index is consistent (not being used)
+ */
+ public synchronized IIndex recreateIndex(IPath path) {
+ // only called to over write an existing cached index...
+ try {
+ IIndex index = (IIndex) this.indexes.get(path);
+ ReadWriteMonitor monitor = (ReadWriteMonitor) this.monitors.remove(index);
+
+ // Path is already canonical
+ String indexPath = computeIndexName(path);
+ if (VERBOSE)
+ JobManager.verbose("-> recreating index: "+indexPath+" for path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+ index = new Index(indexPath, "Index for " + path.toOSString(), false /*reuse index file*/); //$NON-NLS-1$
+ indexes.put(path, index);
+ monitors.put(index, monitor);
+ return index;
+ } catch (IOException e) {
+ // The file could not be created. Possible reason: the project has been deleted.
+ if (VERBOSE) {
+ JobManager.verbose("-> failed to recreate index for path: "+path.toOSString()); //$NON-NLS-1$ //$NON-NLS-2$
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }
+ /**
+ * Trigger removal of a resource to an index
+ * Note: the actual operation is performed in background
+ */
+ public void remove(String resourceName, IPath indexedContainer){
+ request(new RemoveFromIndex(resourceName, indexedContainer, this));
+ }
+ /**
+ * Removes the index for a given path.
+ * This is a no-op if the index did not exist.
+ */
+ public synchronized void removeIndex(IPath path) {
+ if (VERBOSE)
+ JobManager.verbose("removing index " + path); //$NON-NLS-1$
+ String indexName = computeIndexName(path);
+ File indexFile = new File(indexName);
+ if (indexFile.exists())
+ indexFile.delete();
+ Object o = this.indexes.get(path);
+ if (o instanceof IIndex)
+ this.monitors.remove(o);
+ this.indexes.remove(path);
+ updateIndexState(indexName, null);
+ }
+ /**
+ * Removes all indexes whose paths start with (or are equal to) the given path.
+ */
+ public synchronized void removeIndexFamily(IPath path) {
+ // only finds cached index files... shutdown removes all non-cached index files
+ ArrayList toRemove = null;
+ Iterator iterator = this.indexes.keySet().iterator();
+ while (iterator.hasNext()) {
+ IPath indexPath = (IPath) iterator.next();
+ if (path.isPrefixOf(indexPath)) {
+ if (toRemove == null)
+ toRemove = new ArrayList();
+ toRemove.add(indexPath);
+ }
+ }
+ if (toRemove != null)
+ for (int i = 0, length = toRemove.size(); i < length; i++)
+ this.removeIndex((IPath) toRemove.get(i));
+ }
+ /**
+ * Remove the content of the given source folder from the index.
+ */
+ public void removeSourceFolderFromIndex(CProject javaProject, IPath sourceFolder, char[][] exclusionPatterns) {
+ IProject project = javaProject.getProject();
+ if (this.jobEnd > this.jobStart) {
+ // check if a job to index the project is not already in the queue
+ IndexRequest request = new IndexAllProject(project, this);
+ for (int i = this.jobEnd; i > this.jobStart; i--) // NB: don't check job at jobStart, as it may have already started (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32488)
+ if (request.equals(this.awaitingJobs[i])) return;
+ }
+
+ this.request(new RemoveFolderFromIndex(sourceFolder, exclusionPatterns, project, this));
+ }
+ /**
+ * Flush current state
+ */
+ public void reset() {
+ super.reset();
+ if (this.indexes != null) {
+ this.indexes = new HashMap(5);
+ this.monitors = new HashMap(5);
+ this.indexStates = null;
+ }
+ this.indexNames = new SimpleLookupTable();
+ this.javaPluginLocation = null;
+ }
+
+ public void saveIndex(IIndex index) throws IOException {
+ // must have permission to write from the write monitor
+ if (index.hasChanged()) {
+ if (VERBOSE)
+ JobManager.verbose("-> saving index " + index.getIndexFile()); //$NON-NLS-1$
+ index.save();
+ }
+ String indexName = index.getIndexFile().getPath();
+ if (this.jobEnd > this.jobStart) {
+ Object indexPath = indexNames.keyForValue(indexName);
+ if (indexPath != null) {
+ for (int i = this.jobEnd; i > this.jobStart; i--) { // skip the current job
+ IJob job = this.awaitingJobs[i];
+ if (job instanceof IndexRequest)
+ if (((IndexRequest) job).indexPath.equals(indexPath)) return;
+ }
+ }
+ }
+ updateIndexState(indexName, SAVED_STATE);
+ }
+ /**
+ * Commit all index memory changes to disk
+ */
+ public void saveIndexes() {
+ // only save cached indexes... the rest were not modified
+ ArrayList toSave = new ArrayList();
+ synchronized(this) {
+ for (Iterator iter = this.indexes.values().iterator(); iter.hasNext();) {
+ Object o = iter.next();
+ if (o instanceof IIndex)
+ toSave.add(o);
+ }
+ }
+
+ for (int i = 0, length = toSave.size(); i < length; i++) {
+ IIndex index = (IIndex) toSave.get(i);
+ ReadWriteMonitor monitor = getMonitorFor(index);
+ if (monitor == null) continue; // index got deleted since acquired
+ try {
+ monitor.enterWrite();
+ try {
+ saveIndex(index);
+ } catch(IOException e){
+ if (VERBOSE) {
+ JobManager.verbose("-> got the following exception while saving:"); //$NON-NLS-1$
+ e.printStackTrace();
+ }
+ //Util.log(e);
+ }
+ } finally {
+ monitor.exitWrite();
+ }
+ }
+ needToSave = false;
+ }
+
+ public void shutdown() {
+ if (VERBOSE)
+ JobManager.verbose("Shutdown"); //$NON-NLS-1$
+//TODO: BOG Put in Shutdown
+/*
+ IndexSelector indexSelector = new IndexSelector(new JavaWorkspaceScope(), null, false, this);
+ IIndex[] selectedIndexes = indexSelector.getIndexes();
+ SimpleLookupTable knownPaths = new SimpleLookupTable();
+ for (int i = 0, max = selectedIndexes.length; i < max; i++) {
+ String path = selectedIndexes[i].getIndexFile().getAbsolutePath();
+ knownPaths.put(path, path);
+ }
+
+ if (indexStates != null) {
+ Object[] indexNames = indexStates.keyTable;
+ for (int i = 0, l = indexNames.length; i < l; i++) {
+ String key = (String) indexNames[i];
+ if (key != null && !knownPaths.containsKey(key))
+ updateIndexState(key, null);
+ }
+ }
+
+ File indexesDirectory = new File(getJavaPluginWorkingLocation().toOSString());
+ if (indexesDirectory.isDirectory()) {
+ File[] indexesFiles = indexesDirectory.listFiles();
+ if (indexesFiles != null) {
+ for (int i = 0, indexesFilesLength = indexesFiles.length; i < indexesFilesLength; i++) {
+ String fileName = indexesFiles[i].getAbsolutePath();
+ if (!knownPaths.containsKey(fileName) && fileName.toLowerCase().endsWith(".index")) { //$NON-NLS-1$
+ if (VERBOSE)
+ JobManager.verbose("Deleting index file " + indexesFiles[i]); //$NON-NLS-1$
+ indexesFiles[i].delete();
+ }
+ }
+ }
+ }
+*/
+ super.shutdown();
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(10);
+ buffer.append(super.toString());
+ buffer.append("In-memory indexes:\n"); //$NON-NLS-1$
+ int count = 0;
+ for (Iterator iter = this.indexes.values().iterator(); iter.hasNext();) {
+ buffer.append(++count).append(" - ").append(iter.next().toString()).append('\n'); //$NON-NLS-1$
+ }
+ return buffer.toString();
+ }
+
+ private char[] readIndexState() {
+ try {
+ return org.eclipse.cdt.internal.core.search.Util.getFileCharContent(savedIndexNamesFile, null);
+ } catch (IOException ignored) {
+ if (VERBOSE)
+ JobManager.verbose("Failed to read saved index file names"); //$NON-NLS-1$
+ return new char[0];
+ }
+ }
+
+ private void updateIndexState(String indexName, Integer indexState) {
+ getIndexStates(); // ensure the states are initialized
+ if (indexState != null) {
+ if (indexState.equals(indexStates.get(indexName))) return; // not changed
+ indexStates.put(indexName, indexState);
+ } else {
+ if (!indexStates.containsKey(indexName)) return; // did not exist anyway
+ indexStates.removeKey(indexName);
+ }
+
+ BufferedWriter writer = null;
+ try {
+ writer = new BufferedWriter(new FileWriter(savedIndexNamesFile));
+ Object[] indexNames = indexStates.keyTable;
+ Object[] states = indexStates.valueTable;
+ for (int i = 0, l = states.length; i < l; i++) {
+ if (states[i] == SAVED_STATE) {
+ writer.write((String) indexNames[i]);
+ writer.write('\n');
+ }
+ }
+ } catch (IOException ignored) {
+ if (VERBOSE)
+ JobManager.verbose("Failed to write saved index file names"); //$NON-NLS-1$
+ } finally {
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException e) {}
+ }
+ }
+ if (VERBOSE) {
+ String state = "?"; //$NON-NLS-1$
+ if (indexState == SAVED_STATE) state = "SAVED"; //$NON-NLS-1$
+ else if (indexState == UPDATING_STATE) state = "UPDATING"; //$NON-NLS-1$
+ else if (indexState == UNKNOWN_STATE) state = "UNKNOWN"; //$NON-NLS-1$
+ else if (indexState == REBUILDING_STATE) state = "REBUILDING"; //$NON-NLS-1$
+ JobManager.verbose("-> index state updated to: " + state + " for: "+indexName); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /*************
+ *TODO: Remove these methods once the new indexer is
+ *fully integrated
+ * START OF TEMP INDEXER ENABLE SECTION
+ */
+ final static String INDEX_MODEL_ID = CCorePlugin.PLUGIN_ID + ".newindexmodel";
+ final static String ACTIVATION = "enable";
+
+ static QualifiedName activationKey = new QualifiedName(INDEX_MODEL_ID, ACTIVATION);
+
+ public boolean isEnabled(IProject project) {
+ String prop = null;
+ try {
+ if (project != null) {
+ prop = project.getPersistentProperty(activationKey);
+ }
+ } catch (CoreException e) {
+ }
+ return ((prop != null) && prop.equalsIgnoreCase("true"));
+ }
+
+ public void setEnabled(IProject project, boolean on) {
+ try {
+ if (project != null) {
+ Boolean newValue = new Boolean(on);
+ Boolean oldValue = new Boolean(isEnabled(project));
+ if (!oldValue.equals(newValue)) {
+ project.setPersistentProperty(activationKey, newValue.toString());
+ if (on) {
+ indexAll(project);
+ } else {
+ //remove(project);
+ }
+ }
+ }
+ } catch (CoreException e) {
+ }
+ }
+
+ /************
+ * END OF TEMP INDEXER ENABLE SECTION
+ */
+
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexRequest.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexRequest.java
new file mode 100644
index 00000000000..e2d73b04adc
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/IndexRequest.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+
+import java.io.IOException;
+
+import org.eclipse.cdt.internal.core.search.processing.IJob;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.cdt.internal.core.index.IIndex;
+
+public abstract class IndexRequest implements IJob {
+ protected boolean isCancelled = false;
+ protected IPath indexPath;
+ protected IndexManager manager;
+
+ public IndexRequest(IPath indexPath, IndexManager manager) {
+ this.indexPath = indexPath;
+ this.manager = manager;
+ }
+
+ public boolean belongsTo(String projectName) {
+ return projectName.equals(this.indexPath.segment(0));
+ }
+
+ public void cancel() {
+ this.manager.jobWasCancelled(this.indexPath);
+ this.isCancelled = true;
+ }
+
+ public boolean isReadyToRun() {
+ // tag the index as inconsistent
+ this.manager.aboutToUpdateIndex(indexPath, updatedIndexState());
+ return true;
+ }
+ /*
+ * This code is assumed to be invoked while monitor has read lock
+ */
+ protected void saveIfNecessary(IIndex index, ReadWriteMonitor monitor) throws IOException {
+ /* if index has changed, commit these before querying */
+ if (index.hasChanged()) {
+ try {
+ monitor.exitRead(); // free read lock
+ monitor.enterWrite(); // ask permission to write
+ this.manager.saveIndex(index);
+ } finally {
+ monitor.exitWriteEnterRead(); // finished writing and reacquire read permission
+ }
+ }
+ }
+
+ protected Integer updatedIndexState() {
+ return IndexManager.UPDATING_STATE;
+ }
+}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/ReadWriteMonitor.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/ReadWriteMonitor.java
new file mode 100644
index 00000000000..3339e5cdfbf
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/ReadWriteMonitor.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on May 30, 2003
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+
+/**
+ * Monitor ensuring no more than one writer working concurrently.
+ * Multiple readers are allowed to perform simultaneously.
+ */
+public class ReadWriteMonitor {
+
+ /**
+ * <0 : writing (cannot go beyond -1, i.e one concurrent writer)
+ * =0 : idle
+ * >0 : reading (number of concurrent readers)
+ */
+ private int status = 0;
+ /**
+ * Concurrent reading is allowed
+ * Blocking only when already writing.
+ */
+ public synchronized void enterRead() {
+
+ while (status < 0){
+ try {
+ wait();
+ } catch(InterruptedException e){
+ }
+ }
+ status++;
+ }
+ /**
+ * Only one writer at a time is allowed to perform
+ * Blocking only when already writing or reading.
+ */
+ public synchronized void enterWrite() {
+
+ while (status != 0){
+ try {
+ wait();
+ } catch(InterruptedException e){
+ }
+ }
+ status--;
+ }
+ /**
+ * Only notify waiting writer(s) if last reader
+ */
+ public synchronized void exitRead() {
+ if (--status == 0) notifyAll();
+ }
+ /**
+ * When writing is over, all readers and possible
+ * writers are granted permission to restart concurrently
+ */
+ public synchronized void exitWrite() {
+ if (++status == 0) notifyAll();
+ }
+ /**
+ * Atomic exitWrite/enterRead: Allows to keep monitor in between
+ * exit write and next enter read.
+ * When writing is over, all readers are granted permissing to restart
+ * concurrently.
+ * This is the same as:
+ * + * synchronized(monitor) { + * monitor.exitWrite(); + * monitor.enterRead(); + * } + *+ */ + public synchronized void exitWriteEnterRead() { + this.exitWrite(); + this.enterRead(); + } +} + diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/RemoveFolderFromIndex.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/RemoveFolderFromIndex.java new file mode 100644 index 00000000000..4f60b863a2a --- /dev/null +++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/RemoveFolderFromIndex.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 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 v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + ******************************************************************************/ +/* + * Created on Jun 1, 2003 + */ +package org.eclipse.cdt.internal.core.search.indexing; + +import java.io.IOException; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.cdt.internal.core.search.Util; +import org.eclipse.cdt.internal.core.index.IIndex; +import org.eclipse.cdt.internal.core.index.IQueryResult; +import org.eclipse.cdt.internal.core.search.processing.JobManager; + +class RemoveFolderFromIndex extends IndexRequest { + IPath folderPath; + char[][] exclusionPatterns; + IProject project; + + public RemoveFolderFromIndex(IPath folderPath, char[][] exclusionPatterns, IProject project, IndexManager manager) { + super(project.getFullPath(), manager); + this.folderPath = folderPath; + this.exclusionPatterns = exclusionPatterns; + this.project = project; + } + + public boolean execute(IProgressMonitor progressMonitor) { + if (progressMonitor != null && progressMonitor.isCanceled()) return true; + + /* ensure no concurrent write access to index */ + IIndex index = manager.getIndex(this.indexPath, true, /*reuse index file*/ false /*create if none*/); + if (index == null) return true; + ReadWriteMonitor monitor = manager.getMonitorFor(index); + if (monitor == null) return true; // index got deleted since acquired + + try { + monitor.enterRead(); // ask permission to read + IQueryResult[] results = index.queryInDocumentNames(this.folderPath.toString()); + // all file names belonging to the folder or its subfolders and that are not excluded (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=32607) + for (int i = 0, max = results == null ? 0 : results.length; i < max; i++) { + String documentPath = results[i].getPath(); + if (this.exclusionPatterns == null || !Util.isExcluded(new Path(documentPath), this.exclusionPatterns)) { + manager.remove(documentPath, this.indexPath); // write lock will be acquired by the remove operation + } + } + } catch (IOException e) { + if (JobManager.VERBOSE) { + JobManager.verbose("-> failed to remove " + this.folderPath + " from index because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ + e.printStackTrace(); + } + return false; + } finally { + monitor.exitRead(); // free read lock + } + return true; + } + + public String toString() { + return "removing " + this.folderPath + " from index " + this.indexPath; //$NON-NLS-1$ //$NON-NLS-2$ + } +} + diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/RemoveFromIndex.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/RemoveFromIndex.java new file mode 100644 index 00000000000..4dc7b8fae5a --- /dev/null +++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/RemoveFromIndex.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 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 v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + ******************************************************************************/ +/* + * Created on Jun 1, 2003 + */ +package org.eclipse.cdt.internal.core.search.indexing; + +import java.io.IOException; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.cdt.internal.core.index.IIndex; +import org.eclipse.cdt.internal.core.search.processing.JobManager; + +class RemoveFromIndex extends IndexRequest { + String resourceName; + + public RemoveFromIndex(String resourceName, IPath indexPath, IndexManager manager) { + super(indexPath, manager); + this.resourceName = resourceName; + } + + public boolean execute(IProgressMonitor progressMonitor) { + + if (progressMonitor != null && progressMonitor.isCanceled()) return true; + + /* ensure no concurrent write access to index */ + IIndex index = manager.getIndex(this.indexPath, true, /*reuse index file*/ false /*create if none*/); + if (index == null) return true; + ReadWriteMonitor monitor = manager.getMonitorFor(index); + if (monitor == null) return true; // index got deleted since acquired + + try { + monitor.enterWrite(); // ask permission to write + index.remove(resourceName); + } catch (IOException e) { + if (JobManager.VERBOSE) { + JobManager.verbose("-> failed to remove " + this.resourceName + " from index because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ + e.printStackTrace(); + } + return false; + } finally { + monitor.exitWrite(); // free write lock + } + return true; + } + + public String toString() { + return "removing " + this.resourceName + " from index " + this.indexPath; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SaveIndex.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SaveIndex.java new file mode 100644 index 00000000000..426b3a46eff --- /dev/null +++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SaveIndex.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 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 v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + ******************************************************************************/ +/* + * Created on Jun 1, 2003 + */ +package org.eclipse.cdt.internal.core.search.indexing; + +import java.io.IOException; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.cdt.internal.core.index.IIndex; +import org.eclipse.cdt.internal.core.search.processing.JobManager; + +/* + * Save the index of a project. + */ +public class SaveIndex extends IndexRequest { + public SaveIndex(IPath indexPath, IndexManager manager) { + super(indexPath, manager); + } + + public boolean execute(IProgressMonitor progressMonitor) { + if (progressMonitor != null && progressMonitor.isCanceled()) return true; + + /* ensure no concurrent write access to index */ + IIndex index = this.manager.getIndex(this.indexPath, true /*reuse index file*/, false /*don't create if none*/); + if (index == null) return true; + ReadWriteMonitor monitor = this.manager.getMonitorFor(index); + if (monitor == null) return true; // index got deleted since acquired + + try { + monitor.enterWrite(); // ask permission to write + this.manager.saveIndex(index); + } catch (IOException e) { + if (JobManager.VERBOSE) { + JobManager.verbose("-> failed to save index " + this.indexPath + " because of the following exception:"); //$NON-NLS-1$ //$NON-NLS-2$ + e.printStackTrace(); + } + return false; + } finally { + monitor.exitWrite(); // free write lock + } + return true; + } + + public String toString() { + return "saving index for " + this.indexPath; //$NON-NLS-1$ + } +} diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SourceIndexer.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SourceIndexer.java new file mode 100644 index 00000000000..edf305dd989 --- /dev/null +++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SourceIndexer.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 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 v0.5 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v05.html + ******************************************************************************/ +/* + * Created on Jun 1, 2003 + */ +package org.eclipse.cdt.internal.core.search.indexing; + +/** + * @author bgheorgh +*/ + +import java.io.IOException; +import java.io.StringReader; + +import org.eclipse.core.resources.IFile; +import org.eclipse.cdt.core.parser.IParser; +import org.eclipse.cdt.core.parser.ParserFactory; +import org.eclipse.cdt.core.parser.ParserMode; +import org.eclipse.cdt.internal.core.index.IDocument; + +/** + * A SourceIndexer indexes source files using the parser. The following items are indexed: + * Declarations: + * - Classes + * - Structs + * - Unions + * References: + * - Classes + * - Structs + * - Unions + */ +public class SourceIndexer extends AbstractIndexer { + + //TODO: Indexer, add additional file types + public static final String[] FILE_TYPES= new String[] {"cpp","h"}; //$NON-NLS-1$ + //protected DefaultProblemFactory problemFactory= new DefaultProblemFactory(Locale.getDefault()); + IFile resourceFile; + + SourceIndexer(IFile resourceFile) { + this.resourceFile = resourceFile; + } + /** + * Returns the file types the
IIndexer
handles.
+ */
+ public String[] getFileTypes(){
+ return FILE_TYPES;
+ }
+
+ protected void indexFile(IDocument document) throws IOException {
+ // Add the name of the file to the index
+ output.addDocument(document);
+ // Create a new Parser
+ SourceIndexerRequestor requestor = new SourceIndexerRequestor(this, document);
+ IParser parser = ParserFactory.createParser(
+ ParserFactory.createScanner( new StringReader( document.getStringContent() ), document.getName(), null, null, ParserMode.QUICK_PARSE ),
+ requestor, ParserMode.QUICK_PARSE);
+ try{
+ parser.parse();
+ }
+ catch( Exception e ){
+ System.out.println( "Parse Exception in SourceIndexer" );
+ e.printStackTrace();
+ }
+ }
+ /**
+ * Sets the document types the IIndexer
handles.
+ */
+
+ public void setFileTypes(String[] fileTypes){}
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SourceIndexerRequestor.java b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SourceIndexerRequestor.java
new file mode 100644
index 00000000000..600725b9b0e
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/indexing/SourceIndexerRequestor.java
@@ -0,0 +1,1066 @@
+/*******************************************************************************
+ * Copyright (c) 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 v0.5
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v05.html
+ ******************************************************************************/
+/*
+ * Created on Jun 13, 2003
+ *
+ * To change the template for this generated file go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+package org.eclipse.cdt.internal.core.search.indexing;
+
+/**
+* @author bgheorgh
+*/
+
+import org.eclipse.cdt.core.parser.IParser;
+import org.eclipse.cdt.core.parser.IParserCallback;
+import org.eclipse.cdt.core.parser.IProblem;
+import org.eclipse.cdt.core.parser.ISourceElementRequestor;
+import org.eclipse.cdt.core.parser.IToken;
+import org.eclipse.cdt.core.parser.ast.IASTASMDefinition;
+import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTCompilationUnit;
+import org.eclipse.cdt.core.parser.ast.IASTConstructor;
+import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier;
+import org.eclipse.cdt.core.parser.ast.IASTField;
+import org.eclipse.cdt.core.parser.ast.IASTFunction;
+import org.eclipse.cdt.core.parser.ast.IASTInclusion;
+import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification;
+import org.eclipse.cdt.core.parser.ast.IASTMacro;
+import org.eclipse.cdt.core.parser.ast.IASTMethod;
+import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation;
+import org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization;
+import org.eclipse.cdt.core.parser.ast.IASTTypedef;
+import org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration;
+import org.eclipse.cdt.core.parser.ast.IASTUsingDirective;
+import org.eclipse.cdt.core.parser.ast.IASTVariable;
+import org.eclipse.cdt.internal.core.index.IDocument;
+
+/**
+ * @author bgheorgh
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+public class SourceIndexerRequestor implements IParserCallback,ISourceElementRequestor, IIndexConstants {
+
+ SourceIndexer indexer;
+ IDocument document;
+
+ char[] packageName;
+ char[][] enclosingTypeNames = new char[5][];
+ int depth = 0;
+ int methodDepth = 0;
+
+ public SourceIndexerRequestor(SourceIndexer indexer, IDocument document) {
+ super();
+ this.indexer = indexer;
+ this.document= document;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptProblem(org.eclipse.cdt.core.parser.IProblem)
+ */
+ public void acceptProblem(IProblem problem) {
+ // TODO Auto-generated method stub
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptMacro(org.eclipse.cdt.core.parser.ast.IASTMacro)
+ */
+ public void acceptMacro(IASTMacro macro) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptMacro");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptVariable(org.eclipse.cdt.core.parser.ast.IASTVariable)
+ */
+ public void acceptVariable(IASTVariable variable) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptVariable");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptFunctionDeclaration(org.eclipse.cdt.core.parser.ast.IASTFunction)
+ */
+ public void acceptFunctionDeclaration(IASTFunction function) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptFunctionDeclaration");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptUsingDirective(org.eclipse.cdt.core.parser.ast.IASTUsingDirective)
+ */
+ public void acceptUsingDirective(IASTUsingDirective usageDirective) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptUsingDirective");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptUsingDeclaration(org.eclipse.cdt.core.parser.ast.IASTUsingDeclaration)
+ */
+ public void acceptUsingDeclaration(IASTUsingDeclaration usageDeclaration) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptUsingDeclaration");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptASMDefinition(org.eclipse.cdt.core.parser.ast.IASTASMDefinition)
+ */
+ public void acceptASMDefinition(IASTASMDefinition asmDefinition) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptASMDefinition");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptTypedef(org.eclipse.cdt.core.parser.ast.IASTTypedef)
+ */
+ public void acceptTypedef(IASTTypedef typedef) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptTypedef");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptEnumerationSpecifier(org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier)
+ */
+ public void acceptEnumerationSpecifier(IASTEnumerationSpecifier enumeration) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptEnumSpecifier");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterFunctionBody(org.eclipse.cdt.core.parser.ast.IASTFunction)
+ */
+ public void enterFunctionBody(IASTFunction function) {
+ // TODO Auto-generated method stub
+ //System.out.println("enterFunctionBody");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitFunctionBody(org.eclipse.cdt.core.parser.ast.IASTFunction)
+ */
+ public void exitFunctionBody(IASTFunction function) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitFunctionBody");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterCompilationUnit(org.eclipse.cdt.core.parser.ast.IASTCompilationUnit)
+ */
+ public void enterCompilationUnit(IASTCompilationUnit compilationUnit) {
+ // TODO Auto-generated method stub
+ //System.out.println("enterCompilationUnit");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterInclusion(org.eclipse.cdt.core.parser.ast.IASTInclusion)
+ */
+ public void enterInclusion(IASTInclusion inclusion) {
+ // TODO Auto-generated method stub
+
+ //System.out.println("NEW INCLUSION \nInclusion short name: " + inclusion.getName());
+ //System.out.println("Inclusion Long Name: " + inclusion.getFullFileName());
+ //System.out.println("enterInclusion");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterNamespaceDefinition(org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition)
+ */
+ public void enterNamespaceDefinition(IASTNamespaceDefinition namespaceDefinition) {
+ // TODO Auto-generated method stub
+ //System.out.println("enterNamespaceDefinition");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterClassSpecifier(org.eclipse.cdt.core.parser.ast.IASTClassSpecifier)
+ */
+ public void enterClassSpecifier(IASTClassSpecifier classSpecification) {
+ // TODO Auto-generated method stub
+
+ //System.out.println("New class spec: " + classSpecification.getName());
+ indexer.addClassSpecifier(classSpecification);
+ //System.out.println("enterClassSpecifier");
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterLinkageSpecification(org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification)
+ */
+ public void enterLinkageSpecification(IASTLinkageSpecification linkageSpec) {
+ // TODO Auto-generated method stub
+ //System.out.println("enterLinkageSpecification");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterTemplateDeclaration(org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration)
+ */
+ public void enterTemplateDeclaration(IASTTemplateDeclaration declaration) {
+ // TODO Auto-generated method stub
+ //System.out.println("enterTemplateDeclaration");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterTemplateSpecialization(org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization)
+ */
+ public void enterTemplateSpecialization(IASTTemplateSpecialization specialization) {
+ // TODO Auto-generated method stub
+ //System.out.println("enterTemplateSpecialization");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterTemplateExplicitInstantiation(org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation)
+ */
+ public void enterTemplateExplicitInstantiation(IASTTemplateInstantiation instantiation) {
+ // TODO Auto-generated method stub
+ //System.out.println("enterTemplateExplicitInstantiation");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptMethodDeclaration(org.eclipse.cdt.core.parser.ast.IASTMethod)
+ */
+ public void acceptMethodDeclaration(IASTMethod method) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptMethodDeclaration");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#enterMethodBody(org.eclipse.cdt.core.parser.ast.IASTMethod)
+ */
+ public void enterMethodBody(IASTMethod method) {
+ // TODO Auto-generated method stub
+ //System.out.println("enterMethodBody");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitMethodBody(org.eclipse.cdt.core.parser.ast.IASTMethod)
+ */
+ public void exitMethodBody(IASTMethod method) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitMethodBody");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptField(org.eclipse.cdt.core.parser.ast.IASTField)
+ */
+ public void acceptField(IASTField field) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptField");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptConstructor(org.eclipse.cdt.core.parser.ast.IASTConstructor)
+ */
+ public void acceptConstructor(IASTConstructor constructor) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptConstructor");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptClassReference(org.eclipse.cdt.core.parser.ast.IASTClassSpecifier, int)
+ */
+ public void acceptClassReference(IASTClassSpecifier classSpecifier,int referenceOffset) {
+ // TODO Auto-generated method stub
+ //System.out.println("acceptClassReference");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitTemplateDeclaration(org.eclipse.cdt.core.parser.ast.IASTTemplateDeclaration)
+ */
+ public void exitTemplateDeclaration(IASTTemplateDeclaration declaration) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitTemplateDeclaration");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitTemplateSpecialization(org.eclipse.cdt.core.parser.ast.IASTTemplateSpecialization)
+ */
+ public void exitTemplateSpecialization(IASTTemplateSpecialization specialization) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitTemplateSpecialization");
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitTemplateExplicitInstantiation(org.eclipse.cdt.core.parser.ast.IASTTemplateInstantiation)
+ */
+ public void exitTemplateExplicitInstantiation(IASTTemplateInstantiation instantiation) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitTemplateExplicitInstantiation");
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitLinkageSpecification(org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification)
+ */
+ public void exitLinkageSpecification(IASTLinkageSpecification linkageSpec) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitLinkageSpecification");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitClassSpecifier(org.eclipse.cdt.core.parser.ast.IASTClassSpecifier)
+ */
+ public void exitClassSpecifier(IASTClassSpecifier classSpecification) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitClassSpecifier");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitNamespaceDefinition(org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition)
+ */
+ public void exitNamespaceDefinition(IASTNamespaceDefinition namespaceDefinition) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitNamespaceDefinition");
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitInclusion(org.eclipse.cdt.core.parser.ast.IASTInclusion)
+ */
+ public void exitInclusion(IASTInclusion inclusion) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitInclusion");
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#exitCompilationUnit(org.eclipse.cdt.core.parser.ast.IASTCompilationUnit)
+ */
+ public void exitCompilationUnit(IASTCompilationUnit compilationUnit) {
+ // TODO Auto-generated method stub
+ //System.out.println("exitCompilationUnit");
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#setParser(org.eclipse.cdt.core.parser.IParser)
+ */
+ public void setParser(IParser parser) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#translationUnitBegin()
+ */
+ public Object translationUnitBegin() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#translationUnitEnd(java.lang.Object)
+ */
+ public void translationUnitEnd(Object unit) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#inclusionBegin(java.lang.String, int, int, boolean)
+ */
+ public Object inclusionBegin(String includeFile, int nameBeginOffset, int inclusionBeginOffset, boolean local) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#inclusionEnd(java.lang.Object)
+ */
+ public void inclusionEnd(Object inclusion) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#macro(java.lang.String, int, int, int)
+ */
+ public Object macro(String macroName, int macroNameOffset, int macroBeginOffset, int macroEndOffset) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#simpleDeclarationBegin(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public Object simpleDeclarationBegin(Object Container, IToken firstToken) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#simpleDeclSpecifier(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void simpleDeclSpecifier(Object Container, IToken specifier) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#simpleDeclSpecifierName(java.lang.Object)
+ */
+ public void simpleDeclSpecifierName(Object declaration) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#simpleDeclSpecifierType(java.lang.Object, java.lang.Object)
+ */
+ public void simpleDeclSpecifierType(Object declaration, Object type) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#simpleDeclarationEnd(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void simpleDeclarationEnd(Object declaration, IToken lastToken) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#parameterDeclarationBegin(java.lang.Object)
+ */
+ public Object parameterDeclarationBegin(Object Container) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#parameterDeclarationEnd(java.lang.Object)
+ */
+ public void parameterDeclarationEnd(Object declaration) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#nameBegin(org.eclipse.cdt.core.parser.IToken)
+ */
+ public void nameBegin(IToken firstToken) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#nameEnd(org.eclipse.cdt.core.parser.IToken)
+ */
+ public void nameEnd(IToken lastToken) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#declaratorBegin(java.lang.Object)
+ */
+ public Object declaratorBegin(Object container) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#declaratorId(java.lang.Object)
+ */
+ public void declaratorId(Object declarator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#declaratorAbort(java.lang.Object)
+ */
+ public void declaratorAbort(Object declarator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#declaratorPureVirtual(java.lang.Object)
+ */
+ public void declaratorPureVirtual(Object declarator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#declaratorCVModifier(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void declaratorCVModifier(Object declarator, IToken modifier) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#declaratorThrowsException(java.lang.Object)
+ */
+ public void declaratorThrowsException(Object declarator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#declaratorThrowExceptionName(java.lang.Object)
+ */
+ public void declaratorThrowExceptionName(Object declarator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#declaratorEnd(java.lang.Object)
+ */
+ public void declaratorEnd(Object declarator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#arrayDeclaratorBegin(java.lang.Object)
+ */
+ public Object arrayDeclaratorBegin(Object declarator) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#arrayDeclaratorEnd(java.lang.Object)
+ */
+ public void arrayDeclaratorEnd(Object arrayQualifier) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#pointerOperatorBegin(java.lang.Object)
+ */
+ public Object pointerOperatorBegin(Object container) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#pointerOperatorType(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void pointerOperatorType(Object ptrOperator, IToken type) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#pointerOperatorName(java.lang.Object)
+ */
+ public void pointerOperatorName(Object ptrOperator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#pointerOperatorCVModifier(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void pointerOperatorCVModifier(Object ptrOperator, IToken modifier) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#pointerOperatorAbort(java.lang.Object)
+ */
+ public void pointerOperatorAbort(Object ptrOperator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#pointerOperatorEnd(java.lang.Object)
+ */
+ public void pointerOperatorEnd(Object ptrOperator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#argumentsBegin(java.lang.Object)
+ */
+ public Object argumentsBegin(Object declarator) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#argumentsEnd(java.lang.Object)
+ */
+ public void argumentsEnd(Object parameterDeclarationClause) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#functionBodyBegin(java.lang.Object)
+ */
+ public Object functionBodyBegin(Object declaration) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#functionBodyEnd(java.lang.Object)
+ */
+ public void functionBodyEnd(Object functionBody) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#classSpecifierBegin(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public Object classSpecifierBegin(Object container, IToken classKey) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#classSpecifierName(java.lang.Object)
+ */
+ public void classSpecifierName(Object classSpecifier) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#classSpecifierAbort(java.lang.Object)
+ */
+ public void classSpecifierAbort(Object classSpecifier) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#classMemberVisibility(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void classMemberVisibility(Object classSpecifier, IToken visibility) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#classSpecifierEnd(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void classSpecifierEnd(Object classSpecifier, IToken closingBrace) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#baseSpecifierBegin(java.lang.Object)
+ */
+ public Object baseSpecifierBegin(Object containingClassSpec) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#baseSpecifierName(java.lang.Object)
+ */
+ public void baseSpecifierName(Object baseSpecifier) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#baseSpecifierVisibility(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void baseSpecifierVisibility(Object baseSpecifier, IToken visibility) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#baseSpecifierVirtual(java.lang.Object, boolean)
+ */
+ public void baseSpecifierVirtual(Object baseSpecifier, boolean virtual) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#baseSpecifierEnd(java.lang.Object)
+ */
+ public void baseSpecifierEnd(Object baseSpecifier) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#expressionBegin(java.lang.Object)
+ */
+ public Object expressionBegin(Object container) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#expressionOperator(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void expressionOperator(Object expression, IToken operator) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#expressionTerminal(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void expressionTerminal(Object expression, IToken terminal) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#expressionName(java.lang.Object)
+ */
+ public void expressionName(Object expression) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#expressionAbort(java.lang.Object)
+ */
+ public void expressionAbort(Object expression) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#expressionEnd(java.lang.Object)
+ */
+ public void expressionEnd(Object expression) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#elaboratedTypeSpecifierBegin(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public Object elaboratedTypeSpecifierBegin(Object container, IToken classKey) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#elaboratedTypeSpecifierName(java.lang.Object)
+ */
+ public void elaboratedTypeSpecifierName(Object elab) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#elaboratedTypeSpecifierEnd(java.lang.Object)
+ */
+ public void elaboratedTypeSpecifierEnd(Object elab) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#namespaceDefinitionBegin(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public Object namespaceDefinitionBegin(Object container, IToken namespace) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#namespaceDefinitionId(java.lang.Object)
+ */
+ public void namespaceDefinitionId(Object namespace) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#namespaceDefinitionAbort(java.lang.Object)
+ */
+ public void namespaceDefinitionAbort(Object namespace) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#namespaceDefinitionEnd(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void namespaceDefinitionEnd(Object namespace, IToken closingBrace) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#linkageSpecificationBegin(java.lang.Object, java.lang.String)
+ */
+ public Object linkageSpecificationBegin(Object container, String literal) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#linkageSpecificationEnd(java.lang.Object)
+ */
+ public void linkageSpecificationEnd(Object linkageSpec) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#usingDirectiveBegin(java.lang.Object)
+ */
+ public Object usingDirectiveBegin(Object container) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#usingDirectiveNamespaceId(java.lang.Object)
+ */
+ public void usingDirectiveNamespaceId(Object directive) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#usingDirectiveAbort(java.lang.Object)
+ */
+ public void usingDirectiveAbort(Object directive) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#usingDirectiveEnd(java.lang.Object)
+ */
+ public void usingDirectiveEnd(Object directive) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#usingDeclarationBegin(java.lang.Object)
+ */
+ public Object usingDeclarationBegin(Object container) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#usingDeclarationMapping(java.lang.Object, boolean)
+ */
+ public void usingDeclarationMapping(Object declaration, boolean isTypeName) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#usingDeclarationAbort(java.lang.Object)
+ */
+ public void usingDeclarationAbort(Object declaration) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#usingDeclarationEnd(java.lang.Object)
+ */
+ public void usingDeclarationEnd(Object declaration) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#enumSpecifierBegin(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public Object enumSpecifierBegin(Object container, IToken enumKey) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#enumSpecifierId(java.lang.Object)
+ */
+ public void enumSpecifierId(Object enumSpec) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#enumSpecifierAbort(java.lang.Object)
+ */
+ public void enumSpecifierAbort(Object enumSpec) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#enumSpecifierEnd(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void enumSpecifierEnd(Object enumSpec, IToken closingBrace) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#enumeratorBegin(java.lang.Object)
+ */
+ public Object enumeratorBegin(Object enumSpec) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#enumeratorId(java.lang.Object)
+ */
+ public void enumeratorId(Object enumDefn) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#enumeratorEnd(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void enumeratorEnd(Object enumDefn, IToken lastToken) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#asmDefinition(java.lang.Object, java.lang.String)
+ */
+ public void asmDefinition(Object container, String assemblyCode) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#constructorChainBegin(java.lang.Object)
+ */
+ public Object constructorChainBegin(Object declarator) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#constructorChainAbort(java.lang.Object)
+ */
+ public void constructorChainAbort(Object ctor) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#constructorChainEnd(java.lang.Object)
+ */
+ public void constructorChainEnd(Object ctor) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#constructorChainElementBegin(java.lang.Object)
+ */
+ public Object constructorChainElementBegin(Object ctor) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#constructorChainElementId(java.lang.Object)
+ */
+ public void constructorChainElementId(Object element) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#constructorChainElementEnd(java.lang.Object)
+ */
+ public void constructorChainElementEnd(Object element) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#constructorChainElementExpressionListElementBegin(java.lang.Object)
+ */
+ public Object constructorChainElementExpressionListElementBegin(Object element) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#constructorChainElementExpressionListElementEnd(java.lang.Object)
+ */
+ public void constructorChainElementExpressionListElementEnd(Object expression) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#explicitInstantiationBegin(java.lang.Object)
+ */
+ public Object explicitInstantiationBegin(Object container) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#explicitInstantiationEnd(java.lang.Object)
+ */
+ public void explicitInstantiationEnd(Object instantiation) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#explicitSpecializationBegin(java.lang.Object)
+ */
+ public Object explicitSpecializationBegin(Object container) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#explicitSpecializationEnd(java.lang.Object)
+ */
+ public void explicitSpecializationEnd(Object instantiation) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateDeclarationBegin(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public Object templateDeclarationBegin(Object container, IToken firstToken) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateDeclarationAbort(java.lang.Object)
+ */
+ public void templateDeclarationAbort(Object templateDecl) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateDeclarationEnd(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public void templateDeclarationEnd(Object templateDecl, IToken lastToken) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateParameterListBegin(java.lang.Object)
+ */
+ public Object templateParameterListBegin(Object declaration) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateParameterListEnd(java.lang.Object)
+ */
+ public void templateParameterListEnd(Object parameterList) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateTypeParameterBegin(java.lang.Object, org.eclipse.cdt.core.parser.IToken)
+ */
+ public Object templateTypeParameterBegin(Object templDecl, IToken kind) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateTypeParameterName(java.lang.Object)
+ */
+ public void templateTypeParameterName(Object typeParm) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateTypeParameterAbort(java.lang.Object)
+ */
+ public void templateTypeParameterAbort(Object typeParm) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateTypeParameterInitialTypeId(java.lang.Object)
+ */
+ public void templateTypeParameterInitialTypeId(Object typeParm) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#templateTypeParameterEnd(java.lang.Object)
+ */
+ public void templateTypeParameterEnd(Object typeParm) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#startBitfield(java.lang.Object)
+ */
+ public Object startBitfield(Object declarator) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#endBitfield(java.lang.Object)
+ */
+ public void endBitfield(Object bitfield) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#oldKRParametersBegin(java.lang.Object)
+ */
+ public Object oldKRParametersBegin(Object parameterDeclarationClause) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.IParserCallback#oldKRParametersEnd(java.lang.Object)
+ */
+ public void oldKRParametersEnd(Object oldKRParameterDeclarationClause) {
+ // TODO Auto-generated method stub
+
+ }
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.parser.ISourceElementRequestor#acceptElaboratedTypeSpecifier(org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier)
+ */
+ public void acceptElaboratedTypeSpecifier(IASTElaboratedTypeSpecifier elaboratedTypeSpec) {
+ // TODO Auto-generated method stub
+
+ }
+
+//TODO: Get rid of these IParserCallbacks once the parser cleans up
+
+}
diff --git a/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/messages.properties b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/messages.properties
new file mode 100644
index 00000000000..4338a0aa07d
--- /dev/null
+++ b/core/org.eclipse.cdt.core/index/org/eclipse/cdt/internal/core/search/messages.properties
@@ -0,0 +1,16 @@
+###############################################################################
+# 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
+###############################################################################
+### Eclipse CDT Core Search messages.
+
+engine.searching = Searching...
+exception.wrongFormat = Wrong format
+process.name = CDT Indexer
+manager.filesToIndex = {0} files to index
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java
index bc633e2d40b..eeb2d46844f 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java
@@ -8,6 +8,7 @@ package org.eclipse.cdt.core.model;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.internal.core.model.BatchOperation;
import org.eclipse.cdt.internal.core.model.CModelManager;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
@@ -215,4 +216,14 @@ public class CoreModel {
workspace.run(new BatchOperation(action), monitor);
}
}
+
+ public void startIndexing()
+ {
+ manager.getIndexManager().reset();
+ }
+
+ public IndexManager getIndexManager(){
+ return manager.getIndexManager();
+ }
+
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java
index c6e068246ee..e5287a378a7 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java
@@ -41,6 +41,7 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
public class CModelManager implements IResourceChangeListener {
@@ -755,4 +756,8 @@ public class CModelManager implements IResourceChangeListener {
}
}
+ public IndexManager getIndexManager() {
+ return this.fDeltaProcessor.indexManager;
+ }
+
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java
index f62712e70a2..24fadb21ce8 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DeltaProcessor.java
@@ -19,6 +19,8 @@ import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.runtime.IPath;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
+
/**
* This class is used by CModelManager
to convert
* IResourceDelta
s into ICElementDelta
s.
@@ -31,6 +33,8 @@ public class DeltaProcessor {
* The CElementDelta
corresponding to the IResourceDelta
being translated.
*/
protected CElementDelta fCurrentDelta;
+
+ protected IndexManager indexManager = new IndexManager();
/* The C element that was last created (see createElement(IResource).
* This is used as a stack of C elements (using getParent() to pop it, and
@@ -333,6 +337,7 @@ public class DeltaProcessor {
// get the workspace delta, and start processing there.
IResourceDelta[] deltas = changes.getAffectedChildren();
ICElementDelta[] translatedDeltas = new CElementDelta[deltas.length];
+ System.out.println("delta.length: " + deltas.length);
for (int i = 0; i < deltas.length; i++) {
IResourceDelta delta = deltas[i];
fCurrentDelta = new CElementDelta(root);
@@ -446,9 +451,37 @@ public class DeltaProcessor {
protected void updateIndexAddResource(ICElement element, IResourceDelta delta) {
//CModelManager.getDefault().getIndexManager().addResource(delta.getResource());
+
+ if (indexManager == null)
+ return;
+
+ switch (element.getElementType()) {
+ case ICElement.C_PROJECT :
+ this.indexManager.indexAll(element.getCProject().getProject());
+ break;
+ }
+
}
protected void updateIndexRemoveResource(ICElement element, IResourceDelta delta) {
//CModelManager.getDefault().getIndexManager().removeResource(delta.getResource());
+
+ /*
+ if (indexManager == null)
+ return;
+
+ switch (element.getElementType()) {
+ case ICElement.C_PROJECT :
+ this.indexManager.removeIndexFamily(element.getCProject().getProject().getFullPath());
+ // NB: Discarding index jobs belonging to this project was done during PRE_DELETE
+ break;
+ // NB: Update of index if project is opened, closed, or its java nature is added or removed
+ // is done in updateCurrentDeltaAndIndex
+
+ }
+ */
}
-}
+
+
+ }
+
diff --git a/core/org.eclipse.cdt.core/search/ChangeLog b/core/org.eclipse.cdt.core/search/ChangeLog
new file mode 100644
index 00000000000..c95b5629843
--- /dev/null
+++ b/core/org.eclipse.cdt.core/search/ChangeLog
@@ -0,0 +1,10 @@
+2003-06-25 Bogdan Gheorghe
+
+Modified:
+
+ * search/org/eclipse/cdt/core/search/ICSearchConstants.java
+ * search/org/eclipse/cdt/internal/core/search/Utils.java
+ - moved to index/org/eclipse/cdt/internal/core/search/Utils.java
+ * search/org/eclipse/cdt/internal/core/search/matching/CSearchPattern.java
+ * search/org/eclipse/cdt/internal/core/search/processing/IJob.java
+ * search/org/eclipse/cdt/internal/core/search/processing/JobManager.java
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/core/search/ICSearchConstants.java b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/core/search/ICSearchConstants.java
index 799a94c52d6..d87d276d7f2 100644
--- a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/core/search/ICSearchConstants.java
+++ b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/core/search/ICSearchConstants.java
@@ -9,15 +9,24 @@
* IBM Corp. - Rational Software - initial implementation
******************************************************************************/
/*
- * Created on Jun 11, 2003
+ * Created on May 31, 2003
*/
package org.eclipse.cdt.core.search;
/**
- * @author aniefer
- *
- * To change the template for this generated type comment go to
- * Window>Preferences>Java>Code Generation>Code and Comments
+ * @author bgheorgh
+ */
+import org.eclipse.cdt.internal.core.search.processing.*;
+
+
+/**
+ * + * This interface defines the constants used by the search engine. + *
+ *+ * This interface declares constants only; it is not intended to be implemented. + *
+ * @see org.eclipse.cdt.core.search.SearchEngine */ public interface ICSearchConstants { /** @@ -34,37 +43,56 @@ public interface ICSearchConstants { int TYPE= 0; /** - * The searched element is a method. + * The searched element is a function. */ - int METHOD= 1; + int FUNCTION= 1; /** - * The searched element is a package. - */ - //int PACKAGE= 2; - + * The searched element is a namespace. + */ + int NAMESPACE= 2; + /** * The searched element is a constructor. */ - int CONSTRUCTOR= 2; + int CONSTRUCTOR= 3; /** - * The searched element is a field. + * The searched element is a member. + */ + int MEMBER= 4; + + /** + * The searched element is a variable. + * More selective than using TYPE */ - int FIELD= 3; + int VAR= 5; /** * The searched element is a class. * More selective than using TYPE */ - int CLASS= 4; + int CLASS= 6; /** - * The searched element is an interface. + * The searched element is a struct. * More selective than using TYPE */ - int INTERFACE= 5; + int STRUCT= 7; + /** + * The searched element is a enum. + * More selective than using TYPE + */ + int ENUM= 8; + + /** + * The searched element is a union. + * More selective than using TYPE + */ + int UNION= 9; + + /* Nature of match */ /** @@ -81,7 +109,7 @@ public interface ICSearchConstants { * rather exclusively search for classes implementing an interface, or interfaces * extending an interface. */ - int IMPLEMENTORS= 1; + int DEFINITIONS= 1; /** * The search result is a reference. @@ -100,23 +128,6 @@ public interface ICSearchConstants { */ int ALL_OCCURRENCES= 3; - /** - * When searching for field matches, it will exclusively find read accesses, as - * opposed to write accesses. Note that some expressions are considered both - * as field read/write accesses: for example, x++; x+= 1; - * - * @since 2.0 - */ - int READ_ACCESSES = 4; - - /** - * When searching for field matches, it will exclusively find write accesses, as - * opposed to read accesses. Note that some expressions are considered both - * as field read/write accesses: for example, x++; x+= 1; - * - * @since 2.0 - */ - int WRITE_ACCESSES = 5; /* Syntactic match modes */ @@ -156,17 +167,17 @@ public interface ICSearchConstants { * has not finished indexing the workspace. Results will more likely * not contain all the matches. */ - //int FORCE_IMMEDIATE_SEARCH = IJob.ForceImmediate; + int FORCE_IMMEDIATE_SEARCH = IJob.ForceImmediate; /** * The search operation throws anorg.eclipse.core.runtime.OperationCanceledException
* if the underlying indexer has not finished indexing the workspace.
*/
- //int CANCEL_IF_NOT_READY_TO_SEARCH = IJob.CancelIfNotReady;
+ int CANCEL_IF_NOT_READY_TO_SEARCH = IJob.CancelIfNotReady;
/**
* The search operation waits for the underlying indexer to finish indexing
* the workspace before starting the search.
*/
- //int WAIT_UNTIL_READY_TO_SEARCH = IJob.WaitUntilReady;
-
+ int WAIT_UNTIL_READY_TO_SEARCH = IJob.WaitUntilReady;
+
}
diff --git a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/Util.java b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/Util.java
deleted file mode 100644
index ffcbc0c0887..00000000000
--- a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/Util.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 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 v0.5
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- *
- * Contributors:
- * IBM Corp. - Rational Software - initial implementation
- ******************************************************************************/
-/*
- * Created on Jun 13, 2003
- */
-package org.eclipse.cdt.internal.core.search;
-
-/**
- * @author aniefer
- *
- * To change the template for this generated type comment go to
- * Window>Preferences>Java>Code Generation>Code and Comments
- */
-public class Util {
-
- /**
- *
- */
- public Util() {
- super();
- // TODO Auto-generated constructor stub
- }
-
- /**
- * @param string
- * @return
- */
- public static String bind(String string) {
- // TODO Auto-generated method stub
- return null;
- }
-
-}
diff --git a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/matching/CSearchPattern.java b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/matching/CSearchPattern.java
index c7d01fad707..59b8b10f297 100644
--- a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/matching/CSearchPattern.java
+++ b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/matching/CSearchPattern.java
@@ -52,15 +52,15 @@ public abstract class CSearchPattern
case ICSearchConstants.TYPE:
pattern = createTypePattern( patternString, limitTo, matchMode, caseSensitive );
break;
- case ICSearchConstants.METHOD:
- pattern = createMethodPattern( patternString, limitTo, matchMode, caseSensitive );
- break;
+ //case ICSearchConstants.METHOD:
+ // pattern = createMethodPattern( patternString, limitTo, matchMode, caseSensitive );
+ // break;
case ICSearchConstants.CONSTRUCTOR:
pattern = createConstructorPattern( patternString, limitTo, matchMode, caseSensitive );
break;
- case ICSearchConstants.FIELD:
- pattern = createFieldPattern( patternString, limitTo, matchMode, caseSensitive );
- break;
+ //case ICSearchConstants.FIELD:
+ // pattern = createFieldPattern( patternString, limitTo, matchMode, caseSensitive );
+ // break;
}
return pattern;
diff --git a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/processing/IJob.java b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/processing/IJob.java
index a2169d154f6..b5169701791 100644
--- a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/processing/IJob.java
+++ b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/processing/IJob.java
@@ -9,19 +9,17 @@
* IBM Corp. - Rational Software - initial implementation
******************************************************************************/
/*
- * Created on Jun 13, 2003
+ * Created on May 30, 2003
*/
package org.eclipse.cdt.internal.core.search.processing;
+/**
+ * @author bgheorgh
+ */
import org.eclipse.core.runtime.IProgressMonitor;
-/**
- * @author aniefer
- *
- * To change the template for this generated type comment go to
- * Window>Preferences>Java>Code Generation>Code and Comments
- */
public interface IJob {
+
/* Waiting policies */
int ForceImmediate = 1;
int CancelIfNotReady = 2;
@@ -32,7 +30,7 @@ public interface IJob {
boolean COMPLETE = true;
/**
- * Answer true if the job belongs to a given family (tag)
+ * True if job belongs to the passed in jobFamily
*/
public boolean belongsTo(String jobFamily);
/**
@@ -48,4 +46,5 @@ public interface IJob {
* Answer whether the job is ready to run.
*/
public boolean isReadyToRun();
+
}
diff --git a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/processing/JobManager.java b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/processing/JobManager.java
index 1e0d281df0d..92caddd44e8 100644
--- a/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/processing/JobManager.java
+++ b/core/org.eclipse.cdt.core/search/org/eclipse/cdt/internal/core/search/processing/JobManager.java
@@ -9,32 +9,426 @@
* IBM Corp. - Rational Software - initial implementation
******************************************************************************/
/*
- * Created on Jun 13, 2003
+ * Created on May 30, 2003
*/
package org.eclipse.cdt.internal.core.search.processing;
-/**
- * @author aniefer
- *
- * To change the template for this generated type comment go to
- * Window>Preferences>Java>Code Generation>Code and Comments
- */
-public class JobManager implements Runnable {
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.cdt.internal.core.search.Util;
+
+public abstract class JobManager implements Runnable {
+
+ /* queue of jobs to execute */
+ protected IJob[] awaitingJobs = new IJob[10];
+ protected int jobStart = 0;
+ protected int jobEnd = -1;
+ protected boolean executing = false;
+
+ /* background processing */
+ protected Thread thread;
+
+ /* flag indicating whether job execution is enabled or not */
+ private boolean enabled = true;
+
+ public static boolean VERBOSE = false;
+ /* flag indicating that the activation has completed */
+ public boolean activated = false;
+
+ private int awaitingClients = 0;
+
+ public static void verbose(String log) {
+ System.out.println("(" + Thread.currentThread() + ") " + log); //$NON-NLS-1$//$NON-NLS-2$
+ }
/**
- *
+ * Invoked exactly once, in background, before starting processing any job
*/
- public JobManager() {
- super();
- // TODO Auto-generated constructor stub
+ public void activateProcessing() {
+ this.activated = true;
}
+ /**
+ * Answer the amount of awaiting jobs.
+ */
+ public synchronized int awaitingJobsCount() {
- /* (non-Javadoc)
- * @see java.lang.Runnable#run()
+ // pretend busy in case concurrent job attempts performing before activated
+ if (!activated)
+ return 1;
+
+ return jobEnd - jobStart + 1;
+
+ }
+ /**
+ * Answers the first job in the queue, or null if there is no job available
+ * Until the job has completed, the job manager will keep answering the same job.
+ */
+ public synchronized IJob currentJob() {
+
+ if (!enabled)
+ return null;
+
+ if (jobStart <= jobEnd) {
+ return awaitingJobs[jobStart];
+ }
+ return null;
+ }
+
+ public synchronized void disable() {
+ enabled = false;
+ if (VERBOSE)
+ JobManager.verbose("DISABLING background indexing"); //$NON-NLS-1$
+ }
+ /**
+ * Remove the index from cache for a given project.
+ * Passing null as a job family discards them all.
+ */
+ public void discardJobs(String jobFamily) {
+
+ if (VERBOSE)
+ JobManager.verbose("DISCARD background job family - " + jobFamily); //$NON-NLS-1$
+
+ boolean wasEnabled = isEnabled();
+ try {
+ IJob currentJob;
+ // cancel current job if it belongs to the given family
+ synchronized(this){
+ currentJob = this.currentJob();
+ disable();
+ }
+ if (currentJob != null
+ && (jobFamily == null || currentJob.belongsTo(jobFamily))) {
+
+ currentJob.cancel();
+
+ // wait until current active job has finished
+ while (thread != null && executing){
+ try {
+ if (VERBOSE)
+ JobManager.verbose("-> waiting end of current background job - " + currentJob); //$NON-NLS-1$ //$NON-NLS-2$
+ Thread.sleep(50);
+ } catch(InterruptedException e){
+ }
+ }
+ }
+
+ // flush and compact awaiting jobs
+ int loc = -1;
+ synchronized(this) {
+ for (int i = jobStart; i <= jobEnd; i++) {
+ currentJob = awaitingJobs[i];
+ awaitingJobs[i] = null;
+ if (!(jobFamily == null
+ || currentJob.belongsTo(jobFamily))) { // copy down, compacting
+ awaitingJobs[++loc] = currentJob;
+ } else {
+ if (VERBOSE)
+ JobManager.verbose("-> discarding background job - " + currentJob); //$NON-NLS-1$
+ currentJob.cancel();
+ }
+ }
+ jobStart = 0;
+ jobEnd = loc;
+ }
+ } finally {
+ if (wasEnabled)
+ enable();
+ }
+ if (VERBOSE)
+ JobManager.verbose("DISCARD DONE with background job family - " + jobFamily); //$NON-NLS-1$
+ }
+
+ public synchronized void enable() {
+ enabled = true;
+ if (VERBOSE)
+ JobManager.verbose("ENABLING background indexing"); //$NON-NLS-1$
+ }
+
+ public synchronized boolean isEnabled() {
+ return enabled;
+ }
+ /**
+ * Advance to the next available job, once the current one has been completed.
+ * Note: clients awaiting until the job count is zero are still waiting at this point.
+ */
+ protected synchronized void moveToNextJob() {
+
+ //if (!enabled) return;
+
+ if (jobStart <= jobEnd) {
+ awaitingJobs[jobStart++] = null;
+ if (jobStart > jobEnd) {
+ jobStart = 0;
+ jobEnd = -1;
+ }
+ }
+ }
+ /**
+ * When idle, give chance to do something
+ */
+ protected void notifyIdle(long idlingTime) {
+ }
+ /**
+ * This API is allowing to run one job in concurrence with background processing.
+ * Indeed since other jobs are performed in background, resource sharing might be
+ * an issue.Therefore, this functionality allows a given job to be run without
+ * colliding with background ones.
+ * Note: multiple thread might attempt to perform concurrent jobs at the same time,
+ * and should synchronize (it is deliberately left to clients to decide whether
+ * concurrent jobs might interfere or not. In general, multiple read jobs are ok).
+ *
+ * Waiting policy can be:
+ * IJobConstants.ForceImmediateSearch
+ * IJobConstants.CancelIfNotReadyToSearch
+ * IJobConstants.WaitUntilReadyToSearch
+ *
+ */
+ public boolean performConcurrentJob(
+ IJob searchJob,
+ int waitingPolicy,
+ IProgressMonitor progress) {
+
+ if (VERBOSE)
+ JobManager.verbose("STARTING concurrent job - " + searchJob); //$NON-NLS-1$
+ if (!searchJob.isReadyToRun()) {
+ if (VERBOSE)
+ JobManager.verbose("ABORTED concurrent job - " + searchJob); //$NON-NLS-1$
+ return IJob.FAILED;
+ }
+
+ int concurrentJobWork = 100;
+ if (progress != null)
+ progress.beginTask("", concurrentJobWork); //$NON-NLS-1$
+ boolean status = IJob.FAILED;
+ if (awaitingJobsCount() > 0) {
+ switch (waitingPolicy) {
+
+ case IJob.ForceImmediate :
+ if (VERBOSE)
+ JobManager.verbose("-> NOT READY - forcing immediate - " + searchJob);//$NON-NLS-1$
+ boolean wasEnabled = isEnabled();
+ try {
+ disable(); // pause indexing
+ status = searchJob.execute(progress == null ? null : new SubProgressMonitor(progress, concurrentJobWork));
+ } finally {
+ if (wasEnabled)
+ enable();
+ }
+ if (VERBOSE)
+ JobManager.verbose("FINISHED concurrent job - " + searchJob); //$NON-NLS-1$
+ return status;
+
+ case IJob.CancelIfNotReady :
+ if (VERBOSE)
+ JobManager.verbose("-> NOT READY - cancelling - " + searchJob); //$NON-NLS-1$
+ if (progress != null) progress.setCanceled(true);
+ if (VERBOSE)
+ JobManager.verbose("CANCELED concurrent job - " + searchJob); //$NON-NLS-1$
+ throw new OperationCanceledException();
+
+ case IJob.WaitUntilReady :
+ int awaitingWork;
+ IJob previousJob = null;
+ IJob currentJob;
+ IProgressMonitor subProgress = null;
+ int totalWork = this.awaitingJobsCount();
+ if (progress != null && totalWork > 0) {
+ subProgress = new SubProgressMonitor(progress, concurrentJobWork / 2);
+ subProgress.beginTask("", totalWork); //$NON-NLS-1$
+ concurrentJobWork = concurrentJobWork / 2;
+ }
+ int originalPriority = this.thread.getPriority();
+ try {
+ synchronized(this) {
+
+ // use local variable to avoid potential NPE (see Bug 20435 NPE when searching java method)
+ Thread t = this.thread;
+ if (t != null) {
+ t.setPriority(Thread.currentThread().getPriority());
+ }
+ this.awaitingClients++;
+ }
+ while ((awaitingWork = awaitingJobsCount()) > 0) {
+ if (subProgress != null && subProgress.isCanceled())
+ throw new OperationCanceledException();
+ currentJob = currentJob();
+ // currentJob can be null when jobs have been added to the queue but job manager is not enabled
+ if (currentJob != null && currentJob != previousJob) {
+ if (VERBOSE)
+ JobManager.verbose("-> NOT READY - waiting until ready - " + searchJob);//$NON-NLS-1$
+ if (subProgress != null) {
+ subProgress.subTask(
+ Util.bind("manager.filesToIndex", Integer.toString(awaitingWork))); //$NON-NLS-1$
+ subProgress.worked(1);
+ }
+ previousJob = currentJob;
+ }
+ try {
+ Thread.sleep(50);
+ } catch (InterruptedException e) {
+ }
+ }
+ } finally {
+ synchronized(this) {
+ this.awaitingClients--;
+
+ // use local variable to avoid potential NPE (see Bug 20435 NPE when searching java method)
+ Thread t = this.thread;
+ if (t != null) {
+ t.setPriority(originalPriority);
+ }
+ }
+ }
+ if (subProgress != null) {
+ subProgress.done();
+ }
+ }
+ }
+ status = searchJob.execute(progress == null ? null : new SubProgressMonitor(progress, concurrentJobWork));
+ if (progress != null) {
+ progress.done();
+ }
+ if (VERBOSE)
+ JobManager.verbose("FINISHED concurrent job - " + searchJob); //$NON-NLS-1$
+ return status;
+ }
+
+ public abstract String processName();
+
+ public synchronized void request(IJob job) {
+ if (!job.isReadyToRun()) {
+ if (VERBOSE)
+ JobManager.verbose("ABORTED request of background job - " + job); //$NON-NLS-1$
+ return;
+ }
+
+ // append the job to the list of ones to process later on
+ int size = awaitingJobs.length;
+ if (++jobEnd == size) { // when growing, relocate jobs starting at position 0
+ jobEnd -= jobStart;
+ System.arraycopy(
+ awaitingJobs,
+ jobStart,
+ (awaitingJobs = new IJob[size * 2]),
+ 0,
+ jobEnd);
+ jobStart = 0;
+ }
+ awaitingJobs[jobEnd] = job;
+ if (VERBOSE)
+ JobManager.verbose("REQUEST background job - " + job); //$NON-NLS-1$
+
+ }
+ /**
+ * Flush current state
+ */
+ public void reset() {
+ if (VERBOSE)
+ JobManager.verbose("Reset"); //$NON-NLS-1$
+
+ if (thread != null) {
+ discardJobs(null); // discard all jobs
+ } else {
+ /* initiate background processing */
+ thread = new Thread(this, this.processName());
+ thread.setDaemon(true);
+ // less prioritary by default, priority is raised if clients are actively waiting on it
+ thread.setPriority(Thread.NORM_PRIORITY-1);
+ thread.start();
+ }
+ }
+ /**
+ * Infinite loop performing resource indexing
*/
public void run() {
- // TODO Auto-generated method stub
+ long idlingStart = -1;
+ activateProcessing();
+ try {
+ while (this.thread != null) {
+ try {
+ IJob job;
+ if ((job = currentJob()) == null) {
+ if (idlingStart < 0)
+ idlingStart = System.currentTimeMillis();
+ notifyIdle(System.currentTimeMillis() - idlingStart);
+ Thread.sleep(500);
+ continue;
+ } else {
+ idlingStart = -1;
+ }
+ if (VERBOSE) {
+ JobManager.verbose(awaitingJobsCount() + " awaiting jobs"); //$NON-NLS-1$
+ JobManager.verbose("STARTING background job - " + job); //$NON-NLS-1$
+ }
+ try {
+ executing = true;
+ /*boolean status = */job.execute(null);
+ //if (status == FAILED) request(job);
+ } finally {
+ executing = false;
+ if (VERBOSE) {
+ JobManager.verbose("FINISHED background job - " + job); //$NON-NLS-1$
+ }
+ moveToNextJob();
+ if (this.awaitingClients == 0) {
+ Thread.sleep(50);
+ }
+ }
+ } catch (InterruptedException e) { // background indexing was interrupted
+ }
+ }
+ } catch (RuntimeException e) {
+ if (this.thread != null) { // if not shutting down
+ // log exception
+ org.eclipse.cdt.internal.core.model.Util.log(e, "Background Indexer Crash Recovery"); //$NON-NLS-1$
+
+ // keep job manager alive
+ this.discardJobs(null);
+ this.thread = null;
+ this.reset(); // this will fork a new thread with no waiting jobs, some indexes will be inconsistent
+ }
+ throw e;
+ } catch (Error e) {
+ if (this.thread != null && !(e instanceof ThreadDeath)) {
+ // log exception
+ org.eclipse.cdt.internal.core.model.Util.log(e, "Background Indexer Crash Recovery"); //$NON-NLS-1$
+
+ // keep job manager alive
+ this.discardJobs(null);
+ this.thread = null;
+ this.reset(); // this will fork a new thread with no waiting jobs, some indexes will be inconsistent
+ }
+ throw e;
+ }
}
+ /**
+ * Stop background processing, and wait until the current job is completed before returning
+ */
+ public void shutdown() {
+
+ disable();
+ discardJobs(null); // will wait until current executing job has completed
+ Thread thread = this.thread;
+ this.thread = null; // mark the job manager as shutting down so that the thread will stop by itself
+ try {
+ if (thread != null) { // see http://bugs.eclipse.org/bugs/show_bug.cgi?id=31858
+ thread.join();
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+
+ public String toString() {
+ StringBuffer buffer = new StringBuffer(10);
+ buffer.append("Enabled:").append(this.enabled).append('\n'); //$NON-NLS-1$
+ int numJobs = jobEnd - jobStart + 1;
+ buffer.append("Jobs in queue:").append(numJobs).append('\n'); //$NON-NLS-1$
+ for (int i = 0; i < numJobs && i < 15; i++) {
+ buffer.append(i).append(" - job["+i+"]: ").append(awaitingJobs[jobStart+i]).append('\n'); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return buffer.toString();
+ }
}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
index a4fbcc2eb61..f190526499c 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CCorePlugin.java
@@ -139,7 +139,10 @@ public class CCorePlugin extends Plugin {
// Fired up the indexer. It should delay itself for 10 seconds
fIndexModel = IndexModel.getDefault();
fIndexModel.startup();
-
+
+ //Fired up the new indexer
+ fCoreModel.startIndexing();
+
fDescriptorManager = new CDescriptorManager();
fDescriptorManager.startup();
diff --git a/core/org.eclipse.cdt.ui/ChangeLog b/core/org.eclipse.cdt.ui/ChangeLog
index 52b95a38aa5..2a2ac8dfaed 100644
--- a/core/org.eclipse.cdt.ui/ChangeLog
+++ b/core/org.eclipse.cdt.ui/ChangeLog
@@ -13,6 +13,14 @@
Began structuring expressions and declarators in Parser for ISourceElementRequestor.
Updated other packages to use new interfaces.
+2003-06-25 Bogdan Gheorghe
+ Added a new checkbox to the Indexer tab of the C/C++ Project Settings
+ to allow the new indexer to be turned on or off.
+ * src/org/eclipse/cdt/ui/wizards/IndexerBlock.java
+
+ Modified the CSearchPage to work with the new CSearchConstants
+ * src/org/eclipse/cdt/internal/ui/search/CSearchPage.java
+
2003-06-24 Thomas Fletcher
- Proposals will now include additional help information with them
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchPage.java
index 0ac73c9941a..9610d13c4cf 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchPage.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/CSearchPage.java
@@ -161,8 +161,8 @@ public class CSearchPage extends DialogPage implements ISearchPage, ICSearchCons
};
fSearchFor[ TYPE ].addSelectionListener(cElementInitializer);
- fSearchFor[ METHOD ].addSelectionListener(cElementInitializer);
- fSearchFor[ FIELD ].addSelectionListener(cElementInitializer);
+ fSearchFor[ FUNCTION ].addSelectionListener(cElementInitializer);
+ fSearchFor[ MEMBER ].addSelectionListener(cElementInitializer);
fSearchFor[CONSTRUCTOR].addSelectionListener(cElementInitializer);
//fSearchFor[ PACKAGE ].addSelectionListener(cElementInitializer);
@@ -283,34 +283,34 @@ public class CSearchPage extends DialogPage implements ISearchPage, ICSearchCons
}
private void setLimitTo(int searchFor) {
fLimitTo[ DECLARATIONS ].setEnabled( true );
- fLimitTo[ IMPLEMENTORS ].setEnabled( false);
+ //fLimitTo[ IMPLEMENTORS ].setEnabled( false);
fLimitTo[ REFERENCES ].setEnabled( true );
fLimitTo[ ALL_OCCURRENCES ].setEnabled( true );
- fLimitTo[ READ_ACCESSES ].setEnabled( false);
- fLimitTo[ WRITE_ACCESSES ].setEnabled( false);
+ //fLimitTo[ READ_ACCESSES ].setEnabled( false);
+ //fLimitTo[ WRITE_ACCESSES ].setEnabled( false);
- if (!(searchFor == TYPE || searchFor == INTERFACE) && fLimitTo[IMPLEMENTORS].getSelection()) {
- fLimitTo[ IMPLEMENTORS ].setSelection(false);
- fLimitTo[ REFERENCES ].setSelection(true);
- }
-
- if (!(searchFor == FIELD) && (getLimitTo() == READ_ACCESSES || getLimitTo() == WRITE_ACCESSES)) {
- fLimitTo[ getLimitTo()].setSelection(false);
- fLimitTo[ REFERENCES ].setSelection(true);
- }
-
- switch (searchFor) {
- case TYPE:
- case INTERFACE:
- fLimitTo[ IMPLEMENTORS ].setEnabled(true);
- break;
- case FIELD:
- fLimitTo[ READ_ACCESSES ].setEnabled(true);
- fLimitTo[ WRITE_ACCESSES ].setEnabled(true);
- break;
- default :
- break;
- }
+// if (!(searchFor == TYPE || searchFor == INTERFACE) && fLimitTo[IMPLEMENTORS].getSelection()) {
+// fLimitTo[ IMPLEMENTORS ].setSelection(false);
+// fLimitTo[ REFERENCES ].setSelection(true);
+// }
+//
+// if (!(searchFor == FIELD) && (getLimitTo() == READ_ACCESSES || getLimitTo() == WRITE_ACCESSES)) {
+// fLimitTo[ getLimitTo()].setSelection(false);
+// fLimitTo[ REFERENCES ].setSelection(true);
+// }
+//
+// switch (searchFor) {
+// case TYPE:
+// case INTERFACE:
+// fLimitTo[ IMPLEMENTORS ].setEnabled(true);
+// break;
+// case FIELD:
+// fLimitTo[ READ_ACCESSES ].setEnabled(true);
+// fLimitTo[ WRITE_ACCESSES ].setEnabled(true);
+// break;
+// default :
+// break;
+// }
}
private Control createSearchFor(Composite parent) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/IndexerBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/IndexerBlock.java
index cfbf3f26e36..3cfbc96147e 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/IndexerBlock.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/IndexerBlock.java
@@ -7,6 +7,7 @@ package org.eclipse.cdt.ui.wizards;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IndexModel;
+import org.eclipse.cdt.internal.core.search.indexing.IndexManager;
import org.eclipse.cdt.utils.ui.swt.IValidation;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
@@ -18,6 +19,7 @@ import org.eclipse.swt.widgets.Composite;
public class IndexerBlock implements IWizardTab {
private Button indexerSwitch;
+ private Button indexerSwitch2;
IProject project;
IValidation page;
@@ -39,8 +41,13 @@ public class IndexerBlock implements IWizardTab {
indexerSwitch = new Button(composite, SWT.CHECK | SWT.RIGHT);
indexerSwitch.setAlignment(SWT.LEFT);
- indexerSwitch.setText("Enable indexing service for this project");
+ indexerSwitch.setText("Enable CTAGS indexing service for this project");
indexerSwitch.setSelection(indexer.isEnabled(project));
+
+ indexerSwitch2 = new Button(composite, SWT.CHECK | SWT.RIGHT);
+ indexerSwitch2.setAlignment(SWT.LEFT);
+ indexerSwitch2.setText("Enable NEW indexing service for this project");
+ indexerSwitch2.setSelection(false);
return composite;
}
@@ -50,6 +57,9 @@ public class IndexerBlock implements IWizardTab {
public void doRun(IProject project, IProgressMonitor monitor) {
IndexModel indexer = CCorePlugin.getDefault().getIndexModel();
indexer.setEnabled(project, indexerSwitch.getSelection());
+
+ IndexManager newIndexer = CCorePlugin.getDefault().getCoreModel().getIndexManager();
+ newIndexer.setEnabled(project, indexerSwitch2.getSelection());
}
@@ -79,12 +89,21 @@ public class IndexerBlock implements IWizardTab {
*/
public void setVisible(boolean visible) {
IndexModel indexer = CCorePlugin.getDefault().getIndexModel();
-
+ IndexManager newIndexer = CCorePlugin.getDefault().getCoreModel().getIndexManager();
+
if (indexerSwitch != null) {
//indexerSwitch.setAlignment(SWT.LEFT);
//indexerSwitch.setText("Enable indexing service for this project");
indexerSwitch.setSelection(indexer.isEnabled(project));
}
+
+ if (indexerSwitch2 != null) {
+ //indexerSwitch.setAlignment(SWT.LEFT);
+ //indexerSwitch.setText("Enable indexing service for this project");
+ indexerSwitch2.setSelection(newIndexer.isEnabled(project));
+ }
+
+
}
}