package com.chenyang.druid.sql.parser;

import com.chenyang.druid.sql.ast.SQLExpr;
import com.chenyang.druid.util.FnvHash;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class InsertColumnsCache {
   public static InsertColumnsCache global = new InsertColumnsCache(8192);
   public ConcurrentMap<Long, Entry> cache = new ConcurrentHashMap();
   private final Entry[] buckets;
   private final int indexMask;

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

   public final Entry get(long hashCode64) {
      int bucket = (int)hashCode64 & this.indexMask;

      for(Entry entry = this.buckets[bucket]; entry != null; entry = entry.next) {
         if (hashCode64 == entry.hashCode64) {
            return entry;
         }
      }

      return null;
   }

   public boolean put(long hashCode64, String columnsString, String columnsFormattedString, List<SQLExpr> columns) {
      int bucket = (int)hashCode64 & this.indexMask;

      for(Entry entry = this.buckets[bucket]; entry != null; entry = entry.next) {
         if (hashCode64 == entry.hashCode64) {
            return true;
         }
      }

      Entry entry = new Entry(hashCode64, columnsString, columnsFormattedString, columns, this.buckets[bucket]);
      this.buckets[bucket] = entry;
      return false;
   }

   public static final class Entry {
      public final long hashCode64;
      public final String columnsString;
      public final String columnsFormattedString;
      public final long columnsFormattedStringHash;
      public final List<SQLExpr> columns;
      public final Entry next;

      public Entry(long hashCode64, String columnsString, String columnsFormattedString, List<SQLExpr> columns, Entry next) {
         this.hashCode64 = hashCode64;
         this.columnsString = columnsString;
         this.columnsFormattedString = columnsFormattedString;
         this.columnsFormattedStringHash = FnvHash.fnv1a_64_lower(columnsFormattedString);
         this.columns = columns;
         this.next = next;
      }
   }
}
