Package l2p.gameserver.idfactory

Source Code of l2p.gameserver.idfactory.IdFactory

package l2p.gameserver.idfactory;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;

import l2p.Config;
import l2p.Server;
import l2p.common.ParallelExecutor;
import l2p.database.DatabaseUtils;
import l2p.database.FiltredStatement;
import l2p.database.L2DatabaseFactory;
import l2p.database.ThreadConnection;
import l2p.gameserver.idfactory.Tasks.ClearQuery;

public abstract class IdFactory
{
  private static Logger _log = Logger.getLogger(IdFactory.class.getName());
  protected boolean initialized;
  protected long releasedCount = 0;
  public static final int FIRST_OID = 0x10000000;
  public static final int LAST_OID = 0x7FFFFFFF;
  public static final int FREE_OBJECT_ID_SIZE = LAST_OID - FIRST_OID;
  protected static final IdFactory _instance = new BitSetIDFactory();

  protected IdFactory()
  {
    setAllCharacterOffline();
    if(Config.MULTI_THREADED_IDFACTORY_CLEANER)
    {
      mt_cleanUpDB();
    }
    else
    {
      cleanUpDB();
    }
  }

  private void setAllCharacterOffline()
  {
    ThreadConnection conn = null;
    FiltredStatement stmt = null;
    try
    {
      conn = L2DatabaseFactory.getInstance().getConnection();
      stmt = conn.createStatement();
      stmt.executeUpdate("UPDATE characters SET online = 0");
      stmt.executeUpdate("UPDATE characters SET accesslevel = 0 WHERE accesslevel = -1");
      _log.info("Clear characters online status and accesslevel.");
    }
    catch(SQLException e)
    {
    }
    finally
    {
      DatabaseUtils.closeDatabaseCS(conn, stmt);
    }
  }

  /**
   * Cleans up Database
   */
  private void cleanUpDB()
  {
    for(ClearQuery q : ClearQuery.values())
    {
      q.run();
    }
    _log.info("Total cleaned: " + ClearQuery.totalDeleted + ", updated: " + ClearQuery.totalUpdated + " elements in database.");
  }

  private void mt_cleanUpDB()
  {
    ParallelExecutor executor = new ParallelExecutor("cleanUpDB", Thread.NORM_PRIORITY, ClearQuery.values().length);
    try
    {
      for(ClearQuery q : ClearQuery.values())
      {
        executor.execute(q);
      }
      executor.waitForFinishAndDestroy();
      _log.info("Total cleaned: " + ClearQuery.totalDeleted + ", updated: " + ClearQuery.totalUpdated + " elements in database.");
    }
    catch(InterruptedException e)
    {
      e.printStackTrace();
      Server.exit(0, "cleanUpDB");
    }
  }

  protected int[] extractUsedObjectIDTable()
  {
    return Config.MULTI_THREADED_IDFACTORY_EXTRACTOR ? extractUsedObjectIDTable2() : extractUsedObjectIDTable1();
  }

  protected int[] extractUsedObjectIDTable1()
  {
    ThreadConnection con = null;
    FiltredStatement s = null;
    ResultSet rs = null;
    try
    {
      con = L2DatabaseFactory.getInstance().getConnection();
      s = con.createStatement();
      String query = "SELECT " + Tasks.objTables[0][1] + ", 0 AS i FROM " + Tasks.objTables[0][0];
      for(int i = 1; i < Tasks.objTables.length; i++)
      {
        query += " UNION SELECT " + Tasks.objTables[i][1] + ", " + i + " FROM " + Tasks.objTables[i][0];
      }
      rs = s.executeQuery("SELECT COUNT(*), COUNT(DISTINCT " + Tasks.objTables[0][1] + ") FROM ( " + query + " ) AS all_ids");
      if(!rs.next())
      {
        throw new Exception("IdFactory: can't extract count ids");
      }
      if(rs.getInt(1) != rs.getInt(2))
      {
        throw new Exception("IdFactory: there are duplicates in object ids");
      }
      int[] result = new int[rs.getInt(1)];
      DatabaseUtils.closeResultSet(rs);
      _log.info("IdFactory: Extracting " + result.length + " used id's from data tables...");
      rs = s.executeQuery(query);
      int idx = 0;
      while(rs.next())
      {
        result[idx++] = rs.getInt(1);
      }
      _log.info("IdFactory: Successfully extracted " + idx + " used id's from data tables.");
      return result;
    }
    catch(Exception e)
    {
      e.printStackTrace();
      Server.exit(0, "IdFactory");
      return null;
    }
    finally
    {
      DatabaseUtils.closeDatabaseCSR(con, s, rs);
    }
  }

  protected int[] extractUsedObjectIDTable2()
  {
    // считаем количество по всем таблицам распаралеленно
    final int[][] objCounts = new int[Tasks.objTables.length][];
    ParallelExecutor multiextractor = new ParallelExecutor("extractUsedObjectIDTable::CountObjectIds", Thread.NORM_PRIORITY, Tasks.objTables.length);
    try
    {
      for(int i = 0; i < Tasks.objTables.length; i++)
      {
        objCounts[i] = new int[2];
        multiextractor.execute(new Tasks.CountObjectIds(Tasks.objTables[i], objCounts[i]));
      }
      multiextractor.waitForFinishAndDestroy();
    }
    catch(InterruptedException e)
    {
      e.printStackTrace();
      Server.exit(0, "IdFactory::CountObjectIds");
    }
    // выставляем смещения для каждой таблици
    int idx = 0;
    for(int i = 0; i < objCounts.length; i++)
    {
      objCounts[i][1] = idx;
      idx += objCounts[i][0];
    }
    int[] result = new int[idx];
    _log.info("IdFactory: Extracting " + result.length + " used id's from data tables...");
    // извлекаем идентификаторы по всем таблицам распаралеленно
    multiextractor = new ParallelExecutor("extractUsedObjectIDTable::ExtractObjectIds", Thread.NORM_PRIORITY, Tasks.objTables.length);
    try
    {
      for(int i = 0; i < Tasks.objTables.length; i++)
      {
        multiextractor.execute(new Tasks.ExtractObjectIds(Tasks.objTables[i], objCounts[i], result));
      }
      multiextractor.waitForFinishAndDestroy();
    }
    catch(InterruptedException e)
    {
      e.printStackTrace();
      Server.exit(0, "IdFactory::ExtractObjectIds");
    }
    _log.info("IdFactory: Successfully extracted " + result.length + " used id's from data tables.");
    return result;
  }

  public boolean isInitialized()
  {
    return initialized;
  }

  public static IdFactory getInstance()
  {
    return _instance;
  }

  public abstract int getNextId();

  /**
   * return a used Object ID back to the pool
   *
   * @param object ID
   */
  public void releaseId(int id)
  {
    releasedCount++;
  }

  public long getReleasedCount()
  {
    return releasedCount;
  }

  public abstract int size();

  public static void unload()
  {
    if(_instance != null)
    {
      ((BitSetIDFactory) _instance)._unload();
    }
  }
}
TOP

Related Classes of l2p.gameserver.idfactory.IdFactory

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.