View | Details | Raw Unified | Return to bug 138309 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/util/Util.java (+14 lines)
Lines 919-924 Link Here
919
	}
919
	}
920
}
920
}
921
/**
921
/**
922
 * Return the stack trace element of the caller's caller.
923
 */
924
public static StackTraceElement caller() {
925
	StackTraceElement[] elements = new Exception().getStackTrace();
926
	int idx = 0, length=elements.length;
927
	while (idx<length && !elements[idx++].getClassName().equals("org.eclipse.jdt.core.tests.util.Util")) {
928
		// loop until JDT/Core class appears in the stack
929
	}
930
	if (idx < length) {
931
		return elements[idx];
932
	}
933
	return null;
934
}
935
/**
922
 * Makes the given path a path using native path separators as returned by File.getPath()
936
 * Makes the given path a path using native path separators as returned by File.getPath()
923
 * and trimming any extra slash.
937
 * and trimming any extra slash.
924
 */
938
 */
(-)search/org/eclipse/jdt/internal/core/index/DiskIndex.java (-43 / +114 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
2
 * Copyright (c) 2000, 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 19-28 Link Here
19
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
19
import org.eclipse.jdt.internal.compiler.util.HashtableOfObject;
20
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
20
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
21
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
21
import org.eclipse.jdt.internal.compiler.util.SimpleSet;
22
import org.eclipse.jdt.internal.compiler.util.SimpleSetOfCharArray;
22
23
23
public class DiskIndex {
24
public class DiskIndex {
24
25
25
String fileName;
26
File indexFile;
26
27
27
private int headerInfoOffset;
28
private int headerInfoOffset;
28
private int numberOfChunks;
29
private int numberOfChunks;
Lines 37-43 Link Here
37
private HashtableOfObject categoryTables; // category name -> HashtableOfObject(words -> int[] of document #'s) or offset if not read yet
38
private HashtableOfObject categoryTables; // category name -> HashtableOfObject(words -> int[] of document #'s) or offset if not read yet
38
private char[] cachedCategoryName;
39
private char[] cachedCategoryName;
39
40
40
public static final String SIGNATURE= "INDEX VERSION 1.120"; //$NON-NLS-1$
41
public static final String SIGNATURE= "INDEX VERSION 1.121.2"; //$NON-NLS-1$
42
public static final char[] SIGNATURE_ARRAY= SIGNATURE.toCharArray();
41
public static boolean DEBUG = false;
43
public static boolean DEBUG = false;
42
44
43
private static final int RE_INDEXED = -1;
45
private static final int RE_INDEXED = -1;
Lines 45-50 Link Here
45
47
46
private static final int CHUNK_SIZE = 100;
48
private static final int CHUNK_SIZE = 100;
47
49
50
private static final SimpleSetOfCharArray INTERNED_CATEGORY_NAMES = new SimpleSetOfCharArray(20);
51
48
static class IntList {
52
static class IntList {
49
53
50
int size;
54
int size;
Lines 70-77 Link Here
70
}
74
}
71
75
72
76
73
DiskIndex(String fileName) {
77
DiskIndex(File file) {
74
	this.fileName = fileName;
78
	this.indexFile = file;
75
79
76
	// clear cached items
80
	// clear cached items
77
	this.headerInfoOffset = -1;
81
	this.headerInfoOffset = -1;
Lines 204-210 Link Here
204
private void cacheDocumentNames() throws IOException {
208
private void cacheDocumentNames() throws IOException {
205
	// will need all document names so get them now
209
	// will need all document names so get them now
206
	this.cachedChunks = new String[this.numberOfChunks][];
210
	this.cachedChunks = new String[this.numberOfChunks][];
207
	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), this.numberOfChunks > 5 ? 4096 : 2048));
211
	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(this.indexFile), this.numberOfChunks > 5 ? 4096 : 2048));
208
	try {
212
	try {
209
		stream.skip(this.chunkOffsets[0]);
213
		stream.skip(this.chunkOffsets[0]);
210
		for (int i = 0; i < this.numberOfChunks; i++) {
214
		for (int i = 0; i < this.numberOfChunks; i++) {
Lines 336-350 Link Here
336
	}
340
	}
337
}
341
}
338
File getIndexFile() {
342
File getIndexFile() {
339
	if (this.fileName == null) return null;
343
	return this.indexFile;
340
341
	return new File(this.fileName);
342
}
344
}
343
void initialize(boolean reuseExistingFile) throws IOException {
345
void initialize(boolean reuseExistingFile) throws IOException {
344
	File indexFile = getIndexFile();
346
	if (this.indexFile.exists()) {
345
	if (indexFile.exists()) {
346
		if (reuseExistingFile) {
347
		if (reuseExistingFile) {
347
			RandomAccessFile file = new RandomAccessFile(this.fileName, "r"); //$NON-NLS-1$
348
			RandomAccessFile file = new RandomAccessFile(this.indexFile, "r"); //$NON-NLS-1$
348
			try {
349
			try {
349
				String signature = file.readUTF();
350
				String signature = file.readUTF();
350
				if (!signature.equals(SIGNATURE))
351
				if (!signature.equals(SIGNATURE))
Lines 359-371 Link Here
359
			return;
360
			return;
360
		}
361
		}
361
		if (!indexFile.delete()) {
362
		if (!indexFile.delete()) {
363
			String fileName = this.indexFile.getPath();
362
			if (DEBUG)
364
			if (DEBUG)
363
				System.out.println("initialize - Failed to delete index " + this.fileName); //$NON-NLS-1$
365
				System.out.println("initialize - Failed to delete index " + fileName); //$NON-NLS-1$
364
			throw new IOException("Failed to delete index " + this.fileName); //$NON-NLS-1$
366
			throw new IOException("Failed to delete index " + fileName); //$NON-NLS-1$
365
		}
367
		}
366
	}
368
	}
367
	if (indexFile.createNewFile()) {
369
	if (indexFile.createNewFile()) {
368
		RandomAccessFile file = new RandomAccessFile(this.fileName, "rw"); //$NON-NLS-1$
370
		RandomAccessFile file = new RandomAccessFile(this.indexFile, "rw"); //$NON-NLS-1$
369
		try {
371
		try {
370
			file.writeUTF(SIGNATURE);
372
			file.writeUTF(SIGNATURE);
371
			file.writeInt(-1); // file is empty
373
			file.writeInt(-1); // file is empty
Lines 373-391 Link Here
373
			file.close();
375
			file.close();
374
		}
376
		}
375
	} else {
377
	} else {
378
		String fileName = this.indexFile.getPath();
376
		if (DEBUG)
379
		if (DEBUG)
377
			System.out.println("initialize - Failed to create new index " + this.fileName); //$NON-NLS-1$
380
			System.out.println("initialize - Failed to create new index " + fileName); //$NON-NLS-1$
378
		throw new IOException("Failed to create new index " + this.fileName); //$NON-NLS-1$
381
		throw new IOException("Failed to create new index " + fileName); //$NON-NLS-1$
379
	}
382
	}
380
}
383
}
381
private void initializeFrom(DiskIndex diskIndex, File newIndexFile) throws IOException {
384
private void initializeFrom(DiskIndex diskIndex, File newIndexFile) throws IOException {
382
	if (newIndexFile.exists() && !newIndexFile.delete()) { // delete the temporary index file
385
	if (newIndexFile.exists() && !newIndexFile.delete()) { // delete the temporary index file
383
		if (DEBUG)
386
		if (DEBUG)
384
			System.out.println("initializeFrom - Failed to delete temp index " + this.fileName); //$NON-NLS-1$
387
			System.out.println("initializeFrom - Failed to delete temp index " + this.indexFile.getPath()); //$NON-NLS-1$
385
	} else if (!newIndexFile.createNewFile()) {
388
	} else if (!newIndexFile.createNewFile()) {
389
		String fileName = this.indexFile.getPath();
386
		if (DEBUG)
390
		if (DEBUG)
387
			System.out.println("initializeFrom - Failed to create temp index " + this.fileName); //$NON-NLS-1$
391
			System.out.println("initializeFrom - Failed to create temp index " + fileName); //$NON-NLS-1$
388
		throw new IOException("Failed to create temp index " + this.fileName); //$NON-NLS-1$
392
		throw new IOException("Failed to create temp index " + fileName); //$NON-NLS-1$
389
	}
393
	}
390
394
391
	int size = diskIndex.categoryOffsets == null ? 8 : diskIndex.categoryOffsets.elementSize;
395
	int size = diskIndex.categoryOffsets == null ? 8 : diskIndex.categoryOffsets.elementSize;
Lines 465-477 Link Here
465
		if (previousLength == 0) return this; // nothing to do... memory index contained deleted documents that had never been saved
469
		if (previousLength == 0) return this; // nothing to do... memory index contained deleted documents that had never been saved
466
470
467
		// index is now empty since all the saved documents were removed
471
		// index is now empty since all the saved documents were removed
468
		DiskIndex newDiskIndex = new DiskIndex(this.fileName);
472
		DiskIndex newDiskIndex = new DiskIndex(this.indexFile);
469
		newDiskIndex.initialize(false);
473
		newDiskIndex.initialize(false);
470
		return newDiskIndex;
474
		return newDiskIndex;
471
	}
475
	}
472
476
473
	DiskIndex newDiskIndex = new DiskIndex(this.fileName + ".tmp"); //$NON-NLS-1$
477
	DiskIndex newDiskIndex = new DiskIndex(new File(this.indexFile.getPath() + ".tmp")); //$NON-NLS-1$
474
	File newIndexFile = newDiskIndex.getIndexFile();
478
	File newIndexFile = newDiskIndex.indexFile;
475
	try {
479
	try {
476
		newDiskIndex.initializeFrom(this, newIndexFile);
480
		newDiskIndex.initializeFrom(this, newIndexFile);
477
		DataOutputStream stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(newIndexFile, false), 2048));
481
		DataOutputStream stream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(newIndexFile, false), 2048));
Lines 487-494 Link Here
487
				for (int i = 0, l = names.length; i < l; i++)
491
				for (int i = 0, l = names.length; i < l; i++)
488
					if (names[i] != null)
492
					if (names[i] != null)
489
						newDiskIndex.copyQueryResults(
493
						newDiskIndex.copyQueryResults(
490
							(HashtableOfObject) memoryIndex.docsToReferences.get(names[i]),
494
							(HashtableOfObject) memoryIndex.docsToReferences.get(names[i]), ((Integer) integerPositions[i]).intValue());
491
							((Integer) integerPositions[i]).intValue());
492
			}
495
			}
493
			indexedDocuments = null; // free up the space
496
			indexedDocuments = null; // free up the space
494
497
Lines 506-537 Link Here
506
		newDiskIndex.writeOffsetToHeader(offsetToHeader);
509
		newDiskIndex.writeOffsetToHeader(offsetToHeader);
507
510
508
		// rename file by deleting previous index file & renaming temp one
511
		// rename file by deleting previous index file & renaming temp one
509
		File old = getIndexFile();
512
		File old = this.indexFile;
510
		if (old.exists() && !old.delete()) {
513
		if (old.exists() && !old.delete()) {
514
			String fileName = old.getPath();
511
			if (DEBUG)
515
			if (DEBUG)
512
				System.out.println("mergeWith - Failed to delete " + this.fileName); //$NON-NLS-1$
516
				System.out.println("mergeWith - Failed to delete " + fileName); //$NON-NLS-1$
513
			throw new IOException("Failed to delete index file " + this.fileName); //$NON-NLS-1$
517
			throw new IOException("Failed to delete index file " + fileName); //$NON-NLS-1$
514
		}
518
		}
515
		if (!newIndexFile.renameTo(old)) {
519
		if (!newIndexFile.renameTo(old)) {
520
			String fileName = old.getPath();
516
			if (DEBUG)
521
			if (DEBUG)
517
				System.out.println("mergeWith - Failed to rename " + this.fileName); //$NON-NLS-1$
522
				System.out.println("mergeWith - Failed to rename " + fileName); //$NON-NLS-1$
518
			throw new IOException("Failed to rename index file " + this.fileName); //$NON-NLS-1$
523
			throw new IOException("Failed to rename index file " + fileName); //$NON-NLS-1$
519
		}
524
		}
520
	} catch (IOException e) {
525
	} catch (IOException e) {
521
		if (newIndexFile.exists() && !newIndexFile.delete())
526
		if (newIndexFile.exists() && !newIndexFile.delete())
522
			if (DEBUG)
527
			if (DEBUG)
523
				System.out.println("mergeWith - Failed to delete temp index " + newDiskIndex.fileName); //$NON-NLS-1$
528
				System.out.println("mergeWith - Failed to delete temp index " + newDiskIndex.indexFile.getPath()); //$NON-NLS-1$
524
		throw e;
529
		throw e;
525
	}
530
	}
526
531
527
	newDiskIndex.fileName = this.fileName;
532
	newDiskIndex.indexFile = this.indexFile;
528
	return newDiskIndex;
533
	return newDiskIndex;
529
}
534
}
530
private synchronized String[] readAllDocumentNames() throws IOException {
535
private synchronized String[] readAllDocumentNames() throws IOException {
531
	if (this.numberOfChunks <= 0)
536
	if (this.numberOfChunks <= 0)
532
		return CharOperation.NO_STRINGS;
537
		return CharOperation.NO_STRINGS;
533
538
534
	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), this.numberOfChunks > 5 ? 4096 : 2048));
539
	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(this.indexFile), this.numberOfChunks > 5 ? 4096 : 2048));
535
	try {
540
	try {
536
		stream.skip(this.chunkOffsets[0]);
541
		stream.skip(this.chunkOffsets[0]);
537
		int lastIndex = this.numberOfChunks - 1;
542
		int lastIndex = this.numberOfChunks - 1;
Lines 564-570 Link Here
564
		}
569
		}
565
	}
570
	}
566
571
567
	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
572
	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(this.indexFile), 2048));
568
	HashtableOfObject categoryTable = null;
573
	HashtableOfObject categoryTable = null;
569
	char[][] matchingWords = null;
574
	char[][] matchingWords = null;
570
	int count = 0;
575
	int count = 0;
Lines 575-581 Link Here
575
		try {
580
		try {
576
			if (size < 0) { // DEBUG
581
			if (size < 0) { // DEBUG
577
				System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
582
				System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
578
				System.err.println("file = "+getIndexFile()); //$NON-NLS-1$
583
				System.err.println("file = "+this.indexFile); //$NON-NLS-1$
579
				System.err.println("offset = "+offset); //$NON-NLS-1$
584
				System.err.println("offset = "+offset); //$NON-NLS-1$
580
				System.err.println("size = "+size); //$NON-NLS-1$
585
				System.err.println("size = "+size); //$NON-NLS-1$
581
				System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
586
				System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
Lines 585-591 Link Here
585
			// DEBUG
590
			// DEBUG
586
			oom.printStackTrace();
591
			oom.printStackTrace();
587
			System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
592
			System.err.println("-------------------- DEBUG --------------------"); //$NON-NLS-1$
588
			System.err.println("file = "+getIndexFile()); //$NON-NLS-1$
593
			System.err.println("file = "+this.indexFile); //$NON-NLS-1$
589
			System.err.println("offset = "+offset); //$NON-NLS-1$
594
			System.err.println("offset = "+offset); //$NON-NLS-1$
590
			System.err.println("size = "+size); //$NON-NLS-1$
595
			System.err.println("size = "+size); //$NON-NLS-1$
591
			System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
596
			System.err.println("--------------------   END   --------------------"); //$NON-NLS-1$
Lines 615-630 Link Here
615
				categoryTable.put(word, new Integer(arrayOffset)); // offset to array in the file
620
				categoryTable.put(word, new Integer(arrayOffset)); // offset to array in the file
616
			}
621
			}
617
		}
622
		}
618
		this.categoryTables.put(categoryName, categoryTable);
623
		this.categoryTables.put(INTERNED_CATEGORY_NAMES.get(categoryName), categoryTable);
619
		// cache the table as long as its not too big
624
		// cache the table as long as its not too big
620
		// in practice, some tables can be greater than 500K when they contain more than 10K elements
625
		// in practice, some tables can be greater than 500K when they contain more than 10K elements
621
		this.cachedCategoryName = categoryTable.elementSize < 10000 ? categoryName : null;
626
		this.cachedCategoryName = categoryTable.elementSize < 20000 ? categoryName : null;
627
		if (DEBUG) {
628
			Util.verbose("Index file "+this.indexFile+" was read to populate category table..."); //$NON-NLS-1$ //$NON-NLS-2$
629
			printCategoryTables();
630
		}
622
	} finally {
631
	} finally {
623
		stream.close();
632
		stream.close();
624
	}
633
	}
625
634
626
	if (matchingWords != null && count > 0) {
635
	if (matchingWords != null && count > 0) {
627
		stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
636
		stream = new DataInputStream(new BufferedInputStream(new FileInputStream(this.indexFile), 2048));
628
		try {
637
		try {
629
			stream.skip(firstOffset);
638
			stream.skip(firstOffset);
630
			for (int i = 0; i < count; i++) // each array follows the previous one
639
			for (int i = 0; i < count; i++) // each array follows the previous one
Lines 688-694 Link Here
688
		if (numberOfBytes < 0)
697
		if (numberOfBytes < 0)
689
			throw new IllegalArgumentException();
698
			throw new IllegalArgumentException();
690
		byte[] bytes = new byte[numberOfBytes];
699
		byte[] bytes = new byte[numberOfBytes];
691
		FileInputStream file = new FileInputStream(getIndexFile());
700
		FileInputStream file = new FileInputStream(this.indexFile);
692
		try {
701
		try {
693
			file.skip(start);
702
			file.skip(start);
694
			if (file.read(bytes, 0, numberOfBytes) != numberOfBytes)
703
			if (file.read(bytes, 0, numberOfBytes) != numberOfBytes)
Lines 708-714 Link Here
708
	if (arrayOffset instanceof int[])
717
	if (arrayOffset instanceof int[])
709
		return (int[]) arrayOffset;
718
		return (int[]) arrayOffset;
710
719
711
	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(getIndexFile()), 2048));
720
	DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(this.indexFile), 2048));
712
	try {
721
	try {
713
		stream.skip(((Integer) arrayOffset).intValue());
722
		stream.skip(((Integer) arrayOffset).intValue());
714
		return readDocumentArray(stream, stream.readInt());
723
		return readDocumentArray(stream, stream.readInt());
Lines 733-739 Link Here
733
	int size = file.readInt();
742
	int size = file.readInt();
734
	this.categoryOffsets = new HashtableOfIntValues(size);
743
	this.categoryOffsets = new HashtableOfIntValues(size);
735
	for (int i = 0; i < size; i++)
744
	for (int i = 0; i < size; i++)
736
		this.categoryOffsets.put(Util.readUTF(file), file.readInt()); // cache offset to category table
745
		this.categoryOffsets.put(INTERNED_CATEGORY_NAMES.get(Util.readUTF(file)), file.readInt()); // cache offset to category table
737
	this.categoryTables = new HashtableOfObject(3);
746
	this.categoryTables = new HashtableOfObject(3);
738
}
747
}
739
synchronized void startQuery() {
748
synchronized void startQuery() {
Lines 909-915 Link Here
909
}
918
}
910
private void writeOffsetToHeader(int offsetToHeader) throws IOException {
919
private void writeOffsetToHeader(int offsetToHeader) throws IOException {
911
	if (offsetToHeader > 0) {
920
	if (offsetToHeader > 0) {
912
		RandomAccessFile file = new RandomAccessFile(this.fileName, "rw"); //$NON-NLS-1$
921
		RandomAccessFile file = new RandomAccessFile(this.indexFile, "rw"); //$NON-NLS-1$
913
		try {
922
		try {
914
			file.seek(this.headerInfoOffset); // offset to position in header
923
			file.seek(this.headerInfoOffset); // offset to position in header
915
			file.writeInt(offsetToHeader);
924
			file.writeInt(offsetToHeader);
Lines 919-922 Link Here
919
		}
928
		}
920
	}
929
	}
921
}
930
}
931
private void printCategoryTables() {
932
	StringBuffer buffer = new StringBuffer("	- categoryTables:"); //$NON-NLS-1$
933
	int size = 0;
934
	if (this.categoryTables == null) {
935
		buffer.append(" null\n"); //$NON-NLS-1$
936
	} else {
937
		char[][] categoryNames = this.categoryTables.keyTable;
938
		Object[] tables = this.categoryTables.valueTable;
939
		int length = categoryNames.length;
940
		for (int i = 0; i < length; i++) {
941
			if (categoryNames[i] != null) {
942
				buffer.append("\n		+ "+new String(categoryNames[i])); //$NON-NLS-1$
943
				size += categoryNames[i].length + 16;
944
				HashtableOfObject table = (HashtableOfObject) tables[i];
945
				buffer.append(" -> "); //$NON-NLS-1$
946
				if (table == null) {
947
					buffer.append(" null\n"); //$NON-NLS-1$
948
				} else {
949
					buffer.append(table.elementSize);
950
					buffer.append(" int arrays"); //$NON-NLS-1$
951
					int offset = table.elementSize / 10;
952
					int tableSize = 16;
953
					for (int j=0, l=table.keyTable.length; j<l; j++) {
954
						char[] key = table.keyTable[j];
955
						if (key != null) {
956
							tableSize += key.length*2 + 16;
957
							Object value = table.valueTable[j];
958
							if (value instanceof int[]) {
959
								tableSize += (((int[]) value).length-1)*4 + 16;
960
							} else if (value instanceof Integer) {
961
								tableSize += 20;
962
							}
963
							if (offset == 0 || (j%offset) == 0) {
964
								buffer.append("\n			. "); //$NON-NLS-1$
965
								buffer.append(key);
966
								buffer.append(" -> "); //$NON-NLS-1$
967
								buffer.append(value);
968
							}
969
						}
970
					}
971
					buffer.append("\n			  => size ~ "); //$NON-NLS-1$
972
					buffer.append(tableSize);
973
					buffer.append('\n');
974
					size += tableSize;
975
				}
976
			}
977
		}
978
		buffer.append("\n		  => size ~ "); //$NON-NLS-1$
979
		buffer.append(size);
980
		buffer.append('\n');
981
	}
982
	buffer.append("	- cached category:"); //$NON-NLS-1$
983
	buffer.append(this.cachedCategoryName==null?"none":new String(this.cachedCategoryName)); //$NON-NLS-1$
984
	buffer.append('\n');
985
	Util.verbose(buffer.toString());
986
}
987
/* (non-Javadoc)
988
 * @see java.lang.Object#toString()
989
 */
990
public String toString() {
991
	return "DiskIndex for "+this.indexFile; //$NON-NLS-1$
992
}
922
}
993
}
(-)search/org/eclipse/jdt/internal/core/index/Index.java (-2 / +2 lines)
Lines 84-95 Link Here
84
}
84
}
85
85
86
86
87
public Index(String fileName, String containerPath, boolean reuseExistingFile) throws IOException {
87
public Index(File indexFile, String containerPath, boolean reuseExistingFile) throws IOException {
88
	this.containerPath = containerPath;
88
	this.containerPath = containerPath;
89
	this.monitor = new ReadWriteMonitor();
89
	this.monitor = new ReadWriteMonitor();
90
90
91
	this.memoryIndex = new MemoryIndex();
91
	this.memoryIndex = new MemoryIndex();
92
	this.diskIndex = new DiskIndex(fileName);
92
	this.diskIndex = new DiskIndex(indexFile);
93
	this.diskIndex.initialize(reuseExistingFile);
93
	this.diskIndex.initialize(reuseExistingFile);
94
}
94
}
95
public void addIndexEntry(char[] category, char[] key, String containerRelativePath) {
95
public void addIndexEntry(char[] category, char[] key, String containerRelativePath) {
(-)search/org/eclipse/jdt/internal/core/search/indexing/RemoveFolderFromIndex.java (-2 lines)
Lines 24-37 Link Here
24
	IPath folderPath;
24
	IPath folderPath;
25
	char[][] inclusionPatterns;
25
	char[][] inclusionPatterns;
26
	char[][] exclusionPatterns;
26
	char[][] exclusionPatterns;
27
	IProject project;
28
27
29
	public RemoveFolderFromIndex(IPath folderPath, char[][] inclusionPatterns, char[][] exclusionPatterns, IProject project, IndexManager manager) {
28
	public RemoveFolderFromIndex(IPath folderPath, char[][] inclusionPatterns, char[][] exclusionPatterns, IProject project, IndexManager manager) {
30
		super(project.getFullPath(), manager);
29
		super(project.getFullPath(), manager);
31
		this.folderPath = folderPath;
30
		this.folderPath = folderPath;
32
		this.inclusionPatterns = inclusionPatterns;
31
		this.inclusionPatterns = inclusionPatterns;
33
		this.exclusionPatterns = exclusionPatterns;
32
		this.exclusionPatterns = exclusionPatterns;
34
		this.project = project;
35
	}
33
	}
36
	public boolean execute(IProgressMonitor progressMonitor) {
34
	public boolean execute(IProgressMonitor progressMonitor) {
37
35
(-)search/org/eclipse/jdt/internal/core/search/indexing/IndexManager.java (-41 / +56 lines)
Lines 27-32 Link Here
27
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
27
import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
28
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
28
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
29
import org.eclipse.jdt.internal.core.*;
29
import org.eclipse.jdt.internal.core.*;
30
import org.eclipse.jdt.internal.core.index.DiskIndex;
30
import org.eclipse.jdt.internal.core.index.Index;
31
import org.eclipse.jdt.internal.core.index.Index;
31
import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
32
import org.eclipse.jdt.internal.core.search.BasicSearchEngine;
32
import org.eclipse.jdt.internal.core.search.PatternSearchJob;
33
import org.eclipse.jdt.internal.core.search.PatternSearchJob;
Lines 46-57 Link Here
46
	/* need to save ? */
47
	/* need to save ? */
47
	private boolean needToSave = false;
48
	private boolean needToSave = false;
48
	private static final CRC32 checksumCalculator = new CRC32();
49
	private static final CRC32 checksumCalculator = new CRC32();
49
	private IPath javaPluginLocation = null;
50
	private File indexesDirectory = null;
50
51
51
	/* can only replace a current state if its less than the new one */
52
	/* can only replace a current state if its less than the new one */
52
	private SimpleLookupTable indexStates = null;
53
	private SimpleLookupTable indexStates = null;
53
	private File savedIndexNamesFile =
54
	private File savedIndexNamesFile = new File(getIndexesDirectory(), "savedIndexNames.txt"); //$NON-NLS-1$
54
		new File(getJavaPluginWorkingLocation().append("savedIndexNames.txt").toOSString()); //$NON-NLS-1$
55
	public static Integer SAVED_STATE = new Integer(0);
55
	public static Integer SAVED_STATE = new Integer(0);
56
	public static Integer UPDATING_STATE = new Integer(1);
56
	public static Integer UPDATING_STATE = new Integer(1);
57
	public static Integer UNKNOWN_STATE = new Integer(2);
57
	public static Integer UNKNOWN_STATE = new Integer(2);
Lines 106-114 Link Here
106
	PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null);
106
	PatternSearchJob job = new PatternSearchJob(null, SearchEngine.getDefaultSearchParticipant(), scope, null);
107
	Index[] selectedIndexes = job.getIndexes(null);
107
	Index[] selectedIndexes = job.getIndexes(null);
108
	for (int j = 0, max = selectedIndexes.length; j < max; j++) {
108
	for (int j = 0, max = selectedIndexes.length; j < max; j++) {
109
		// TODO should use getJavaPluginWorkingLocation()+index simple name to avoid bugs such as https://bugs.eclipse.org/bugs/show_bug.cgi?id=62267
109
		String fileName = selectedIndexes[j].getIndexFile().getName();
110
		String path = selectedIndexes[j].getIndexFile().getAbsolutePath();
110
		knownPaths.put(fileName, fileName);
111
		knownPaths.put(path, path);
112
	}
111
	}
113
112
114
	if (indexStates != null) {
113
	if (indexStates != null) {
Lines 127-138 Link Here
127
		}
126
		}
128
	}
127
	}
129
128
130
	File indexesDirectory = new File(getJavaPluginWorkingLocation().toOSString());
129
	File idxDir = getIndexesDirectory();
131
	if (indexesDirectory.isDirectory()) {
130
	if (idxDir.isDirectory()) {
132
		File[] indexesFiles = indexesDirectory.listFiles();
131
		File[] indexesFiles = idxDir.listFiles();
133
		if (indexesFiles != null) {
132
		if (indexesFiles != null) {
134
			for (int i = 0, indexesFilesLength = indexesFiles.length; i < indexesFilesLength; i++) {
133
			for (int i = 0, indexesFilesLength = indexesFiles.length; i < indexesFilesLength; i++) {
135
				String fileName = indexesFiles[i].getAbsolutePath();
134
				String fileName = indexesFiles[i].getName();
136
				if (!knownPaths.containsKey(fileName) && fileName.toLowerCase().endsWith(".index")) { //$NON-NLS-1$
135
				if (!knownPaths.containsKey(fileName) && fileName.toLowerCase().endsWith(".index")) { //$NON-NLS-1$
137
					if (VERBOSE)
136
					if (VERBOSE)
138
						Util.verbose("Deleting index file " + indexesFiles[i]); //$NON-NLS-1$
137
						Util.verbose("Deleting index file " + indexesFiles[i]); //$NON-NLS-1$
Lines 148-157 Link Here
148
		String pathString = containerPath.toOSString();
147
		String pathString = containerPath.toOSString();
149
		checksumCalculator.reset();
148
		checksumCalculator.reset();
150
		checksumCalculator.update(pathString.getBytes());
149
		checksumCalculator.update(pathString.getBytes());
151
		String fileName = Long.toString(checksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
150
		indexLocation = Long.toString(checksumCalculator.getValue()) + ".index"; //$NON-NLS-1$
152
		if (VERBOSE)
151
		if (VERBOSE) {
153
			Util.verbose("-> index name for " + pathString + " is " + fileName); //$NON-NLS-1$ //$NON-NLS-2$
152
			Util.verbose("-> index name for " + pathString + " is " + indexLocation); //$NON-NLS-1$ //$NON-NLS-2$
154
		indexLocation = getJavaPluginWorkingLocation().append(fileName).toOSString();
153
		}
155
		this.indexLocations.put(containerPath, indexLocation);
154
		this.indexLocations.put(containerPath, indexLocation);
156
	}
155
	}
157
	return indexLocation;
156
	return indexLocation;
Lines 223-232 Link Here
223
		// index isn't cached, consider reusing an existing index file
222
		// index isn't cached, consider reusing an existing index file
224
		String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
223
		String containerPathString = containerPath.getDevice() == null ? containerPath.toString() : containerPath.toOSString();
225
		if (reuseExistingFile) {
224
		if (reuseExistingFile) {
226
			File indexFile = new File(indexLocation);
225
			File indexFile = getIndexFile(indexLocation);
227
			if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing
226
			if (indexFile.exists()) { // check before creating index so as to avoid creating a new empty index if file is missing
228
				try {
227
				try {
229
					index = new Index(indexLocation, containerPathString, true /*reuse index file*/);
228
					index = new Index(indexFile, containerPathString, true /*reuse index file*/);
230
					indexes.put(indexLocation, index);
229
					indexes.put(indexLocation, index);
231
					return index;
230
					return index;
232
				} catch (IOException e) {
231
				} catch (IOException e) {
Lines 250-256 Link Here
250
			try {
249
			try {
251
				if (VERBOSE)
250
				if (VERBOSE)
252
					Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
251
					Util.verbose("-> create empty index: "+indexLocation+" path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
253
				index = new Index(indexLocation, containerPathString, false /*do not reuse index file*/);
252
				index = new Index(getIndexFile(indexLocation), containerPathString, false /*do not reuse index file*/);
254
				indexes.put(indexLocation, index);
253
				indexes.put(indexLocation, index);
255
				return index;
254
				return index;
256
			} catch (IOException e) {
255
			} catch (IOException e) {
Lines 267-272 Link Here
267
public synchronized Index getIndex(String indexLocation) {
266
public synchronized Index getIndex(String indexLocation) {
268
	return (Index) indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed
267
	return (Index) indexes.get(indexLocation); // is null if unknown, call if the containerPath must be computed
269
}
268
}
269
private File getIndexFile(String indexLocation) {
270
	return (indexLocation.indexOf(File.separatorChar) < 0)
271
		? new File(this.indexesDirectory, indexLocation)
272
		: new File(indexLocation);
273
}
270
public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
274
public synchronized Index getIndexForUpdate(IPath containerPath, boolean reuseExistingFile, boolean createIfMissing) {
271
	String indexLocation = computeIndexLocation(containerPath);
275
	String indexLocation = computeIndexLocation(containerPath);
272
	if (getIndexStates().get(indexLocation) == REBUILDING_STATE)
276
	if (getIndexStates().get(indexLocation) == REBUILDING_STATE)
Lines 281-300 Link Here
281
	char[] savedIndexNames = readIndexState();
285
	char[] savedIndexNames = readIndexState();
282
	if (savedIndexNames.length > 0) {
286
	if (savedIndexNames.length > 0) {
283
		char[][] names = CharOperation.splitOn('\n', savedIndexNames);
287
		char[][] names = CharOperation.splitOn('\n', savedIndexNames);
284
		if (names.length > 0) {
288
		int length = names.length;
285
			// check to see if workspace has moved, if so then do not trust saved indexes
289
		if (length > 0) {
286
			File indexesDirectory = new File(getJavaPluginWorkingLocation().toOSString());
290
			// First line should be DiskIndex signature, otherwise saved names are obsolete
287
			char[] dirName = indexesDirectory.getAbsolutePath().toCharArray();
291
			if (length > 2 && names[0][0] == DiskIndex.SIGNATURE_ARRAY[0] && CharOperation.equals(names[0], DiskIndex.SIGNATURE_ARRAY)) {
288
			int delimiterPos = dirName.length;
292
				// check to see if workspace has moved, if so then do not trust saved indexes
289
			if (CharOperation.match(names[0], 0, delimiterPos, dirName, 0, delimiterPos, true)) {
293
				char[] dirName = getIndexesDirectory().getAbsolutePath().toCharArray();
290
				for (int i = 0, l = names.length; i < l; i++) {
294
				boolean sameDir = names[1][0] == dirName[0] && CharOperation.equals(names[1], dirName); // second line is indexes directory where existing index files were built
295
				for (int i = 2; i < length; i++) {
291
					char[] name = names[i];
296
					char[] name = names[i];
292
					if (name.length > 0)
297
					if (name.length > 0) {
293
						this.indexStates.put(new String(name), SAVED_STATE);
298
						if (CharOperation.indexOf(File.separatorChar, name) < 0) {
299
							if (sameDir) {
300
								this.indexStates.put(new String(name), SAVED_STATE);
301
							}
302
						} else {
303
							this.indexStates.put(new String(name), SAVED_STATE);						
304
						}
305
					}
294
				}
306
				}
295
			} else {
307
			} else {
296
				savedIndexNamesFile.delete(); // forget saved indexes & delete each index file
308
				savedIndexNamesFile.delete(); // forget saved indexes & delete each index file
297
				File[] files = indexesDirectory.listFiles();
309
				File[] files = getIndexesDirectory().listFiles();
298
				if (files != null) {
310
				if (files != null) {
299
					for (int i = 0, l = files.length; i < l; i++) {
311
					for (int i = 0, l = files.length; i < l; i++) {
300
						String fileName = files[i].getAbsolutePath();
312
						String fileName = files[i].getAbsolutePath();
Lines 310-320 Link Here
310
	}
322
	}
311
	return this.indexStates;
323
	return this.indexStates;
312
}
324
}
313
private IPath getJavaPluginWorkingLocation() {
325
private File getIndexesDirectory() {
314
	if (this.javaPluginLocation != null) return this.javaPluginLocation;
326
	if (this.indexesDirectory == null) {
315
327
		this.indexesDirectory = JavaCore.getPlugin().getStateLocation().toFile();
316
	IPath stateLocation = JavaCore.getPlugin().getStateLocation();
328
	}
317
	return this.javaPluginLocation = stateLocation;
329
	return this.indexesDirectory;
318
}
330
}
319
public void indexDocument(SearchDocument searchDocument, SearchParticipant searchParticipant, Index index, IPath indexLocation) {
331
public void indexDocument(SearchDocument searchDocument, SearchParticipant searchParticipant, Index index, IPath indexLocation) {
320
	try {
332
	try {
Lines 365-372 Link Here
365
	IndexRequest request = null;
377
	IndexRequest request = null;
366
	if (target instanceof IFile) {
378
	if (target instanceof IFile) {
367
		request = new AddJarFileToIndex((IFile) target, this);
379
		request = new AddJarFileToIndex((IFile) target, this);
368
	} else if (target instanceof java.io.File) {
380
	} else if (target instanceof File) {
369
		if (((java.io.File) target).isFile()) {
381
		if (((File) target).isFile()) {
370
			request = new AddJarFileToIndex(path, this);
382
			request = new AddJarFileToIndex(path, this);
371
		} else {
383
		} else {
372
			return;
384
			return;
Lines 443-449 Link Here
443
		request = new IndexBinaryFolder((IFolder) target, this);
455
		request = new IndexBinaryFolder((IFolder) target, this);
444
	} else if (target instanceof IFile) {
456
	} else if (target instanceof IFile) {
445
		request = new AddJarFileToIndex((IFile) target, this);
457
		request = new AddJarFileToIndex((IFile) target, this);
446
	} else if (target instanceof java.io.File) {
458
	} else if (target instanceof File) {
447
		request = new AddJarFileToIndex(containerPath, this);
459
		request = new AddJarFileToIndex(containerPath, this);
448
	}
460
	}
449
	if (request != null)
461
	if (request != null)
Lines 466-472 Link Here
466
478
467
		if (VERBOSE)
479
		if (VERBOSE)
468
			Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
480
			Util.verbose("-> recreating index: "+indexLocation+" for path: "+containerPathString); //$NON-NLS-1$ //$NON-NLS-2$
469
		index = new Index(indexLocation, containerPathString, false /*reuse index file*/);
481
		index = new Index(getIndexFile(indexLocation), containerPathString, false /*reuse index file*/);
470
		this.indexes.put(indexLocation, index);
482
		this.indexes.put(indexLocation, index);
471
		index.monitor = monitor;
483
		index.monitor = monitor;
472
		return index;
484
		return index;
Lines 494-500 Link Here
494
	if (VERBOSE)
506
	if (VERBOSE)
495
		Util.verbose("removing index " + containerPath); //$NON-NLS-1$
507
		Util.verbose("removing index " + containerPath); //$NON-NLS-1$
496
	String indexLocation = computeIndexLocation(containerPath);
508
	String indexLocation = computeIndexLocation(containerPath);
497
	File indexFile = new File(indexLocation);
509
	File indexFile = getIndexFile(indexLocation);
498
	if (indexFile.exists())
510
	if (indexFile.exists())
499
		indexFile.delete();
511
		indexFile.delete();
500
	Object o = this.indexes.get(indexLocation);
512
	Object o = this.indexes.get(indexLocation);
Lines 521-527 Link Here
521
			if (index != null) index.monitor = null;
533
			if (index != null) index.monitor = null;
522
			if (locations == null) locations = new String[max];
534
			if (locations == null) locations = new String[max];
523
			locations[ptr++] = indexLocation;
535
			locations[ptr++] = indexLocation;
524
			File indexFile = new File(indexLocation);
536
			File indexFile = getIndexFile(indexLocation);
525
			if (indexFile.exists()) {
537
			if (indexFile.exists()) {
526
				indexFile.delete();
538
				indexFile.delete();
527
			}
539
			}
Lines 579-585 Link Here
579
		this.indexStates = null;
591
		this.indexStates = null;
580
	}
592
	}
581
	this.indexLocations = new SimpleLookupTable();
593
	this.indexLocations = new SimpleLookupTable();
582
	this.javaPluginLocation = null;
594
	this.indexesDirectory = null;
583
}
595
}
584
public void saveIndex(Index index) throws IOException {
596
public void saveIndex(Index index) throws IOException {
585
	// must have permission to write from the write monitor
597
	// must have permission to write from the write monitor
Lines 588-595 Link Here
588
			Util.verbose("-> saving index " + index.getIndexFile()); //$NON-NLS-1$
600
			Util.verbose("-> saving index " + index.getIndexFile()); //$NON-NLS-1$
589
		index.save();
601
		index.save();
590
	}
602
	}
591
	// TODO should use getJavaPluginWorkingLocation()+index simple name to avoid bugs such as https://bugs.eclipse.org/bugs/show_bug.cgi?id=62267
603
	String indexLocation = index.getIndexFile().getName();
592
	String indexLocation = index.getIndexFile().getPath();
593
	if (this.jobEnd > this.jobStart) {
604
	if (this.jobEnd > this.jobStart) {
594
		Object containerPath = this.indexLocations.keyForValue(indexLocation);
605
		Object containerPath = this.indexLocations.keyForValue(indexLocation);
595
		if (containerPath != null) {
606
		if (containerPath != null) {
Lines 737-742 Link Here
737
	BufferedWriter writer = null;
748
	BufferedWriter writer = null;
738
	try {
749
	try {
739
		writer = new BufferedWriter(new FileWriter(savedIndexNamesFile));
750
		writer = new BufferedWriter(new FileWriter(savedIndexNamesFile));
751
		writer.write(DiskIndex.SIGNATURE);
752
		writer.write('\n');
753
		writer.write(getIndexesDirectory().getAbsolutePath());
754
		writer.write('\n');
740
		Object[] keys = indexStates.keyTable;
755
		Object[] keys = indexStates.keyTable;
741
		Object[] states = indexStates.valueTable;
756
		Object[] states = indexStates.valueTable;
742
		for (int i = 0, l = states.length; i < l; i++) {
757
		for (int i = 0, l = states.length; i < l; i++) {
(-)compiler/org/eclipse/jdt/internal/compiler/util/SimpleSetOfCharArray.java (+15 lines)
Lines 76-81 Link Here
76
	return result;
76
	return result;
77
}
77
}
78
78
79
public char[] get(char[] object) {
80
	int length = this.values.length;
81
	int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length;
82
	char[] current;
83
	while ((current = this.values[index]) != null) {
84
		if (CharOperation.equals(current, object)) return current;
85
		if (++index == length) index = 0;
86
	}
87
	this.values[index] = object;
88
89
	// assumes the threshold is never equal to the size of the table
90
	if (++this.elementSize > this.threshold) rehash();
91
	return object;
92
}
93
79
public boolean includes(char[] object) {
94
public boolean includes(char[] object) {
80
	int length = values.length;
95
	int length = values.length;
81
	int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length;
96
	int index = (CharOperation.hashCode(object) & 0x7FFFFFFF) % length;

Return to bug 138309