Package ise.mace.plugins.database

Source Code of ise.mace.plugins.database.DatabasePlugin

package ise.mace.plugins.database;

import ise.mace.environment.PublicEnvironmentConnection;
import ise.mace.groups.LoansGroup;
import ise.mace.participants.PublicAgentDataModel;
import ise.mace.participants.PublicGroupDataModel;
import ise.mace.tokens.TurnType;
import org.simpleframework.xml.Element;
import java.io.File;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import presage.Plugin;
import presage.Simulation;
import presage.annotations.PluginConstructor;

/**
* Updated version of DatabasePlugin that is more more more more... just better.
*/
public class DatabasePlugin implements Plugin
{
  private static final long serialVersionUID = 1L;
  private final static Logger logger = Logger.getLogger("mace.DatabasePlugin");
  private final static String name = "Database Plugin v2.9";
  @Element
  private final Boolean remote;
  @Element
  private final String comment;
  @Element
  private final Boolean docRemote;
  @Element
  private final Boolean loans;

  /**
   * Creates a new instance of the DatabasePlugin,
   * stores data in local db.
   *
   */
  DatabasePlugin()
  {
    //default parameters: local database
    this("No comment", false);
  }

  /**
   * Creates a new instance of the DatabasePlugin
   * with specified parameters.
   * @param comment Comment for simulation
   * @param remote Use remote db instead of local
   *
   */
  @PluginConstructor(
  {
    "comment", "remote"
  })
  public DatabasePlugin(String comment, Boolean remote)
  {
    this(comment, remote, false, false);

  }

  /**
   * Creates a new instance of the DatabasePlugin
   * with specified parameters.
   * @param comment Comment for simulation
   * @param remote Use remote db instead of local
   * @param docRemote Uses doc remote database
   * @param loans Should be used for simulating loans
   */
  @PluginConstructor(
  {
    "comment", "remote", "docRemote"
  })
  public DatabasePlugin(String comment, Boolean remote, Boolean docRemote)
  {
    this(comment, remote, docRemote, false);
  }

  /**
   * Creates a new instance of the DatabasePlugin
   * with specified parameters.
   * @param comment Comment for simulation
   * @param remote Use remote db instead of local
   * @param docRemote Uses doc remote database
   * @param loans Should be used for simulating loans
   */
  @PluginConstructor(
  {
    "comment", "remote", "docRemote", "loans"
  })
  public DatabasePlugin(String comment, Boolean remote, Boolean docRemote,
          Boolean loans)
  {
    this.loans = loans;
    this.comment = comment;
    this.remote = remote;
    this.docRemote = docRemote;
  }
  private ConnectionWrapper wrap;
  private PublicEnvironmentConnection ec;
  private Simulation sim;
  //internal storage of roundsPassed()
  private int round;
  //used to generate simulation unique agentid and groupid
  private int agentIdGenerator = 0;
  private int groupIdGenerator = 0;
  private final TreeMap<String, PublicGroupDataModel> trackedGroups = new TreeMap<String, PublicGroupDataModel>();
  private final TreeMap<String, PublicAgentDataModel> trackedAgents = new TreeMap<String, PublicAgentDataModel>();
  //contains agentid and groupid that are used to represent participants in the database
  //HashMap size should same order of magnitude as agents+groups set size for speed
  private final Map<String, Integer> agentIdMap = new HashMap<String, Integer>(
          100);
  private final Map<String, Integer> groupIdMap = new HashMap<String, Integer>(
          100);

  @Override
  public void execute()
  {
    //data only updated at the beginning of round
    if (ec.getCurrentTurnType() != TurnType.firstTurn) return;
    round = ec.getRoundsPassed();
    findNewGroups();
    findNewAgents();
    pruneOldAgents();
    //update FreeAgentsGroup with data
    wrap.getFreeAgentGroupData(round, ec.getUngroupedAgents().size());
    //disables agent round data collection for remote db, to speed it up
    //also updates trust table
    if (!remote)
      getAgentRoundData();
    pruneOldGroups();
    getGroupRoundData();


    //writes to db every 50 rounds (or 30 cycles) for local db
    //remote only writes at the end
    //no writes till the end
     /* if(round%50==0 && !remote)
    {
    if (!remote) logger.log(Level.INFO,"Writing data to local database");
    else logger.log(Level.INFO,"Writing data to remote database (could take a while)");
    wrap.flush(round);
    logger.log(Level.INFO,"Database write complete");
    }
     */
  }

  @Override
  public void initialise(Simulation sim)
  {
    ec = PublicEnvironmentConnection.getInstance();
    this.sim = sim;
    if (ec == null) throw new IllegalStateException(
              "Connection created before EnviromentConnection was accessible");

    try
    {
      //selects database connection
      String url;
      Properties connProperties = new java.util.Properties();
      if (remote)
      {
        String dbUsername;
        String dbPassword;
        if (docRemote)
        {
          //url to remote db
          url = "jdbc:mysql://icsflibsrv.su.ic.ac.uk:3306/gol";
          dbUsername = "gol";
          dbPassword = "gol";
        }
        else
        {
          url = "jdbc:mysql://69.175.26.66:3306/stratra1_isegol";
          dbUsername = "stratra1_isegol";
          dbPassword = "ise4r3g00d";
        }
        connProperties.put("user", dbUsername);
        connProperties.put("password", dbPassword);
        connProperties.put("autoReconnect", "true");
        //connProperties.put("useCompression", "true");
        //15 seconds delay before each reconnect
        connProperties.put("initialTimeout", "15");
        connProperties.put("maxReconnects", "5");
        logger.log(Level.INFO, "Connecting to remote database:{0}", url);
      }
      else
      {
        //path to /Simulations folder
        String simDir = new File(System.getProperty("user.dir"), "simulations").getAbsolutePath();
        //url to local db
        url = "jdbc:sqlite:" + simDir + "/Simulations.db";
        logger.log(Level.INFO,
                "Connecting to local database at: {0}/Simulations.db", simDir);
      }
      //Establish connection to database
      wrap = new ConnectionWrapper(url, connProperties, comment, ec.getId(),
              remote, loans);

    }
    catch (SQLException ex)
    {
      logger.log(Level.SEVERE, "Initializing database error:", ex);
    }
    catch (ClassNotFoundException ex)
    {
      logger.log(Level.SEVERE, "SQLite JDBC class not found", ex);
    }

    //required to prevent null exception for agents without group
    createFreeAgentGroup();

  }

  @Override
  public void onDelete()
  {
    wrap.flush(round);
    wrap.end(round);
  }

  @Override
  public void onSimulationComplete()
  {
    if (!remote) logger.log(Level.INFO, "Writing data to local database");
    else
      logger.log(Level.INFO,
              "Writing data to remote database."
              + "\n ---= DO NOT CLOSE WINDOW (DATABASE UPLOAD IN PROGRESS) =---"
              + "\n\t (wait till upload complete message if you wish to upload whole of your simulation");
    wrap.flush(round);
    wrap.end(round);
  }

  @Override
  public String getLabel()
  {
    return name;
  }

  @Override
  public String getShortLabel()
  {
    return name;
  }

  private void findNewAgents()
  {
    // get all active agentsin simulation
    //TreeSet<String> newAgents = new TreeSet<String>(ec.getAgents());
    TreeSet<String> newAgents = new TreeSet<String>(sim.getactiveParticipantIdSet(
            "hunter"));
    //remove already tracked groups
    newAgents.removeAll(trackedAgents.keySet());

    for (String a : newAgents)
    {
      PublicAgentDataModel agent = ec.getAgentById(a);
      int agentid = ++agentIdGenerator;
      wrap.agentAdd(a, agentid, round, agent.getName());
      agentIdMap.put(a, agentid);
      //add the agent to tracked groups
      trackedAgents.put(a, agent);
    }
  }

  private void findNewGroups()
  {
    // get all active groups in simulation
    TreeSet<String> newGroups = new TreeSet<String>(ec.getGroups());
    //TreeSet<String> newGroups = new TreeSet<String>(ec.isAgentId(name));
    //remove already tracked groups
    newGroups.removeAll(trackedGroups.keySet());
                //get rid of special group
                String SpecialID = "";
                for(String group : newGroups)
                   if(ec.getGroupById(group).getName().equals("Group #2"))
                       SpecialID = group;
                newGroups.remove(SpecialID);               
   
                for (String g : newGroups)
    {
      int groupid = ++groupIdGenerator;
      if (!loans) wrap.groupAdd(g, groupid, round);
      else wrap.groupAdd(g, groupid, round,
                LoansGroup.getGreediness(ec.getGroupById(g)));
      groupIdMap.put(g, groupid);
      //add the group to tracked groups
      trackedGroups.put(g, ec.getGroupById(g));
      //logger.log(Level.WARNING,"Name of the normal group:{0}, db id:{1}",new Object[] {ec.getGroupById(g).getName(),groupid});

    }
  }

  private void pruneOldGroups()
  {
    //Stop tracking old groups
    TreeSet<String> oldGroups = new TreeSet<String>(trackedGroups.keySet());
    oldGroups.removeAll(ec.getGroups());
    for (String g : oldGroups)
    {
      //queue group death sql statement
      wrap.groupDie(groupIdMap.remove(g), round);
      trackedGroups.remove(g);
    }
  }

  private void pruneOldAgents()
  {
    //Stop tracking dead agents
    TreeSet<String> deadAgents = new TreeSet<String>(trackedAgents.keySet());
    deadAgents.removeAll(sim.getactiveParticipantIdSet("hunter"));

    for (String a : deadAgents)
    {
      //queue agent death sql statement
      wrap.agentDie(agentIdMap.remove(a), round);
      trackedAgents.remove(a);
    }
  }

  private void getGroupRoundData()
  {

    for (Map.Entry<String, PublicGroupDataModel> entry : trackedGroups.entrySet())
    {
      PublicGroupDataModel group = entry.getValue();
      try
      {

        if (loans)
        {
          double averageHappiness = 0;
          for (String member : group.getMemberList())
          {
            averageHappiness += ec.getAgentById(member).getCurrentHappiness();
          }
          averageHappiness = averageHappiness / group.getMemberList().size();
          wrap.loanGroupRound(groupIdMap.get(entry.getKey()), round, group,
                  averageHappiness);
        }
        else wrap.groupRound(groupIdMap.get(entry.getKey()), round, group);
      }
      catch (NullPointerException ex)
      {
        logger.log(Level.WARNING,
                "Null Exception: For group {0} for round {1}.Ex:{2}"
                + " ", new Object[]
                {
                  group.getName(), round, ex
                });
      }
    }


  }

  private void getAgentRoundData()
  {
    for (Map.Entry<String, PublicAgentDataModel> entry : trackedAgents.entrySet())
    {
      PublicAgentDataModel agent = entry.getValue();
      try
      {
        //gets the agents groupid and maps it to database id for group
        //if agent group is null, the map returns 0 groupid

        int groupid = groupIdMap.get(agent.getGroupId());
        int agentid = agentIdMap.get(entry.getKey());
        wrap.agentRound(agentid, groupid, round, agent);
        for (Map.Entry<String, PublicAgentDataModel> entry2 : trackedAgents.entrySet())
        {
          Double trust = agent.getTrust(entry2.getKey());
          if (trust != null)
          {
            int agentid_other = agentIdMap.get(entry2.getKey());
            wrap.agentTrust(agentid, agentid_other, trust, round);
          }
        }
      }
      catch (NullPointerException ex)
      {
        logger.log(Level.WARNING, "Null Exception: For agent {0} for round {1}"
                + " ", new Object[]
                {
                  agent.getName(), round
                });
      }
    }
  }
  /*
   * creates a group for free agents.
   */

  private void createFreeAgentGroup()
  {
    int groupid = 0;
    wrap.groupAdd("FreeAgentsGroup", groupid, round);
    //required to allow idMap to work for agents with no group
    groupIdMap.put(null, groupid);
  }
}
TOP

Related Classes of ise.mace.plugins.database.DatabasePlugin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.