OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2014, the Dart project authors. |
| 3 * |
| 4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except |
| 5 * in compliance with the License. You may obtain a copy of the License at |
| 6 * |
| 7 * http://www.eclipse.org/legal/epl-v10.html |
| 8 * |
| 9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License |
| 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express |
| 11 * or implied. See the License for the specific language governing permissions a
nd limitations under |
| 12 * the License. |
| 13 */ |
| 14 |
| 15 package com.google.dart.engine.internal.index.file; |
| 16 |
| 17 import com.google.common.collect.Maps; |
| 18 import com.google.dart.engine.context.AnalysisContext; |
| 19 import com.google.dart.engine.utilities.logging.Logger; |
| 20 |
| 21 import java.io.DataInputStream; |
| 22 import java.io.DataOutputStream; |
| 23 import java.io.InputStream; |
| 24 import java.io.OutputStream; |
| 25 import java.util.ArrayList; |
| 26 import java.util.List; |
| 27 import java.util.Map; |
| 28 import java.util.Map.Entry; |
| 29 |
| 30 /** |
| 31 * A {@link FileManager} based {@link NodeManager}. |
| 32 * |
| 33 * @coverage dart.engine.index |
| 34 */ |
| 35 public class FileNodeManager implements NodeManager { |
| 36 private static int VERSION = 1; |
| 37 |
| 38 private final FileManager fileManager; |
| 39 private final Logger logger; |
| 40 private final StringCodec stringCodec; |
| 41 private final ContextCodec contextCodec; |
| 42 private final ElementCodec elementCodec; |
| 43 private final RelationshipCodec relationshipCodec; |
| 44 private final Map<String, Integer> nodeLocationCounts = Maps.newHashMap(); |
| 45 private int locationCount = 0; |
| 46 |
| 47 public FileNodeManager(FileManager fileManager, Logger logger, StringCodec str
ingCodec, |
| 48 ContextCodec contextCodec, ElementCodec elementCodec, RelationshipCodec re
lationshipCodec) { |
| 49 this.fileManager = fileManager; |
| 50 this.logger = logger; |
| 51 this.stringCodec = stringCodec; |
| 52 this.contextCodec = contextCodec; |
| 53 this.elementCodec = elementCodec; |
| 54 this.relationshipCodec = relationshipCodec; |
| 55 } |
| 56 |
| 57 @Override |
| 58 public void clear() { |
| 59 fileManager.clear(); |
| 60 } |
| 61 |
| 62 @Override |
| 63 public ContextCodec getContextCodec() { |
| 64 return contextCodec; |
| 65 } |
| 66 |
| 67 @Override |
| 68 public ElementCodec getElementCodec() { |
| 69 return elementCodec; |
| 70 } |
| 71 |
| 72 @Override |
| 73 public int getLocationCount() { |
| 74 return locationCount; |
| 75 } |
| 76 |
| 77 @Override |
| 78 public IndexNode getNode(String name) { |
| 79 try { |
| 80 InputStream inputStream = fileManager.openInputStream(name); |
| 81 if (inputStream != null) { |
| 82 try { |
| 83 DataInputStream stream = new DataInputStream(inputStream); |
| 84 // check version |
| 85 { |
| 86 int version = stream.readInt(); |
| 87 if (version != VERSION) { |
| 88 throw new IllegalStateException("Version " + VERSION + " expected,
but " + version |
| 89 + " found."); |
| 90 } |
| 91 } |
| 92 // context |
| 93 int contextId = stream.readInt(); |
| 94 AnalysisContext context = contextCodec.decode(contextId); |
| 95 if (context == null) { |
| 96 return null; |
| 97 } |
| 98 // relations |
| 99 Map<RelationKeyData, List<LocationData>> relations = Maps.newHashMap()
; |
| 100 int numRelations = stream.readInt(); |
| 101 for (int i = 0; i < numRelations; i++) { |
| 102 RelationKeyData key = readElementRelationKey(stream); |
| 103 int numLocations = stream.readInt(); |
| 104 List<LocationData> locations = new ArrayList<LocationData>(numLocati
ons); |
| 105 for (int j = 0; j < numLocations; j++) { |
| 106 locations.add(readLocationData(stream)); |
| 107 } |
| 108 relations.put(key, locations); |
| 109 } |
| 110 // create IndexNode |
| 111 IndexNode node = new IndexNode(context, elementCodec, relationshipCode
c); |
| 112 node.setRelations(relations); |
| 113 return node; |
| 114 } finally { |
| 115 inputStream.close(); |
| 116 } |
| 117 } |
| 118 } catch (Throwable e) { |
| 119 logger.logError("Exception during reading index file " + name, e); |
| 120 } |
| 121 return null; |
| 122 } |
| 123 |
| 124 @Override |
| 125 public StringCodec getStringCodec() { |
| 126 return stringCodec; |
| 127 } |
| 128 |
| 129 @Override |
| 130 public IndexNode newNode(AnalysisContext context) { |
| 131 return new IndexNode(context, elementCodec, relationshipCodec); |
| 132 } |
| 133 |
| 134 @Override |
| 135 public void putNode(String name, IndexNode node) { |
| 136 // update location count |
| 137 { |
| 138 locationCount -= getLocationCount(name); |
| 139 int nodeLocationCount = node.getLocationCount(); |
| 140 nodeLocationCounts.put(name, nodeLocationCount); |
| 141 locationCount += nodeLocationCount; |
| 142 } |
| 143 // write the node |
| 144 try { |
| 145 OutputStream stream = fileManager.openOutputStream(name); |
| 146 try { |
| 147 writeNode(node, stream); |
| 148 } finally { |
| 149 stream.close(); |
| 150 } |
| 151 } catch (Throwable e) { |
| 152 logger.logError("Exception during writing index file " + name, e); |
| 153 } |
| 154 } |
| 155 |
| 156 @Override |
| 157 public void removeNode(String name) { |
| 158 // update location count |
| 159 locationCount -= getLocationCount(name); |
| 160 nodeLocationCounts.remove(name); |
| 161 // remove node |
| 162 fileManager.delete(name); |
| 163 } |
| 164 |
| 165 private int getLocationCount(String name) { |
| 166 Integer locationCount = nodeLocationCounts.get(name); |
| 167 return locationCount != null ? locationCount : 0; |
| 168 } |
| 169 |
| 170 private RelationKeyData readElementRelationKey(DataInputStream stream) throws
Exception { |
| 171 int elementId = stream.readInt(); |
| 172 int relationshipId = stream.readInt(); |
| 173 return new RelationKeyData(elementId, relationshipId); |
| 174 } |
| 175 |
| 176 private LocationData readLocationData(DataInputStream stream) throws Exception
{ |
| 177 int elementId = stream.readInt(); |
| 178 int offset = stream.readInt(); |
| 179 int length = stream.readInt(); |
| 180 return new LocationData(elementId, offset, length); |
| 181 } |
| 182 |
| 183 private void writeElementRelationKey(DataOutputStream stream, RelationKeyData
key) |
| 184 throws Exception { |
| 185 stream.writeInt(key.elementId); |
| 186 stream.writeInt(key.relationshipId); |
| 187 } |
| 188 |
| 189 private void writeNode(IndexNode node, OutputStream outputStream) throws Excep
tion { |
| 190 DataOutputStream stream = new DataOutputStream(outputStream); |
| 191 // version |
| 192 stream.writeInt(VERSION); |
| 193 // context |
| 194 { |
| 195 AnalysisContext context = node.getContext(); |
| 196 int contextId = contextCodec.encode(context); |
| 197 stream.writeInt(contextId); |
| 198 } |
| 199 // relations |
| 200 Map<RelationKeyData, List<LocationData>> relations = node.getRelations(); |
| 201 stream.writeInt(relations.size()); |
| 202 for (Entry<RelationKeyData, List<LocationData>> entry : relations.entrySet()
) { |
| 203 RelationKeyData key = entry.getKey(); |
| 204 List<LocationData> locations = entry.getValue(); |
| 205 writeElementRelationKey(stream, key); |
| 206 stream.writeInt(locations.size()); |
| 207 for (LocationData location : locations) { |
| 208 stream.writeInt(location.elementId); |
| 209 stream.writeInt(location.offset); |
| 210 stream.writeInt(location.length); |
| 211 } |
| 212 } |
| 213 } |
| 214 } |
OLD | NEW |