// Copyright 2014 The Bazel Authors. All rights reserved.
//
// 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.
package com.google.devtools.build.lib.util;

import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;

import java.util.Map;

/**
 * A string indexer backed by a map and reverse index lookup.
 * Every unique string is stored in memory exactly once.
 */
@ThreadSafe
public class CanonicalStringIndexer extends AbstractIndexer {

  private static final int NOT_FOUND = -1;

  // This is similar to (Synchronized) BiMap.
  // These maps *must* be weakly threadsafe to ensure thread safety for string
  // indexer as a whole. Specifically, mutating operations are serialized, but
  // read-only operations may be executed concurrently with mutators.
  private final Map<String, Integer> stringToInt;
  private final Map<Integer, String> intToString;

  /*
   * Creates an indexer instance from two backing maps. These maps may be
   * pre-initialized with data, but *must*:
   * a. Support read-only operations done concurrently with mutations.
   *    Note that mutations will be serialized.
   * b. Be reverse mappings of each other, if pre-initialized.
   */
  public CanonicalStringIndexer(Map<String, Integer> stringToInt,
                                Map<Integer, String> intToString) {
    Preconditions.checkArgument(stringToInt.size() == intToString.size());
    this.stringToInt = stringToInt;
    this.intToString = intToString;
  }


  @Override
  public synchronized void clear() {
    stringToInt.clear();
    intToString.clear();
  }

  @Override
  public int size() {
    return intToString.size();
  }

  @Override
  public int getOrCreateIndex(String s) {
    Integer i = stringToInt.get(s);
    if (i == null) {
      synchronized (this) {
        // First, make sure another thread hasn't just added the entry:
        i = stringToInt.get(s);
        if (i != null) {
          return i;
        }

        int ind = intToString.size();
        s = StringCanonicalizer.intern(s);
        stringToInt.put(s, ind);
        intToString.put(ind, s);
        return ind;
      }
    } else {
      return i;
    }
  }

  @Override
  public int getIndex(String s) {
    Integer i = stringToInt.get(s);
    return (i == null) ? NOT_FOUND : i;
  }

  @Override
  public synchronized boolean addString(String s) {
    int originalSize = size();
    getOrCreateIndex(s);
    return (size() > originalSize);
  }

  @Override
  public String getStringForIndex(int i) {
    return intToString.get(i);
  }

  @Override
  public synchronized String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("size = ").append(size()).append("\n");
    for (Map.Entry<String, Integer> entry : stringToInt.entrySet()) {
      builder.append(entry.getKey()).append(" <==> ").append(entry.getValue()).append("\n");
    }
    return builder.toString();
  }
}
