mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-26 06:43:25 -04:00
Majorly optimise saving of BlockDB. (from 30 to 10 seconds on a full 128x128x128 map)
This commit is contained in:
parent
87758df1e3
commit
f47d84b732
@ -18,6 +18,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MySql.Data.MySqlClient;
|
||||
@ -37,6 +38,10 @@ namespace MCGalaxy.SQL {
|
||||
|
||||
public abstract bool Execute(string query);
|
||||
|
||||
public abstract IDbCommand CreateCommand(string query);
|
||||
|
||||
public abstract DbParameter CreateParam(string paramName, DbType type);
|
||||
|
||||
public void Commit() {
|
||||
try {
|
||||
transaction.Commit();
|
||||
@ -64,5 +69,16 @@ namespace MCGalaxy.SQL {
|
||||
transaction = null;
|
||||
connection = null;
|
||||
}
|
||||
|
||||
public static bool Execute(string query, IDbCommand cmd) {
|
||||
try {
|
||||
cmd.ExecuteNonQuery();
|
||||
} catch (Exception e) {
|
||||
System.IO.File.AppendAllText("MySQL_error.log", DateTime.Now + " " + query + "\r\n");
|
||||
Server.ErrorLog(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MySql.Data.MySqlClient;
|
||||
@ -67,5 +69,13 @@ namespace MCGalaxy.SQL {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override IDbCommand CreateCommand(string query) {
|
||||
return new MySqlCommand(query, (MySqlConnection)connection, (MySqlTransaction)transaction);
|
||||
}
|
||||
|
||||
public override DbParameter CreateParam(string paramName, DbType type) {
|
||||
return new MySqlParameter(paramName, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Data.SQLite;
|
||||
|
||||
namespace MCGalaxy.SQL {
|
||||
@ -63,5 +65,13 @@ namespace MCGalaxy.SQL {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override IDbCommand CreateCommand(string query) {
|
||||
return new SQLiteCommand(query, (SQLiteConnection)connection, (SQLiteTransaction)transaction);
|
||||
}
|
||||
|
||||
public override DbParameter CreateParam(string paramName, DbType type) {
|
||||
return new SQLiteParameter(paramName, type);
|
||||
}
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.Common;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
@ -335,34 +336,67 @@ namespace MCGalaxy
|
||||
return true;
|
||||
}
|
||||
|
||||
public void saveChanges()
|
||||
{
|
||||
public unsafe void saveChanges() {
|
||||
if (blockCache.Count == 0) return;
|
||||
List<BlockPos> tempCache = blockCache;
|
||||
ushort x, y, z;
|
||||
string date = new String('-', 19); //yyyy-mm-dd hh:mm:ss
|
||||
|
||||
string template = "INSERT INTO `Block" + name +
|
||||
"` (Username, TimePerformed, X, Y, Z, type, deleted) VALUES ('{0}', '{1}', {2}, {3}, {4}, {5}, {6})";
|
||||
DatabaseTransactionHelper transaction = DatabaseTransactionHelper.Create();
|
||||
using (transaction)
|
||||
{
|
||||
for (int i = 0; i < tempCache.Count; i++ ) {
|
||||
BlockPos bP = tempCache[i];
|
||||
int deleted = bP.deleted ? 1 : 0;
|
||||
IntToPos(bP.index, out x, out y, out z);
|
||||
DateTime time = Server.StartTimeLocal.AddSeconds(bP.timeDelta);
|
||||
string query = String.Format(template, bP.name, time.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
x, y, z, bP.type, deleted);
|
||||
if (!transaction.Execute(query)) {
|
||||
transaction.Rollback(); return;
|
||||
}
|
||||
using (DatabaseTransactionHelper transaction = DatabaseTransactionHelper.Create()) {
|
||||
fixed (char* ptr = date) {
|
||||
ptr[4] = '-'; ptr[7] = '-'; ptr[10] = ' '; ptr[13] = ':'; ptr[16] = ':';
|
||||
DoSaveChanges(tempCache, ptr, date, transaction);
|
||||
}
|
||||
transaction.Commit();
|
||||
}
|
||||
tempCache.Clear();
|
||||
blockCache = new List<BlockPos>();
|
||||
}
|
||||
|
||||
unsafe bool DoSaveChanges(List<BlockPos> tempCache, char* ptr, string date,
|
||||
DatabaseTransactionHelper transaction) {
|
||||
string template = "INSERT INTO `Block" + name +
|
||||
"` (Username, TimePerformed, X, Y, Z, type, deleted) VALUES (@Name, @Time, @X, @Y, @Z, @Tile, @Del)";
|
||||
ushort x, y, z;
|
||||
|
||||
IDbCommand cmd = transaction.CreateCommand(template);
|
||||
DbParameter nameP = transaction.CreateParam("@Name", DbType.AnsiStringFixedLength); cmd.Parameters.Add(nameP);
|
||||
DbParameter timeP = transaction.CreateParam("@Time", DbType.AnsiStringFixedLength); cmd.Parameters.Add(timeP);
|
||||
DbParameter xP = transaction.CreateParam("@X", DbType.UInt16); cmd.Parameters.Add(xP);
|
||||
DbParameter yP = transaction.CreateParam("@Y", DbType.UInt16); cmd.Parameters.Add(yP);
|
||||
DbParameter zP = transaction.CreateParam("@Z", DbType.UInt16); cmd.Parameters.Add(zP);
|
||||
DbParameter tileP = transaction.CreateParam("@Tile", DbType.Byte); cmd.Parameters.Add(tileP);
|
||||
DbParameter delP = transaction.CreateParam("@Del", DbType.Boolean); cmd.Parameters.Add(delP);
|
||||
|
||||
for (int i = 0; i < tempCache.Count; i++) {
|
||||
BlockPos bP = tempCache[i];
|
||||
IntToPos(bP.index, out x, out y, out z);
|
||||
nameP.Value = bP.name;
|
||||
DateTime time = Server.StartTimeLocal.AddSeconds(bP.timeDelta);
|
||||
MakeInt(time.Year, 4, 0, ptr); MakeInt(time.Month, 2, 5, ptr); MakeInt(time.Day, 2, 8, ptr);
|
||||
MakeInt(time.Hour, 2, 11, ptr); MakeInt(time.Minute, 2, 14, ptr); MakeInt(time.Second, 2, 17, ptr);
|
||||
|
||||
timeP.Value = date;
|
||||
xP.Value = x; yP.Value = y; zP.Value = z;
|
||||
tileP.Value = bP.type;
|
||||
delP.Value = bP.deleted;
|
||||
|
||||
if (!DatabaseTransactionHelper.Execute(template, cmd)) {
|
||||
cmd.Dispose();
|
||||
transaction.Rollback(); return false;
|
||||
}
|
||||
}
|
||||
cmd.Dispose();
|
||||
transaction.Commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
unsafe static void MakeInt(int value, int chars, int offset, char* ptr) {
|
||||
for (int i = 0; i < chars; i++, value /= 10) {
|
||||
char c = (char)('0' + (value % 10));
|
||||
ptr[offset + (chars - 1 - i)] = c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool InBound(ushort x, ushort y, ushort z)
|
||||
{
|
||||
return x >= 0 && y >= 0 && z >= 0 && x < Width && y < Height && z < Length;
|
||||
|
Loading…
x
Reference in New Issue
Block a user