/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * This software is the proprietary information of Sun Microsystems, Inc.
 * Use is subject to license terms.
 * 
 * Copyright 2004 Sun Microsystems, Inc.  Tous droits réservés.
 * Ce logiciel est propriété de Sun Microsystems, Inc.
 * Distribué par des licences qui en restreignent l'utilisation.
 *
 * ident        "@(#)STORE.java 1.8     04/05/19 SMI"
 *
 */

package com.sun.mfwk.examples.storeCP;

// java imports
//

import java.util.*;
import java.util.logging.Logger;


// JESMA transaction API
//

import com.sun.mfwk.trans.*;
import com.sun.mfwk.util.instrum.*;
import com.sun.mfwk.discovery.*;
import com.sun.mfwk.util.log.*;


public class STORE {

       MfResourceMetrics monitoring;
       Hashtable store;
       
       public static final String NOT_AVAILABLE = new String("This entry is not available in the store");
       public static final String ERROR = new String("An error occured in the store");
       
       Logger logger = MfLogService.getLogger("STORE");
       
       /*
       ** Constructor
       */
       public STORE() {
	       store = new Hashtable();
       }
       
       
       /*
       ** Setter for ResourceMetrics
       */
       public void setResourceMetrics(MfResourceMetrics m) {
	       this.monitoring = m;
       }
       
       /*
       ** SEARCH method
       */
       
       public String SEARCH(String k) {
	       try {
		       String result = "";
		       long startTime = java.lang.System.currentTimeMillis();
		       
		       logger.finest("STORE:search:sleep ");
		       STORE.sleep();
		       
		       result = search(k);
		       
		       long stopTime = java.lang.System.currentTimeMillis();
		       long operationTime = stopTime - startTime;
		       
		       monitoring.setAccumulatedOperationTime(monitoring.getAccumulatedOperationTime() + operationTime);
		       monitoring.setAccumulatedSqOperationTime(monitoring.getAccumulatedSqOperationTime() + (operationTime*operationTime));
		       monitoring.setNbOperations(monitoring.getNbOperations() + 1);
		       updateMinMaxOperationTime(operationTime);
		       
		       return result;
		       
	       } catch (Exception e) {
		       monitoring.setFailedOperations(monitoring.getFailedOperations() + 1);
		       return ERROR;
	       }
       }
 
       
       private synchronized String search(String k) {
	       String result = "";
	       if (! store.containsKey(k) ) {
			       result = NOT_AVAILABLE;
	       } else {
			       result = (String) store.get(k);
	       }
	       return result;
       }
       
       
       /*
       ** MODIFY method
       */
       
       public String MODIFY(String k, String v)  {
	       try {
		       String result = "";
		       long startTime = java.lang.System.currentTimeMillis();
		       
		       logger.finest("STORE:modify:sleep ");
		       STORE.sleep();
		     
		       result = modify(k, v);
		       
		       long stopTime = java.lang.System.currentTimeMillis();
		       long operationTime = stopTime - startTime;
		       
		       monitoring.setAccumulatedOperationTime(monitoring.getAccumulatedOperationTime() + operationTime);
		       monitoring.setAccumulatedSqOperationTime(monitoring.getAccumulatedSqOperationTime() + (operationTime*operationTime));
		       monitoring.setNbOperations(monitoring.getNbOperations() + 1);
		       updateMinMaxOperationTime(operationTime);
		       
		       return result;
		       
	       } catch (Exception e) {
		       monitoring.setFailedOperations(monitoring.getFailedOperations() + 1);
		       return ERROR;
	       }
       }

       private synchronized String modify(String k, String v)  {
	       String result = "";
	       
       	       if (! store.containsKey(k) ) {
	              result = NOT_AVAILABLE;
		      store.put(k, v);			       
	       } else {
		      result = (String) store.put(k, v);
	       }
	       return result;
       }
       
       
       /*
       ** REMOVE method
       */
       
       public String REMOVE(String k)  {
	       try {
		       String result = "";
		       long startTime = java.lang.System.currentTimeMillis();
		       
		       logger.finest("STORE:remove:sleep ");
		       STORE.sleep();
		     
		       result = remove(k);
		       
		       long stopTime = java.lang.System.currentTimeMillis();
		       long operationTime = stopTime - startTime;
		       
		       monitoring.setAccumulatedOperationTime(monitoring.getAccumulatedOperationTime() + operationTime);
		       monitoring.setAccumulatedSqOperationTime(monitoring.getAccumulatedSqOperationTime() + (operationTime*operationTime));
		       monitoring.setNbOperations(monitoring.getNbOperations() + 1);
		       updateMinMaxOperationTime(operationTime);
		       
		       return result;
		       
	       } catch (Exception e) {
		       monitoring.setFailedOperations(monitoring.getFailedOperations() + 1);
		       return ERROR;
	       }
       }      

 
       private synchronized String remove(String k) {
	       String result = "";
	       
	        if (! store.containsKey(k) ) {
			result = NOT_AVAILABLE;
		} else {
			result = (String) store.remove(k);
		}
		return result;
       }
       
       
       private synchronized void updateMinMaxOperationTime(long value) {
	       
	       long min = monitoring.getMinOperationTime();
	       long max = monitoring.getMaxOperationTime();
	       
	       if (min == 0 && max == 0) {
		       monitoring.setMinOperationTime(value);
		       monitoring.setMaxOperationTime(value);
	       } else if (value < min) {
		       monitoring.setMinOperationTime(value);
	       } else if (value > max) {
		       monitoring.setMaxOperationTime(value);
	       }
       }
       
       
       private static void sleep() {
		try {
		    Thread.sleep((int)(Math.random() * 100));
		} catch (InterruptedException e) {
		    return;
		}
       }
       
       
       
       
       
       
       
       
       
       
}
