| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.cdt.internal.core.index.impl; |
| |
| import org.eclipse.cdt.internal.core.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,<br> |
| * if the current references are [1 3 4]<br> |
| * and mapping is [1 2 3 4 5]<br> |
| * in references 1 becomes mapping[1] = 2, 3->4, and 4->5<br> |
| * => references = [2 4 5].<br> |
| */ |
| 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); |
| } |
| } |
| |