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.
16 package com.intellij.openapi.project;
18 import com.intellij.ide.caches.FileContent;
19 import com.intellij.openapi.application.ApplicationManager;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.progress.ProcessCanceledException;
22 import com.intellij.openapi.progress.ProgressIndicator;
23 import com.intellij.openapi.progress.ProgressManager;
24 import com.intellij.openapi.vfs.VirtualFile;
25 import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
26 import org.jetbrains.annotations.NotNull;
27 import org.jetbrains.annotations.Nullable;
29 import java.io.IOException;
30 import java.util.Collection;
31 import java.util.concurrent.ArrayBlockingQueue;
36 @SuppressWarnings({"SynchronizeOnThis"})
37 public class FileContentQueue {
38 private static final Logger LOG = Logger.getInstance("#com.intellij.ide.startup.FileContentQueue");
39 private static final long SIZE_THRESHOLD = 1024*1024;
40 private long myTotalSize;
42 private final ArrayBlockingQueue<FileContent> myQueue = new ArrayBlockingQueue<FileContent>(256);
43 private FileContent myPushbackBuffer;
45 public void queue(final Collection<VirtualFile> files, @Nullable final ProgressIndicator indicator) {
46 final Runnable contentLoadingRunnable = new Runnable() {
49 for (VirtualFile file : files) {
50 if (indicator != null) {
51 indicator.checkCanceled();
56 // put end-of-queue marker only if not canceled
58 myQueue.put(new FileContent(null));
60 catch (InterruptedException e) {
64 catch (ProcessCanceledException e) {
65 // Do nothing, exit the thread.
67 catch (InterruptedException e) {
73 ApplicationManager.getApplication().executeOnPooledThread(contentLoadingRunnable);
76 private void put(VirtualFile file) throws InterruptedException {
77 final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
79 FileContent content = new FileContent(file);
82 final long contentLength = content.getLength();
83 boolean counterUpdated = false;
85 if (contentLength < PersistentFS.MAX_INTELLISENSE_FILESIZE) {
87 while (myTotalSize > SIZE_THRESHOLD) {
88 if (indicator != null) {
89 indicator.checkCanceled();
93 myTotalSize += contentLength;
94 counterUpdated = true;
97 content.getBytes(); // Reads the content bytes and caches them.
100 catch (IOException e) {
102 if (counterUpdated) {
103 synchronized (this) {
104 myTotalSize -= contentLength; // revert size counter
108 content.setEmptyContent();
110 catch (ProcessCanceledException e) {
111 if (counterUpdated) {
112 synchronized (this) {
113 myTotalSize -= contentLength; // revert size counter
119 catch (InterruptedException e) {
120 if (counterUpdated) {
121 synchronized (this) {
122 myTotalSize -= contentLength; // revert size counter
128 catch (Throwable e) {
133 content.setEmptyContent();
136 myQueue.put(content);
139 public FileContent take() {
141 synchronized (this) {
142 if (myPushbackBuffer != null) {
143 result = myPushbackBuffer;
144 myPushbackBuffer = null;
150 result = myQueue.take();
152 catch (InterruptedException e) {
153 throw new RuntimeException(e);
156 final VirtualFile file = result.getVirtualFile();
160 if (result.getLength() < PersistentFS.MAX_INTELLISENSE_FILESIZE) {
161 synchronized (this) {
163 myTotalSize -= result.getLength();
174 public synchronized void pushback(@NotNull FileContent content) {
175 LOG.assertTrue(myPushbackBuffer == null, "Pushback buffer is already full");
176 myPushbackBuffer = content;