1 11 package org.eclipse.core.internal.events; 12 13 import org.eclipse.core.runtime.IPath; 14 15 19 public class NodeIDMap { 20 private static final int[] SIZES = new int[] {13, 29, 71, 173, 349, 733, 1511, 3079, 6133, 16381, 32653, 65543, 131111, 262139, 524287, 1051601}; 22 private static final double LOAD_FACTOR = 0.75; 23 private static final long LARGE_NUMBER = 2654435761L; 25 26 int sizeOffset = 0; 27 protected int elementCount = 0; 28 protected long[] ids; 29 protected IPath[] oldPaths; 30 protected IPath[] newPaths; 31 32 35 public NodeIDMap() { 36 this.sizeOffset = 0; 37 this.ids = new long[SIZES[sizeOffset]]; 38 this.oldPaths = new IPath[SIZES[sizeOffset]]; 39 this.newPaths = new IPath[SIZES[sizeOffset]]; 40 } 41 42 46 protected void expand() { 47 int newLength; 48 try { 49 newLength = SIZES[++sizeOffset]; 50 } catch (ArrayIndexOutOfBoundsException e) { 51 newLength = ids.length * 2; 53 } 54 long[] grownIds = new long[newLength]; 55 IPath[] grownOldPaths = new IPath[newLength]; 56 IPath[] grownNewPaths = new IPath[newLength]; 57 int maxArrayIndex = newLength - 1; 58 for (int i = 0; i < ids.length; i++) { 59 long id = ids[i]; 60 if (id != 0) { 61 int hash = hashFor(id, newLength); 62 while (grownIds[hash] != 0) { 63 hash++; 64 if (hash > maxArrayIndex) 65 hash = 0; 66 } 67 grownIds[hash] = id; 68 grownOldPaths[hash] = oldPaths[i]; 69 grownNewPaths[hash] = newPaths[i]; 70 } 71 } 72 ids = grownIds; 73 oldPaths = grownOldPaths; 74 newPaths = grownNewPaths; 75 } 76 77 81 private int getIndex(long searchID) { 82 final int len = ids.length; 83 int hash = hashFor(searchID, len); 84 85 for (int i = hash; i < len; i++) { 87 if (ids[i] == searchID) 88 return i; 89 if (ids[i] == 0) 91 return -1; 92 } 93 94 for (int i = 0; i < hash - 1; i++) { 96 if (ids[i] == searchID) 97 return i; 98 if (ids[i] == 0) 100 return -1; 101 } 102 return -1; 104 } 105 106 110 public IPath getNewPath(long nodeID) { 111 int index = getIndex(nodeID); 112 if (index == -1) 113 return null; 114 return newPaths[index]; 115 } 116 117 121 public IPath getOldPath(long nodeID) { 122 int index = getIndex(nodeID); 123 if (index == -1) 124 return null; 125 return oldPaths[index]; 126 } 127 128 private int hashFor(long id, int size) { 129 return (int) Math.abs((id * LARGE_NUMBER) % size); 131 } 132 133 137 public boolean isEmpty() { 138 return elementCount == 0; 139 } 140 141 145 private void put(long id, IPath oldPath, IPath newPath) { 146 if (oldPath == null && newPath == null) 147 return; 148 int hash = hashFor(id, ids.length); 149 150 for (int i = hash; i < ids.length; i++) { 152 if (ids[i] == id) { 153 if (oldPath != null) 155 oldPaths[i] = oldPath; 156 if (newPath != null) 157 newPaths[i] = newPath; 158 return; 159 } 160 if (ids[i] == 0) { 161 ids[i] = id; 163 if (oldPath != null) 164 oldPaths[i] = oldPath; 165 if (newPath != null) 166 newPaths[i] = newPath; 167 elementCount++; 168 if (shouldGrow()) 170 expand(); 171 return; 172 } 173 } 174 175 for (int i = 0; i < hash - 1; i++) { 177 if (ids[i] == id) { 178 if (oldPath != null) 180 oldPaths[i] = oldPath; 181 if (newPath != null) 182 newPaths[i] = newPath; 183 return; 184 } 185 if (ids[i] == 0) { 186 ids[i] = id; 188 if (oldPath != null) 189 oldPaths[i] = oldPath; 190 if (newPath != null) 191 newPaths[i] = newPath; 192 elementCount++; 193 if (shouldGrow()) 195 expand(); 196 return; 197 } 198 } 199 expand(); 201 put(id, oldPath, newPath); 202 } 203 204 207 public void putOldPath(long id, IPath path) { 208 put(id, path, null); 209 } 210 211 214 public void putNewPath(long id, IPath path) { 215 put(id, null, path); 216 } 217 218 private boolean shouldGrow() { 219 return elementCount > ids.length * LOAD_FACTOR; 220 } 221 } 222 | Popular Tags |