package com.chenyang.druid.sql.parser;

import java.nio.charset.Charset;

public class SymbolTable {
   private static final Charset UTF8 = Charset.forName("UTF-8");
   private static final boolean JVM_16;
   public static SymbolTable global;
   private final Entry[] entries;
   private final int indexMask;

   public SymbolTable(int tableSize) {
      this.indexMask = tableSize - 1;
      this.entries = new Entry[tableSize];
   }

   public String addSymbol(String buffer, int offset, int len, long hash) {
      int bucket = (int)hash & this.indexMask;
      Entry entry = this.entries[bucket];
      if (entry != null) {
         if (hash == entry.hash) {
            return entry.value;
         } else {
            String str = JVM_16 ? subString(buffer, offset, len) : buffer.substring(offset, offset + len);
            return str;
         }
      } else {
         String str = JVM_16 ? subString(buffer, offset, len) : buffer.substring(offset, offset + len);
         entry = new Entry(hash, len, str);
         this.entries[bucket] = entry;
         return str;
      }
   }

   public String addSymbol(byte[] buffer, int offset, int len, long hash) {
      int bucket = (int)hash & this.indexMask;
      Entry entry = this.entries[bucket];
      if (entry != null) {
         if (hash == entry.hash) {
            return entry.value;
         } else {
            String str = subString(buffer, offset, len);
            return str;
         }
      } else {
         String str = subString(buffer, offset, len);
         entry = new Entry(hash, len, str);
         this.entries[bucket] = entry;
         return str;
      }
   }

   public String addSymbol(String symbol, long hash) {
      int bucket = (int)hash & this.indexMask;
      Entry entry = this.entries[bucket];
      if (entry != null) {
         return hash == entry.hash ? entry.value : symbol;
      } else {
         entry = new Entry(hash, symbol.length(), symbol);
         this.entries[bucket] = entry;
         return symbol;
      }
   }

   public String findSymbol(long hash) {
      int bucket = (int)hash & this.indexMask;
      Entry entry = this.entries[bucket];
      return entry != null && entry.hash == hash ? entry.value : null;
   }

   private static String subString(String src, int offset, int len) {
      char[] chars = new char[len];
      src.getChars(offset, offset + len, chars, 0);
      return new String(chars);
   }

   private static String subString(byte[] bytes, int from, int len) {
      byte[] strBytes = new byte[len];
      System.arraycopy(bytes, from, strBytes, 0, len);
      return new String(strBytes, UTF8);
   }

   static {
      String version = null;

      try {
         version = System.getProperty("java.specification.version");
      } catch (IllegalArgumentException var2) {
      } catch (SecurityException var3) {
      }

      JVM_16 = "1.6".equals(version);
      global = new SymbolTable(32768);
   }

   private static class Entry {
      public final long hash;
      public final int len;
      public final String value;

      public Entry(long hash, int len, String value) {
         this.hash = hash;
         this.len = len;
         this.value = value;
      }
   }
}
