### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java,v retrieving revision 1.34 diff -u -r1.34 HashtableOfObject.java --- compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java 7 Mar 2009 01:08:09 -0000 1.34 +++ compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObject.java 20 Jan 2010 14:59:16 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -24,6 +24,10 @@ public int elementSize; // number of elements in the table int threshold; + // used during putInOrder + private int lastIndex = -1; + private boolean foundEmpty = false; + public HashtableOfObject() { this(13); } @@ -39,6 +43,13 @@ this.valueTable = new Object[extraRoom]; } + public HashtableOfObject(int size, int hashtablesize) { + this.elementSize = 0; + this.threshold = size; // size represents the expected number of elements + this.keyTable = new char[hashtablesize][]; + this.valueTable = new Object[hashtablesize]; + } + public void clear() { for (int i = this.keyTable.length; --i >= 0;) { this.keyTable[i] = null; @@ -111,8 +122,40 @@ if (++this.elementSize > this.threshold) rehash(); return value; + } + /** + * This can be used while recreating the hashtable from + * an hashtable contents that was persisted on a file. + * This should be called in the same order of the other hashtable's + * valuetable. It also assumes that the key used and length + * are same. This function just tries to recreate the similar hashtable + * by finding out the empty slots. + */ + public Object putInOrder(char[] key, Object value) { + int length = this.keyTable.length, + index = CharOperation.hashCode(key) % length; + + if (index <= this.lastIndex) { + index = this.lastIndex + 1; + } else if (index != this.lastIndex + 1) { + if (!this.foundEmpty) { + // in the previous hash table, this index could have + // had conflicts such that it could have got reindexed + // at the beginning of the hash table, where as the original + // index would have been at the end of the hashtable. + if (index+this.threshold-this.elementSize > length) { + index = this.lastIndex+1; + } else { + this.foundEmpty = true; + } + } + } + this.keyTable[index] = key; + this.valueTable[index] = value; + this.lastIndex = index; + ++this.elementSize; + return value; } - public Object removeKey(char[] key) { int length = this.keyTable.length, index = CharOperation.hashCode(key) % length; Index: search/org/eclipse/jdt/internal/core/index/DiskIndex.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java,v retrieving revision 1.68 diff -u -r1.68 DiskIndex.java --- search/org/eclipse/jdt/internal/core/index/DiskIndex.java 16 Jan 2009 14:29:29 -0000 1.68 +++ search/org/eclipse/jdt/internal/core/index/DiskIndex.java 20 Jan 2010 14:59:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -46,7 +46,7 @@ private int streamEnd; // used when writing data from the streamBuffer to the file char separator = Index.DEFAULT_SEPARATOR; -public static final String SIGNATURE= "INDEX VERSION 1.126"; //$NON-NLS-1$ +public static final String SIGNATURE= "INDEX VERSION 1.127"; //$NON-NLS-1$ private static final char[] SIGNATURE_CHARS = SIGNATURE.toCharArray(); public static boolean DEBUG = false; @@ -132,7 +132,7 @@ } return results; } -private HashtableOfObject addQueryResult(HashtableOfObject results, char[] word, HashtableOfObject wordsToDocNumbers, MemoryIndex memoryIndex) throws IOException { +private HashtableOfObject addQueryResult(HashtableOfObject results, char[] word, Object wordsToDocNumbers, MemoryIndex memoryIndex) throws IOException { // must skip over documents which have been added/changed/deleted in the memory index if (results == null) results = new HashtableOfObject(13); @@ -141,11 +141,11 @@ if (result == null) results.put(word, new EntryResult(word, wordsToDocNumbers)); else - result.addDocumentTable(wordsToDocNumbers); + result.addDocument(wordsToDocNumbers); } else { SimpleLookupTable docsToRefs = memoryIndex.docsToReferences; if (result == null) result = new EntryResult(word, null); - int[] docNumbers = readDocumentNumbers(wordsToDocNumbers.get(word)); + int[] docNumbers = readDocumentNumbers(wordsToDocNumbers); for (int i = 0, l = docNumbers.length; i < l; i++) { String docName = readDocumentName(docNumbers[i]); if (!docsToRefs.containsKey(docName)) @@ -170,7 +170,7 @@ results = new HashtableOfObject(wordsToDocNumbers.elementSize); for (int j = 0, m = words.length; j < m; j++) if (words[j] != null) - results = addQueryResult(results, words[j], wordsToDocNumbers, memoryIndex); + results = addQueryResult(results, words[j], wordsToDocNumbers.valueTable[j], memoryIndex); } } if (results != null && this.cachedChunks == null) @@ -180,8 +180,9 @@ case SearchPattern.R_EXACT_MATCH | SearchPattern.R_CASE_SENSITIVE: for (int i = 0, l = categories.length; i < l; i++) { HashtableOfObject wordsToDocNumbers = readCategoryTable(categories[i], false); - if (wordsToDocNumbers != null && wordsToDocNumbers.containsKey(key)) - results = addQueryResult(results, key, wordsToDocNumbers, memoryIndex); + Object value; + if (wordsToDocNumbers != null && ((value = wordsToDocNumbers.get(key)) != null)) + results = addQueryResult(results, key, value, memoryIndex); } break; case SearchPattern.R_PREFIX_MATCH | SearchPattern.R_CASE_SENSITIVE: @@ -192,7 +193,7 @@ for (int j = 0, m = words.length; j < m; j++) { char[] word = words[j]; if (word != null && key[0] == word[0] && CharOperation.prefixEquals(key, word)) - results = addQueryResult(results, word, wordsToDocNumbers, memoryIndex); + results = addQueryResult(results, word, wordsToDocNumbers.valueTable[j], memoryIndex); } } } @@ -205,7 +206,7 @@ for (int j = 0, m = words.length; j < m; j++) { char[] word = words[j]; if (word != null && Index.isMatch(key, word, matchRule)) - results = addQueryResult(results, word, wordsToDocNumbers, memoryIndex); + results = addQueryResult(results, word, wordsToDocNumbers.valueTable[j], memoryIndex); } } } @@ -613,6 +614,7 @@ this.bufferIndex = 0; this.bufferEnd = stream.read(this.streamBuffer, 0, this.streamBuffer.length); int size = readStreamInt(stream); + int hashtablesize = readStreamInt(stream); try { if (size < 0) { // DEBUG System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$ @@ -621,7 +623,7 @@ System.err.println("size = "+size); //$NON-NLS-1$ System.err.println("-------------------- END --------------------"); //$NON-NLS-1$ } - categoryTable = new HashtableOfObject(size); + categoryTable = new HashtableOfObject(size, hashtablesize); } catch (OutOfMemoryError oom) { // DEBUG oom.printStackTrace(); @@ -641,9 +643,9 @@ // > 1 & < 256 then the size of the array is > 1 & < 256, the document array follows immediately // 256 if the array size >= 256 followed by another int which is the offset to the array (written prior to the table) if (arrayOffset <= 0) { - categoryTable.put(word, new int[] {-arrayOffset}); // store 1 element array by negating documentNumber + categoryTable.putInOrder(word, new int[] {-arrayOffset}); // store 1 element array by negating documentNumber } else if (arrayOffset < largeArraySize) { - categoryTable.put(word, readStreamDocumentArray(stream, arrayOffset)); // read in-lined array providing size + categoryTable.putInOrder(word, readStreamDocumentArray(stream, arrayOffset)); // read in-lined array providing size } else { arrayOffset = readStreamInt(stream); // read actual offset if (readDocNumbers) { @@ -653,7 +655,7 @@ firstOffset = arrayOffset; matchingWords[count++] = word; } - categoryTable.put(word, new Integer(arrayOffset)); // offset to array in the file + categoryTable.putInOrder(word, new Integer(arrayOffset)); // offset to array in the file } } this.categoryTables.put(INTERNED_CATEGORY_NAMES.get(categoryName), categoryTable); @@ -1060,6 +1062,7 @@ this.categoryOffsets.put(categoryName, this.streamEnd); // remember the offset to the start of the table this.categoryTables.put(categoryName, null); // flush cached table writeStreamInt(stream, wordsToDocs.elementSize); + writeStreamInt(stream, wordsToDocs.valueTable.length); char[][] words = wordsToDocs.keyTable; for (int i = 0, l = words.length; i < l; i++) { Object o = values[i]; Index: search/org/eclipse/jdt/internal/core/index/EntryResult.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/EntryResult.java,v retrieving revision 1.13 diff -u -r1.13 EntryResult.java --- search/org/eclipse/jdt/internal/core/index/EntryResult.java 7 Mar 2009 01:08:11 -0000 1.13 +++ search/org/eclipse/jdt/internal/core/index/EntryResult.java 20 Jan 2010 14:59:18 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2010 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 @@ -11,42 +11,41 @@ package org.eclipse.jdt.internal.core.index; import org.eclipse.jdt.core.compiler.CharOperation; -import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.SimpleSet; public class EntryResult { private char[] word; -private HashtableOfObject[] documentTables; +private Object[] documents; private SimpleSet documentNames; -public EntryResult(char[] word, HashtableOfObject table) { +public EntryResult(char[] word, Object document) { this.word = word; - if (table != null) - this.documentTables = new HashtableOfObject[] {table}; + if (document != null) + this.documents = new Object[] {document}; } public void addDocumentName(String documentName) { if (this.documentNames == null) this.documentNames = new SimpleSet(3); this.documentNames.add(documentName); } -public void addDocumentTable(HashtableOfObject table) { - if (this.documentTables != null) { - int length = this.documentTables.length; - System.arraycopy(this.documentTables, 0, this.documentTables = new HashtableOfObject[length + 1], 0, length); - this.documentTables[length] = table; +public void addDocument(Object document) { + if (this.documents != null) { + int length = this.documents.length; + System.arraycopy(this.documents, 0, this.documents = new Object[length + 1], 0, length); + this.documents[length] = document; } else { - this.documentTables = new HashtableOfObject[] {table}; + this.documents = new Object[] {document}; } } public char[] getWord() { return this.word; } public String[] getDocumentNames(Index index) throws java.io.IOException { - if (this.documentTables != null) { - int length = this.documentTables.length; + if (this.documents != null) { + int length = this.documents.length; if (length == 1 && this.documentNames == null) { // have a single table - Object offset = this.documentTables[0].get(this.word); + Object offset = this.documents[0]; int[] numbers = index.diskIndex.readDocumentNumbers(offset); String[] names = new String[numbers.length]; for (int i = 0, l = numbers.length; i < l; i++) @@ -55,7 +54,7 @@ } for (int i = 0; i < length; i++) { - Object offset = this.documentTables[i].get(this.word); + Object offset = this.documents[i]; int[] numbers = index.diskIndex.readDocumentNumbers(offset); for (int j = 0, k = numbers.length; j < k; j++) addDocumentName(index.diskIndex.readDocumentName(numbers[j])); @@ -74,6 +73,6 @@ return names; } public boolean isEmpty() { - return this.documentTables == null && this.documentNames == null; + return this.documents == null && this.documentNames == null; } }