StackIDFactory.java 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright (C) 2004-2015 L2J Server
  3. *
  4. * This file is part of L2J Server.
  5. *
  6. * L2J Server is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * L2J Server is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package com.l2jserver.gameserver.idfactory;
  20. import java.sql.Connection;
  21. import java.sql.PreparedStatement;
  22. import java.sql.ResultSet;
  23. import java.sql.SQLException;
  24. import java.util.Stack;
  25. import com.l2jserver.Config;
  26. import com.l2jserver.commons.database.pool.impl.ConnectionFactory;
  27. /**
  28. * This class ...
  29. * @version $Revision: 1.3.2.1.2.7 $ $Date: 2005/04/11 10:06:12 $
  30. */
  31. public class StackIDFactory extends IdFactory
  32. {
  33. private int _curOID;
  34. private int _tempOID;
  35. private final Stack<Integer> _freeOIDStack = new Stack<>();
  36. protected StackIDFactory()
  37. {
  38. super();
  39. _curOID = FIRST_OID;
  40. _tempOID = FIRST_OID;
  41. try (Connection con = ConnectionFactory.getInstance().getConnection())
  42. {
  43. // con.createStatement().execute("drop table if exists tmp_obj_id");
  44. Integer[] tmp_obj_ids = extractUsedObjectIDTable();
  45. if (tmp_obj_ids.length > 0)
  46. {
  47. _curOID = tmp_obj_ids[tmp_obj_ids.length - 1];
  48. }
  49. _log.info("Max Id = " + _curOID);
  50. int N = tmp_obj_ids.length;
  51. for (int idx = 0; idx < N; idx++)
  52. {
  53. N = insertUntil(tmp_obj_ids, idx, N, con);
  54. }
  55. _curOID++;
  56. _log.info("IdFactory: Next usable Object ID is: " + _curOID);
  57. _initialized = true;
  58. }
  59. catch (Exception e)
  60. {
  61. _log.severe(getClass().getSimpleName() + ": Could not be initialized properly:" + e.getMessage());
  62. }
  63. }
  64. private int insertUntil(Integer[] tmp_obj_ids, int idx, int N, Connection con) throws SQLException
  65. {
  66. int id = tmp_obj_ids[idx];
  67. if (id == _tempOID)
  68. {
  69. _tempOID++;
  70. return N;
  71. }
  72. // check these IDs not present in DB
  73. if (Config.BAD_ID_CHECKING)
  74. {
  75. for (String check : ID_CHECKS)
  76. {
  77. try (PreparedStatement ps = con.prepareStatement(check))
  78. {
  79. ps.setInt(1, _tempOID);
  80. // ps.setInt(1, _curOID);
  81. ps.setInt(2, id);
  82. try (ResultSet rs = ps.executeQuery())
  83. {
  84. while (rs.next())
  85. {
  86. int badId = rs.getInt(1);
  87. _log.severe("Bad ID " + badId + " in DB found by: " + check);
  88. throw new RuntimeException();
  89. }
  90. }
  91. }
  92. }
  93. }
  94. // int hole = id - _curOID;
  95. int hole = id - _tempOID;
  96. if (hole > (N - idx))
  97. {
  98. hole = N - idx;
  99. }
  100. for (int i = 1; i <= hole; i++)
  101. {
  102. // log.info("Free ID added " + (_tempOID));
  103. _freeOIDStack.push(_tempOID);
  104. _tempOID++;
  105. // _curOID++;
  106. }
  107. if (hole < (N - idx))
  108. {
  109. _tempOID++;
  110. }
  111. return N - hole;
  112. }
  113. public static IdFactory getInstance()
  114. {
  115. return _instance;
  116. }
  117. @Override
  118. public synchronized int getNextId()
  119. {
  120. int id;
  121. if (!_freeOIDStack.empty())
  122. {
  123. id = _freeOIDStack.pop();
  124. }
  125. else
  126. {
  127. id = _curOID;
  128. _curOID = _curOID + 1;
  129. }
  130. return id;
  131. }
  132. /**
  133. * return a used Object ID back to the pool
  134. * @param id
  135. */
  136. @Override
  137. public synchronized void releaseId(int id)
  138. {
  139. _freeOIDStack.push(id);
  140. }
  141. @Override
  142. public int size()
  143. {
  144. return (FREE_OBJECT_ID_SIZE - _curOID) + FIRST_OID + _freeOIDStack.size();
  145. }
  146. }