/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 *
 * 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.
 */

/*
 * @author: Eugene Zhuravlev
 * Date: Mar 3, 2003
 * Time: 12:34:44 PM
 */
package com.intellij.compiler;

import com.intellij.compiler.make.CacheCorruptedException;
import com.intellij.openapi.compiler.CompilerBundle;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.SLRUCache;
import com.intellij.util.io.PersistentEnumerator;
import com.intellij.util.io.PersistentStringEnumerator;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.io.IOException;

public class SymbolTable {
  private final PersistentStringEnumerator myTrie;

  // both caches should have equal size
  private static final int STRING_CACHE_SIZE = 1024;

  private final SLRUCache<Integer, String> myIndexStringCache = new SLRUCache<Integer, String>(STRING_CACHE_SIZE * 2, STRING_CACHE_SIZE) {
    @NotNull
    public String createValue(Integer key) {
      try {
        return myTrie.valueOf(key.intValue());
      }
      catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
  };
  
  private final SLRUCache<String, Integer> myStringIndexCache = new SLRUCache<String, Integer>(STRING_CACHE_SIZE * 2, STRING_CACHE_SIZE) {
    @NotNull
    public Integer createValue(String key) {
      try {
        return myTrie.enumerate(key);
      }
      catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
  };


  public SymbolTable(File file) throws CacheCorruptedException {
    try {
      if (!file.exists()) {
        FileUtil.createIfDoesntExist(file);
      }
      myTrie = new PersistentStringEnumerator(file);
    }
    catch (PersistentEnumerator.CorruptedException e) {
      throw new CacheCorruptedException(CompilerBundle.message("error.compiler.caches.corrupted"), e);
    }
    catch (IOException e) {
      throw new CacheCorruptedException(e);
    }
  }

  public synchronized int getId(@NotNull String symbol) throws CacheCorruptedException {
    if (symbol.length() == 0) {
      return -1;
    }
    try {
      return myStringIndexCache.get(symbol);
    }
    catch (RuntimeException e) {
      if (e.getCause() instanceof IOException) {
        throw new CacheCorruptedException(e.getCause());
      }
      throw e;
    }
  }

  public synchronized String getSymbol(int id) throws CacheCorruptedException {
    if (id == -1) {
      return "";
    }
    try {
      return myIndexStringCache.get(id);
    }
    catch (RuntimeException e) {
      if (e.getCause() instanceof IOException) {
        throw new CacheCorruptedException(e.getCause());
      }
      throw e;
    }
  }

  public synchronized void dispose() throws CacheCorruptedException {
    try {
      myIndexStringCache.clear();
      myStringIndexCache.clear();
      myTrie.close(); // will call "flush()" if needed
    }
    catch (IOException e) {
      throw new CacheCorruptedException(e);
    }
  }
}

@@ -867,55 +867,8 @@
 il;%0A
-import com.intellij.util.containers.SLRUCache;%0A
 impo
@@ -1145,802 +1145,8 @@
 e;%0A%0A
-  // both caches should have equal size%0A  private static final int STRING_CACHE_SIZE = 1024;%0A%0A  private final SLRUCache%3CInteger, String%3E myIndexStringCache = new SLRUCache%3CInteger, String%3E(STRING_CACHE_SIZE * 2, STRING_CACHE_SIZE) %7B%0A    @NotNull%0A    public String createValue(Integer key) %7B%0A      try %7B%0A        return myTrie.valueOf(key.intValue());%0A      %7D%0A      catch (IOException e) %7B%0A        throw new RuntimeException(e);%0A      %7D%0A    %7D%0A  %7D;%0A  %0A  private final SLRUCache%3CString, Integer%3E myStringIndexCache = new SLRUCache%3CString, Integer%3E(STRING_CACHE_SIZE * 2, STRING_CACHE_SIZE) %7B%0A    @NotNull%0A    public Integer createValue(String key) %7B%0A      try %7B%0A        return myTrie.enumerate(key);%0A      %7D%0A      catch (IOException e) %7B%0A        throw new RuntimeException(e);%0A      %7D%0A    %7D%0A  %7D;%0A%0A%0A
   pu
@@ -1342,24 +1342,30 @@
 merator(file
+, true
 );%0A    %7D%0A   
@@ -1618,29 +1618,16 @@
  public 
-synchronized 
 int getI
@@ -1769,28 +1769,22 @@
 n my
-StringIndexCache.get
+Trie.enumerate
 (sym
@@ -1798,39 +1798,34 @@
    %7D%0A    catch (
-Runtime
+IO
 Exception e) %7B%0A 
@@ -1827,59 +1827,8 @@
 ) %7B%0A
-      if (e.getCause() instanceof IOException) %7B%0A  
     
@@ -1878,39 +1878,16 @@
 use());%0A
-      %7D%0A      throw e;%0A
     %7D%0A  
@@ -1898,29 +1898,16 @@
  public 
-synchronized 
 String g
@@ -2028,28 +2028,20 @@
 n my
-IndexStringCache.get
+Trie.valueOf
 (id)
@@ -2063,15 +2063,10 @@
 ch (
-Runtime
+IO
 Exce
@@ -2080,59 +2080,8 @@
 ) %7B%0A
-      if (e.getCause() instanceof IOException) %7B%0A  
     
@@ -2135,31 +2135,8 @@
 ));%0A
-      %7D%0A      throw e;%0A
     
@@ -2155,21 +2155,8 @@
 lic 
-synchronized 
 void
@@ -2213,76 +2213,8 @@
 y %7B%0A
-      myIndexStringCache.clear();%0A      myStringIndexCache.clear();%0A
     

Use PersistentStringEnumerator's caches