update copyrights
[fedora-idea.git] / platform / lang-impl / src / com / intellij / util / indexing / FileContentStorage.java
blob3037751322161121f1ac0f071a19dfd7e2447290
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.util.indexing;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.util.io.FileUtil;
21 import com.intellij.openapi.vfs.VirtualFile;
22 import com.intellij.util.containers.SLRUCache;
23 import gnu.trove.TIntHashSet;
24 import org.jetbrains.annotations.NotNull;
25 import org.jetbrains.annotations.Nullable;
27 import java.io.*;
29 /**
30 * @author Eugene Zhuravlev
31 * Date: Feb 19, 2008
33 public class FileContentStorage {
34 private static final Logger LOG = Logger.getInstance("#com.intellij.util.indexing.FileContentStorage");
35 private static final byte[] EMPTY_BYTE_ARRAY = new byte[]{};
37 private int myKeyBeingRemoved = -1;
38 private final File myStorageRoot;
39 private final TIntHashSet myFileIds = new TIntHashSet();
40 private final Object myLock = new Object();
42 private final SLRUCache<Integer, byte[]> myCache = new SLRUCache<Integer, byte[]>(256, 64) {
43 @NotNull
44 public byte[] createValue(final Integer key) {
45 final int _keyValue = key.intValue();
46 if (myFileIds.contains(_keyValue)) {
47 final File dataFile = getDataFile(_keyValue);
48 try {
49 return FileUtil.loadFileBytes(dataFile);
51 catch (IOException ignored) {
54 return EMPTY_BYTE_ARRAY;
57 protected void onDropFromCache(final Integer key, final byte[] bytes) {
58 if (key.intValue() == myKeyBeingRemoved) {
59 FileUtil.delete(getDataFile(key));
61 else if (bytes.length > 0){
62 final File dataFile = getDataFile(key);
63 try {
64 final BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(dataFile));
65 try {
66 os.write(bytes);
68 finally {
69 os.close();
72 catch (IOException e) {
73 LOG.error(e);
80 private File getDataFile(final int fileId) {
81 return new File(myStorageRoot, String.valueOf(fileId));
84 public FileContentStorage(File storageRoot) {
85 myStorageRoot = storageRoot;
86 final boolean wasCreated = storageRoot.mkdirs();
87 if (!wasCreated) {
88 final String[] names = storageRoot.list();
89 if (names != null) {
90 for (String name : names) {
91 try {
92 myFileIds.add(Integer.parseInt(name));
94 catch (NumberFormatException ignored) {
101 public void offer(VirtualFile file) throws IOException {
102 try {
103 final byte[] bytes = file.contentsToByteArray();
104 if (bytes != null) {
105 synchronized (myLock) {
106 final int fileId = Math.abs(FileBasedIndex.getFileId(file));
107 final boolean added = myFileIds.add(fileId);
108 if (added) {
109 myCache.put(fileId, bytes);
114 catch (FileNotFoundException ignored) {
115 // may happen, if content was never queried before
116 // In this case the index for this file must not have been built and it is ok to ignore the file
118 //catch (IOException e) {
119 // LOG.error(e);
123 @Nullable
124 public byte[] remove(VirtualFile file) {
125 final int fileId = Math.abs(FileBasedIndex.getFileId(file));
126 synchronized (myLock) {
127 try {
128 return myFileIds.contains(fileId)? myCache.get(fileId) : null;
130 finally {
131 if (myFileIds.remove(fileId)) {
132 myKeyBeingRemoved = fileId;
133 if (!myCache.remove(fileId)) {
134 FileUtil.delete(getDataFile(fileId));
136 myKeyBeingRemoved = -1;
142 public boolean containsContent(VirtualFile file) {
143 final int fileId = Math.abs(FileBasedIndex.getFileId(file));
144 synchronized (myLock) {
145 return myFileIds.contains(fileId);
149 public void dispose() {
150 myCache.clear(); // drop contexts on disk if something is left in memory