Package com.google.dart.engine.internal.index.file

Source Code of com.google.dart.engine.internal.index.file.FileNodeManager

/*
* Copyright (c) 2014, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

package com.google.dart.engine.internal.index.file;

import com.google.common.collect.Maps;
import com.google.dart.engine.context.AnalysisContext;
import com.google.dart.engine.utilities.logging.Logger;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
* A {@link FileManager} based {@link NodeManager}.
*
* @coverage dart.engine.index
*/
public class FileNodeManager implements NodeManager {
  private static int VERSION = 1;

  private final FileManager fileManager;
  private final Logger logger;
  private final StringCodec stringCodec;
  private final ContextCodec contextCodec;
  private final ElementCodec elementCodec;
  private final RelationshipCodec relationshipCodec;
  private final Map<String, Integer> nodeLocationCounts = Maps.newHashMap();
  private int locationCount = 0;

  public FileNodeManager(FileManager fileManager, Logger logger, StringCodec stringCodec,
      ContextCodec contextCodec, ElementCodec elementCodec, RelationshipCodec relationshipCodec) {
    this.fileManager = fileManager;
    this.logger = logger;
    this.stringCodec = stringCodec;
    this.contextCodec = contextCodec;
    this.elementCodec = elementCodec;
    this.relationshipCodec = relationshipCodec;
  }

  @Override
  public void clear() {
    fileManager.clear();
  }

  @Override
  public ContextCodec getContextCodec() {
    return contextCodec;
  }

  @Override
  public ElementCodec getElementCodec() {
    return elementCodec;
  }

  @Override
  public int getLocationCount() {
    return locationCount;
  }

  @Override
  public IndexNode getNode(String name) {
    try {
      InputStream inputStream = fileManager.openInputStream(name);
      if (inputStream != null) {
        try {
          DataInputStream stream = new DataInputStream(inputStream);
          // check version
          {
            int version = stream.readInt();
            if (version != VERSION) {
              throw new IllegalStateException("Version " + VERSION + " expected, but " + version
                  + " found.");
            }
          }
          // context
          int contextId = stream.readInt();
          AnalysisContext context = contextCodec.decode(contextId);
          if (context == null) {
            return null;
          }
          // relations
          Map<RelationKeyData, List<LocationData>> relations = Maps.newHashMap();
          int numRelations = stream.readInt();
          for (int i = 0; i < numRelations; i++) {
            RelationKeyData key = readElementRelationKey(stream);
            int numLocations = stream.readInt();
            List<LocationData> locations = new ArrayList<LocationData>(numLocations);
            for (int j = 0; j < numLocations; j++) {
              locations.add(readLocationData(stream));
            }
            relations.put(key, locations);
          }
          // create IndexNode
          IndexNode node = new IndexNode(context, elementCodec, relationshipCodec);
          node.setRelations(relations);
          return node;
        } finally {
          inputStream.close();
        }
      }
    } catch (Throwable e) {
      logger.logError("Exception during reading index file " + name, e);
    }
    return null;
  }

  @Override
  public StringCodec getStringCodec() {
    return stringCodec;
  }

  @Override
  public IndexNode newNode(AnalysisContext context) {
    return new IndexNode(context, elementCodec, relationshipCodec);
  }

  @Override
  public void putNode(String name, IndexNode node) {
    // update location count
    {
      locationCount -= getLocationCount(name);
      int nodeLocationCount = node.getLocationCount();
      nodeLocationCounts.put(name, nodeLocationCount);
      locationCount += nodeLocationCount;
    }
    // write the node
    try {
      OutputStream stream = fileManager.openOutputStream(name);
      try {
        writeNode(node, stream);
      } finally {
        stream.close();
      }
    } catch (Throwable e) {
      logger.logError("Exception during writing index file " + name, e);
    }
  }

  @Override
  public void removeNode(String name) {
    // update location count
    locationCount -= getLocationCount(name);
    nodeLocationCounts.remove(name);
    // remove node
    fileManager.delete(name);
  }

  private int getLocationCount(String name) {
    Integer locationCount = nodeLocationCounts.get(name);
    return locationCount != null ? locationCount : 0;
  }

  private RelationKeyData readElementRelationKey(DataInputStream stream) throws Exception {
    int elementId = stream.readInt();
    int relationshipId = stream.readInt();
    return new RelationKeyData(elementId, relationshipId);
  }

  private LocationData readLocationData(DataInputStream stream) throws Exception {
    int elementId = stream.readInt();
    int offset = stream.readInt();
    int length = stream.readInt();
    return new LocationData(elementId, offset, length);
  }

  private void writeElementRelationKey(DataOutputStream stream, RelationKeyData key)
      throws Exception {
    stream.writeInt(key.elementId);
    stream.writeInt(key.relationshipId);
  }

  private void writeNode(IndexNode node, OutputStream outputStream) throws Exception {
    DataOutputStream stream = new DataOutputStream(outputStream);
    // version
    stream.writeInt(VERSION);
    // context
    {
      AnalysisContext context = node.getContext();
      int contextId = contextCodec.encode(context);
      stream.writeInt(contextId);
    }
    // relations
    Map<RelationKeyData, List<LocationData>> relations = node.getRelations();
    stream.writeInt(relations.size());
    for (Entry<RelationKeyData, List<LocationData>> entry : relations.entrySet()) {
      RelationKeyData key = entry.getKey();
      List<LocationData> locations = entry.getValue();
      writeElementRelationKey(stream, key);
      stream.writeInt(locations.size());
      for (LocationData location : locations) {
        stream.writeInt(location.elementId);
        stream.writeInt(location.offset);
        stream.writeInt(location.length);
      }
    }
  }
}
TOP

Related Classes of com.google.dart.engine.internal.index.file.FileNodeManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.