/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.opennlp.ml.maxent;

import org.apache.opennlp.ml.model.MaxentModel;

/**
 * A object which can be used to ensure that a Maxent application can swap the
 * model currently in use with a new one in a thread-safe manner without
 * stopping the servicing of requests. Use this if your maxent application is
 * a heavy-weight one or you have only one particular MaxentModel to use with
 * your application. If your application class is lightweight and you will be
 * creating multiple instances of it with different underlying models, consider
 * using a DomainToModelMap object to ensure thread-safe model swapping.
 *
 * <p>For example, in your application, create a ModelReplacementManager as
 * follows:
 *
 *     <pre>
 *     private final ModelReplacementManager replacementManager =
 *	  new ModelReplacementManager(
 *	      new ModelSetter() {
 *		  public void setModel(MaxentModel m) {
 *		      model = m;
 *		  }
 *	      }
 *	  );
 *     </pre>
 *
 * where "model" would be the actual variable name of the model used by your
 * application which you wish to be able to swap (you might have other models
 * which need their own ModelReplacementManager).
 *
 * <p>You'll also need a method to swap the model which calls the manager's
 * replaceModel(MaxentModel m) method, e.g.,
 *
 *     <pre>
 *     public void replaceModel (MaxentModel newmod) {
 *	  replacementManager.replaceModel(newmod);
 *    }
 *     </pre>
 * 
 * Then, in the code that uses the model, you need to inform the
 * ModelReplacementManager when a thread is beginning to use the model and when
 * it no longer needs to be sure that the same model is being used.  For
 * example, it is quite common to evaluate a particular context, get back a
 * double[] which has the normalized probabilities of each of the outcomes given
 * that context, and then request the name of a particular outcome.  The model
 * cannot be swapped during that time since the mapping from outcome labels to
 * unique will (probably) be different between the different models.  So, do as
 * follows:
 *
 *     <pre>
 *	  replacementManager.startUsingModel();
 *	    // some code which evaluates the context, e.g.,
 *	    double[] probs = model.eval(someContext);
 *	    // some code which returns a particular outcome
 *	    if (model.getBestOutcome(probs).equals("T") ...
 *	  replacementManager.finishUsingModel();
 *     </pre>
 *
 * The manager will then make sure that all requests which are currently being
 * serviced are completed before the new model is swapped in.  New requests
 * which are made while the models are being swapped are forced to wait for the
 * swap to finish.  These requests will then be serviced by the new model.
 */
public class ModelReplacementManager {
  private ModelSetter setter;

  private int users = 0;
  private boolean replacementCanProceed = true;
  private Thread replacementThread = null;

  public ModelReplacementManager(ModelSetter ms) {
    setter = ms;
  }

  /**
   * Inform the manager that a thread is using the model. If a replacement is
   * underway, the thread is forced to join the replacement thread and thus wait
   * until it is finished to begin using the model.
   */
  public void startUsingModel() {
    if (replacementThread != null) {
      try {
        replacementThread.join();
      } catch (InterruptedException e) {
      }
    }
    replacementCanProceed = false;
    users++;
  }

  /**
   * Inform the manager that a thread is done using the model, and thus is not
   * dependending on it being unchanged.
   */
  public void finishUsingModel() {
    users--;
    if (users <= 0)
      replacementCanProceed = true;
  }

  /**
   * Replace the old model with a new one, forcing the replacement to wait until
   * all threads using the old model have finished using it.
   * 
   * @param model
   *          The new model which is being swapped in.
   */
  public synchronized void replaceModel(MaxentModel model) {
    replacementThread = Thread.currentThread();
    while (!replacementCanProceed)
      Thread.yield();
    setter.setModel(model);
    replacementThread = null;
  }
    
}
