| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.core.index; |
| |
| import org.eclipse.jdt.core.search.*; |
| import org.eclipse.jdt.internal.core.util.*; |
| import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; |
| import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; |
| |
| public class MemoryIndex { |
| |
| public int NUM_CHANGES = 100; // number of separate document changes... used to decide when to merge |
| |
| SimpleLookupTable docsToReferences; // document paths -> HashtableOfObject(category names -> set of words) |
| SimpleWordSet allWords; // save space by locally interning the referenced words, since an indexer can generate numerous duplicates |
| |
| MemoryIndex() { |
| this.docsToReferences = new SimpleLookupTable(7); |
| this.allWords = new SimpleWordSet(7); |
| } |
| void addDocumentNames(String substring, SimpleSet results) { |
| // assumed the disk index already skipped over documents which have been added/changed/deleted |
| Object[] paths = this.docsToReferences.keyTable; |
| Object[] referenceTables = this.docsToReferences.valueTable; |
| if (substring == null) { // add all new/changed documents |
| for (int i = 0, l = referenceTables.length; i < l; i++) |
| if (referenceTables[i] != null) |
| results.add(paths[i]); |
| } else { |
| for (int i = 0, l = referenceTables.length; i < l; i++) |
| if (referenceTables[i] != null && ((String) paths[i]).startsWith(substring, 0)) |
| results.add(paths[i]); |
| } |
| } |
| void addIndexEntry(char[] category, char[] key, String documentName) { |
| // assumed a document was removed before its reindexed |
| HashtableOfObject referenceTable = (HashtableOfObject) this.docsToReferences.get(documentName); |
| if (referenceTable == null) |
| this.docsToReferences.put(documentName, referenceTable = new HashtableOfObject(3)); |
| |
| SimpleWordSet existingWords = (SimpleWordSet) referenceTable.get(category); |
| if (existingWords == null) |
| referenceTable.put(category, existingWords = new SimpleWordSet(1)); |
| |
| existingWords.add(this.allWords.add(key)); |
| } |
| HashtableOfObject addQueryResults(char[][] categories, char[] key, int matchRule, HashtableOfObject results) { |
| // assumed the disk index already skipped over documents which have been added/changed/deleted |
| // results maps a word -> EntryResult |
| Object[] paths = this.docsToReferences.keyTable; |
| Object[] referenceTables = this.docsToReferences.valueTable; |
| if (matchRule == (SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE) && key != null) { |
| nextPath : for (int i = 0, l = referenceTables.length; i < l; i++) { |
| HashtableOfObject categoryToWords = (HashtableOfObject) referenceTables[i]; |
| if (categoryToWords != null) { |
| for (int j = 0, m = categories.length; j < m; j++) { |
| SimpleWordSet wordSet = (SimpleWordSet) categoryToWords.get(categories[j]); |
| if (wordSet != null && wordSet.includes(key)) { |
| if (results == null) |
| results = new HashtableOfObject(13); |
| EntryResult result = (EntryResult) results.get(key); |
| if (result == null) |
| results.put(key, result = new EntryResult(key, null)); |
| result.addDocumentName((String) paths[i]); |
| continue nextPath; |
| } |
| } |
| } |
| } |
| } else { |
| for (int i = 0, l = referenceTables.length; i < l; i++) { |
| HashtableOfObject categoryToWords = (HashtableOfObject) referenceTables[i]; |
| if (categoryToWords != null) { |
| for (int j = 0, m = categories.length; j < m; j++) { |
| SimpleWordSet wordSet = (SimpleWordSet) categoryToWords.get(categories[j]); |
| if (wordSet != null) { |
| char[][] words = wordSet.words; |
| for (int k = 0, n = words.length; k < n; k++) { |
| char[] word = words[k]; |
| if (word != null && Index.isMatch(key, word, matchRule)) { |
| if (results == null) |
| results = new HashtableOfObject(13); |
| EntryResult result = (EntryResult) results.get(word); |
| if (result == null) |
| results.put(word, result = new EntryResult(word, null)); |
| result.addDocumentName((String) paths[i]); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| return results; |
| } |
| boolean hasChanged() { |
| return this.docsToReferences.elementSize > 0; |
| } |
| void remove(String documentName) { |
| this.docsToReferences.put(documentName, null); |
| } |
| boolean shouldMerge() { |
| return this.docsToReferences.elementSize >= NUM_CHANGES; |
| } |
| } |